diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..b983583855 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,8 @@ +# Website development +* @expressjs/docs-collaborators + +# Codeowners +.github/CODEOWNERS @expressjs/docs-captains + +# Blog +_posts @expressjs/express-tc \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..ec082eb3d7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + + - package-ecosystem: docker + directory: / + schedule: + interval: monthly + + - package-ecosystem: bundler + directory: / + schedule: + interval: monthly + + - package-ecosystem: npm + directory: / + schedule: + interval: monthly + open-pull-requests-limit: 10 + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] diff --git a/.github/scripts/get-contributing.sh b/.github/scripts/get-contributing.sh new file mode 100755 index 0000000000..2b046e4d1a --- /dev/null +++ b/.github/scripts/get-contributing.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +# This script replaces the contents of a section with the contents from the annotated source address or local file paths inside the DEST file. + +# read contents of file into memory +DEST="../../en/resources/contributing.md" + +# track the header level +level='' +# tracks src for curl calls +src='' +# tracks file paths for local file reads +local='' + while IFS= read -r line; do + # REMOVE PREVIOUS CONTENT SECTION + # if src or local tags are not empty + if [[ -n "$src" || -n "$local" ]]; then + # if current line not a horitzontal rule hr + if [[ "$line" != "----"* ]]; then + # if line == level -- level is num of ## + if [[ "$line" == "$level"'#'* || + # line not a header line + "$line" != '#'* ]]; then + # skip line and rewrite over old content + continue + fi + fi + fi + + # PRINT TO PAGE SECTION + src='' + local='' + # if line is a header + if [[ "$line" == '#'* ]]; then + # if header has (#id-of-link) or {#id-on-page} patterns + if [[ $line =~ (\(\#.*\))\. || "$line" =~ \{\#.*\} ]]; then + # isolate the matching part of line + match=${BASH_REMATCH[0]} + # remove match - leaving rest + rest=${line//${match}} + # remove any # symbols from start + title_rest=${rest##*\#} + # slice rest of line to get only level + level="${rest:0:$((${#rest} - ${#title_rest}))}" + else + # any other headers -- these before SRC/LOCAL pages anchors + header=${line##*\#} + level="${line:0:$((${#line} - ${#header}))}" + fi + # if line is SRC anchor in read file + elif [[ "$line" == ' - diff --git a/_includes/header/header-en.html b/_includes/header/header-en.html deleted file mode 100644 index 68f49a1df9..0000000000 --- a/_includes/header/header-en.html +++ /dev/null @@ -1,178 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-es.html b/_includes/header/header-es.html deleted file mode 100644 index eb187b82ab..0000000000 --- a/_includes/header/header-es.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-fr.html b/_includes/header/header-fr.html deleted file mode 100644 index 3de9257430..0000000000 --- a/_includes/header/header-fr.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-it.html b/_includes/header/header-it.html deleted file mode 100644 index e825762fad..0000000000 --- a/_includes/header/header-it.html +++ /dev/null @@ -1,129 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-ja.html b/_includes/header/header-ja.html deleted file mode 100644 index 23562f410f..0000000000 --- a/_includes/header/header-ja.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-ko.html b/_includes/header/header-ko.html deleted file mode 100644 index 286f359cdd..0000000000 --- a/_includes/header/header-ko.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-pt-br.html b/_includes/header/header-pt-br.html deleted file mode 100644 index 1b23a2c188..0000000000 --- a/_includes/header/header-pt-br.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-ru.html b/_includes/header/header-ru.html deleted file mode 100644 index 4d29c40bd8..0000000000 --- a/_includes/header/header-ru.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-sk.html b/_includes/header/header-sk.html deleted file mode 100644 index a5aec987b3..0000000000 --- a/_includes/header/header-sk.html +++ /dev/null @@ -1,135 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-th.html b/_includes/header/header-th.html deleted file mode 100644 index 8e9a00f145..0000000000 --- a/_includes/header/header-th.html +++ /dev/null @@ -1,161 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-tr.html b/_includes/header/header-tr.html deleted file mode 100644 index 39463f2658..0000000000 --- a/_includes/header/header-tr.html +++ /dev/null @@ -1,161 +0,0 @@ -
-
- Black Lives Matter. Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-uk.html b/_includes/header/header-uk.html deleted file mode 100644 index d61f9a4452..0000000000 --- a/_includes/header/header-uk.html +++ /dev/null @@ -1,131 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-uz.html b/_includes/header/header-uz.html deleted file mode 100644 index 34bbf8f4ca..0000000000 --- a/_includes/header/header-uz.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-zh-cn.html b/_includes/header/header-zh-cn.html deleted file mode 100644 index 283d41ade9..0000000000 --- a/_includes/header/header-zh-cn.html +++ /dev/null @@ -1,132 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/header/header-zh-tw.html b/_includes/header/header-zh-tw.html deleted file mode 100644 index 91c061292c..0000000000 --- a/_includes/header/header-zh-tw.html +++ /dev/null @@ -1,133 +0,0 @@ -
-
- Black Lives Matter.
- Support the Equal Justice Initiative. -
-
- -
- - -
diff --git a/_includes/i18n-notice.html b/_includes/i18n-notice.html index d5583cf2d1..6c5adf9e0b 100644 --- a/_includes/i18n-notice.html +++ b/_includes/i18n-notice.html @@ -1,2 +1,10 @@ -

{% include notice/notice-{{ page.lang }}.md %}

-
+{% assign notice = site.data[page.lang].general.i18n_notice %} +{% assign lang_path = '/' | append: page.lang | append: '/' %} +{% if notice %} + {% assign notice_link_text = site.data[page.lang].general.i18n_notice_link_text %} +{% else %} + {% assign notice = site.data.en.general.i18n_notice %} + {% assign notice_link_text = site.data.en.general.i18n_notice_link_text %} +{% endif %} +

{{ notice }} {{ notice_link_text}}.

+
\ No newline at end of file diff --git a/_includes/icons/X.svg b/_includes/icons/X.svg new file mode 100644 index 0000000000..cc93734c32 --- /dev/null +++ b/_includes/icons/X.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/announcement.svg b/_includes/icons/announcement.svg new file mode 100644 index 0000000000..460c9522f8 --- /dev/null +++ b/_includes/icons/announcement.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/arrow.svg b/_includes/icons/arrow.svg new file mode 100644 index 0000000000..3b44d7b7bb --- /dev/null +++ b/_includes/icons/arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/bluesky.svg b/_includes/icons/bluesky.svg new file mode 100644 index 0000000000..ac3613791d --- /dev/null +++ b/_includes/icons/bluesky.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/caution.svg b/_includes/icons/caution.svg new file mode 100644 index 0000000000..c62c756faf --- /dev/null +++ b/_includes/icons/caution.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/express-logo.svg b/_includes/icons/express-logo.svg new file mode 100644 index 0000000000..16bcc7070a --- /dev/null +++ b/_includes/icons/express-logo.svg @@ -0,0 +1,3 @@ + diff --git a/_includes/icons/github.svg b/_includes/icons/github.svg new file mode 100644 index 0000000000..b2b41dbd47 --- /dev/null +++ b/_includes/icons/github.svg @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/_includes/icons/hamburger.svg b/_includes/icons/hamburger.svg new file mode 100644 index 0000000000..9a681768f3 --- /dev/null +++ b/_includes/icons/hamburger.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/_includes/icons/i18n.svg b/_includes/icons/i18n.svg new file mode 100644 index 0000000000..e0b2a0b2bc --- /dev/null +++ b/_includes/icons/i18n.svg @@ -0,0 +1,3 @@ + + + diff --git a/_includes/icons/moon.svg b/_includes/icons/moon.svg new file mode 100644 index 0000000000..0b224e4910 --- /dev/null +++ b/_includes/icons/moon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/_includes/icons/note.svg b/_includes/icons/note.svg new file mode 100644 index 0000000000..b08a648992 --- /dev/null +++ b/_includes/icons/note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/opencollective.svg b/_includes/icons/opencollective.svg new file mode 100644 index 0000000000..e4c1b67a75 --- /dev/null +++ b/_includes/icons/opencollective.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/openjs_foundation-logo-horizontal-white.svg b/_includes/icons/openjs_foundation-logo-horizontal-white.svg new file mode 100644 index 0000000000..e87bedfa01 --- /dev/null +++ b/_includes/icons/openjs_foundation-logo-horizontal-white.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_includes/icons/slack.svg b/_includes/icons/slack.svg new file mode 100644 index 0000000000..e6bb3f152c --- /dev/null +++ b/_includes/icons/slack.svg @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/_includes/icons/sun.svg b/_includes/icons/sun.svg new file mode 100644 index 0000000000..0701fffd93 --- /dev/null +++ b/_includes/icons/sun.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/_includes/icons/warning.svg b/_includes/icons/warning.svg new file mode 100644 index 0000000000..fa4907c793 --- /dev/null +++ b/_includes/icons/warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/icons/youtube.svg b/_includes/icons/youtube.svg new file mode 100644 index 0000000000..5968f9b040 --- /dev/null +++ b/_includes/icons/youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/language-picker.html b/_includes/language-picker.html new file mode 100644 index 0000000000..0a344ed9a3 --- /dev/null +++ b/_includes/language-picker.html @@ -0,0 +1,21 @@ +{% assign url_parts = page.url | split: '/' %} +{% assign url_remainder = url_parts | slice: 2, url_parts.size | join: '/' %} +{% assign current_lang = page.lang %} +
+ + +
\ No newline at end of file diff --git a/_includes/mw-list.md b/_includes/mw-list.md index e2fc559c16..7eae8705cc 100644 --- a/_includes/mw-list.md +++ b/_includes/mw-list.md @@ -4,7 +4,6 @@ - [cookie-parser](/resources/middleware/cookie-parser.html) - [cookie-session](/resources/middleware/cookie-session.html) - [cors](/resources/middleware/cors.html) -- [csurf](/resources/middleware/csurf.html) - [errorhandler](/resources/middleware/errorhandler.html) - [method-override](/resources/middleware/method-override.html) - [morgan](/resources/middleware/morgan.html) @@ -16,3 +15,4 @@ - [session](/resources/middleware/session.html) - [timeout](/resources/middleware/timeout.html) - [vhost](/resources/middleware/vhost.html) +{: #side-menu .active} \ No newline at end of file diff --git a/_includes/note.html b/_includes/note.html deleted file mode 100644 index 924986895e..0000000000 --- a/_includes/note.html +++ /dev/null @@ -1,3 +0,0 @@ -
Note: -{{include.content}} -
diff --git a/_includes/notice/notice-de.md b/_includes/notice/notice-de.md deleted file mode 100755 index 20041cbca5..0000000000 --- a/_includes/notice/notice-de.md +++ /dev/null @@ -1,3 +0,0 @@ -

Diese Übersetzung zur Verfügung gestellt von StrongLoop / IBM.

- -Dieses Dokument kann im Vergleich zur englischen Dokumentation veraltet sein. Aktuelle Updates finden Sie in der englischen Dokumentation. diff --git a/_includes/notice/notice-en.md b/_includes/notice/notice-en.md deleted file mode 100755 index 85d0ac63e1..0000000000 --- a/_includes/notice/notice-en.md +++ /dev/null @@ -1 +0,0 @@ -This document might be outdated relative to the documentation in English. For the latest updates, please refer to the documentation in English. diff --git a/_includes/notice/notice-es.md b/_includes/notice/notice-es.md deleted file mode 100755 index d6db223672..0000000000 --- a/_includes/notice/notice-es.md +++ /dev/null @@ -1,3 +0,0 @@ -

Esta traducción proporcionada por StrongLoop / IBM.

- -Este documento puede estar desfasado respecto a la documentación en inglés. Para ver las últimas actualizaciones, consulte la documentación en inglés. diff --git a/_includes/notice/notice-fr.md b/_includes/notice/notice-fr.md deleted file mode 100755 index c3b485eae3..0000000000 --- a/_includes/notice/notice-fr.md +++ /dev/null @@ -1,3 +0,0 @@ -

Cette traduction fournie par StrongLoop / IBM.

- -Il se peut que ce document soit obsolète par rapport à la documentation en anglais. Pour connaître les mises à jour les plus récentes, reportez-vous à la documentation en anglais. diff --git a/_includes/notice/notice-it.md b/_includes/notice/notice-it.md deleted file mode 100755 index f18c2c7109..0000000000 --- a/_includes/notice/notice-it.md +++ /dev/null @@ -1,3 +0,0 @@ -

Questa traduzione fornita da StrongLoop / IBM.

- -È possibile che questo documento non sia aggiornato poiché la documentazione è in inglese. Per gli ultimi aggiornamenti, fare riferimento alla documentazione in inglese. diff --git a/_includes/notice/notice-ja.md b/_includes/notice/notice-ja.md deleted file mode 100755 index ec7b72ead1..0000000000 --- a/_includes/notice/notice-ja.md +++ /dev/null @@ -1,3 +0,0 @@ -

StrongLoop / IBMによって提供されるこの翻訳.

- -本書は、英語の資料と比較すると古くなっている可能性があります。最新の更新については、英語版の資料を参照してください。 diff --git a/_includes/notice/notice-ko.md b/_includes/notice/notice-ko.md deleted file mode 100755 index 7a2e866c8a..0000000000 --- a/_includes/notice/notice-ko.md +++ /dev/null @@ -1,3 +0,0 @@ -

StrongLoop / IBM에 의해 제공이 번역.

- -이 문서는 영문판 문서에 비해 더 오래된 버전일 수도 있습니다. 최신 업데이트를 확인하려면 영문판 문서를 참조하십시오. diff --git a/_includes/notice/notice-pt-br.md b/_includes/notice/notice-pt-br.md deleted file mode 100755 index 2d5fc7c7ae..0000000000 --- a/_includes/notice/notice-pt-br.md +++ /dev/null @@ -1,3 +0,0 @@ -

Esta tradução fornecida pelo StrongLoop / IBM.

- -Este documento pode estar desatualizado em relação à documentação em Inglês. Para obter as atualizações mais recentes, consulte a documentação em Inglês. diff --git a/_includes/notice/notice-ru.md b/_includes/notice/notice-ru.md deleted file mode 100755 index 9b690b4de8..0000000000 --- a/_includes/notice/notice-ru.md +++ /dev/null @@ -1,3 +0,0 @@ -

Этот перевод обеспечивается StrongLoop / IBM.

- -Этот документ может быть устаревшим по отношению к документации на английском языке. Последние обновления содержатся в документации на английском языке. diff --git a/_includes/notice/notice-sk.md b/_includes/notice/notice-sk.md deleted file mode 100644 index 4d135d577a..0000000000 --- a/_includes/notice/notice-sk.md +++ /dev/null @@ -1 +0,0 @@ -Tento dokument môže byť v porovnaní s dokumentáciou v angličtine zastaralý. Aktuálne informácie nájdete v dokumentácii v angličtine. diff --git a/_includes/notice/notice-th.md b/_includes/notice/notice-th.md deleted file mode 100755 index eff97e8d5d..0000000000 --- a/_includes/notice/notice-th.md +++ /dev/null @@ -1 +0,0 @@ -ในเอกสารนี้อาจจะเก่าไปแล้วที่เกี่ยวเนื่องกับรุ่นของเอกสารในภาษาอังกฤษ สำหรับรุ่นล่าสุดโปรดอ้างอิงจาก เอกสารในภาษาอังกฤษ. diff --git a/_includes/notice/notice-tr.md b/_includes/notice/notice-tr.md deleted file mode 100644 index 51df1fe86a..0000000000 --- a/_includes/notice/notice-tr.md +++ /dev/null @@ -1 +0,0 @@ -Bu doküman ingilizce dokümana göre eski olabilir. Son güncellemeler için lütfen İngilizce Dokümanı. ziyaret edin diff --git a/_includes/notice/notice-uk.md b/_includes/notice/notice-uk.md deleted file mode 100755 index a008968378..0000000000 --- a/_includes/notice/notice-uk.md +++ /dev/null @@ -1 +0,0 @@ -Цей документ може бути застарілим, в порівнянні з оригінальною англійською версією документації. diff --git a/_includes/notice/notice-uz.md b/_includes/notice/notice-uz.md deleted file mode 100755 index 85d0ac63e1..0000000000 --- a/_includes/notice/notice-uz.md +++ /dev/null @@ -1 +0,0 @@ -This document might be outdated relative to the documentation in English. For the latest updates, please refer to the documentation in English. diff --git a/_includes/notice/notice-zh-cn.md b/_includes/notice/notice-zh-cn.md deleted file mode 100755 index a61ca1ac3f..0000000000 --- a/_includes/notice/notice-zh-cn.md +++ /dev/null @@ -1,3 +0,0 @@ -

这个翻译StrongLoop / IBM提供.

- -相对于英文版的文档,本文档可能已过时。要了解最近的更新,请参阅英文版文档。 diff --git a/_includes/notice/notice-zh-tw.md b/_includes/notice/notice-zh-tw.md deleted file mode 100755 index 2c176fee06..0000000000 --- a/_includes/notice/notice-zh-tw.md +++ /dev/null @@ -1,3 +0,0 @@ -

這個翻譯StrongLoop / IBM提供.

- -相對於英文版說明文件,本文件可能已不合時宜。如需最新的更新,請參閱英文版說明文件。 diff --git a/_includes/readmes/body-parser.md b/_includes/readmes/body-parser.md index 7d7fa882ce..7fe2e56935 100644 --- a/_includes/readmes/body-parser.md +++ b/_includes/readmes/body-parser.md @@ -1,9 +1,10 @@ # body-parser -[![NPM Version][npm-image]][npm-url] -[![NPM Downloads][downloads-image]][downloads-url] -[![Build Status][github-actions-ci-image]][github-actions-ci-url] +[![NPM Version][npm-version-image]][npm-url] +[![NPM Downloads][npm-downloads-image]][npm-url] +[![Build Status][ci-image]][ci-url] [![Test Coverage][coveralls-image]][coveralls-url] +[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer] Node.js body parsing middleware. @@ -50,14 +51,12 @@ $ npm install body-parser ## API ```js -var bodyParser = require('body-parser') +const bodyParser = require('body-parser') ``` The `bodyParser` object exposes various factories to create middlewares. All middlewares will populate the `req.body` property with the parsed body when -the `Content-Type` request header matches the `type` option, or an empty -object (`{}`) if there was no body to parse, the `Content-Type` was not matched, -or an error occurred. +the `Content-Type` request header matches the `type` option. The various errors returned by this module are described in the [errors section](#errors). @@ -66,8 +65,8 @@ 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` and -`deflate` encodings. +Unicode encoding of the body and supports automatic inflation of `gzip`, +`br` (brotli) and `deflate` encodings. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). @@ -77,6 +76,11 @@ object after the middleware (i.e. `req.body`). The `json` function takes an optional `options` object that may contain any of the following keys: +##### defaultCharset + +Specify the default character set for the json content if the charset is not +specified in the `Content-Type` header of the request. Defaults to `utf-8`. + ##### inflate When set to `true`, then deflated (compressed) bodies will be inflated; when @@ -121,7 +125,8 @@ encoding of the request. The parsing can be aborted by throwing an error. 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` and `deflate` encodings. +parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate` +encodings. 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 @@ -166,7 +171,8 @@ encoding of the request. The parsing can be aborted by throwing an error. 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` and `deflate` encodings. +parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate` +encodings. 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 @@ -216,7 +222,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 encoding of the body and supports automatic -inflation of `gzip` and `deflate` encodings. +inflation of `gzip`, `br` (brotli) and `deflate` encodings. 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 @@ -230,16 +236,12 @@ any of the following keys: ##### extended -The `extended` option allows to choose between parsing the URL-encoded data -with the `querystring` library (when `false`) or the `qs` library (when -`true`). 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](https://www.npmjs.org/package/qs#readme). +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](https://www.npmjs.org/package/qs#readme). -Defaults to `true`, but using the default has been deprecated. Please -research into the difference between `qs` and `querystring` and choose the -appropriate setting. +Defaults to `false`. ##### inflate @@ -277,6 +279,27 @@ The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)` where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. +##### defaultCharset + +The default charset to parse as, if not specified in content-type. Must be +either `utf-8` or `iso-8859-1`. Defaults to `utf-8`. + +##### charsetSentinel + +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 + +Whether to decode numeric entities such as `☺` when parsing an iso-8859-1 +form. Defaults to `false`. + + +##### depth + +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 The middlewares provided by this module create errors using the @@ -342,6 +365,14 @@ 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 + +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 This error will occur when the content of the request exceeds the configured @@ -365,6 +396,10 @@ 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 + +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. + ## Examples ### Express/Connect top-level generic @@ -374,13 +409,13 @@ top-level middleware, which will parse the bodies of all incoming requests. This is the simplest setup. ```js -var express = require('express') -var bodyParser = require('body-parser') +const express = require('express') +const bodyParser = require('body-parser') -var app = express() +const app = express() // parse application/x-www-form-urlencoded -app.use(bodyParser.urlencoded({ extended: false })) +app.use(bodyParser.urlencoded()) // parse application/json app.use(bodyParser.json()) @@ -388,7 +423,7 @@ app.use(bodyParser.json()) app.use(function (req, res) { res.setHeader('Content-Type', 'text/plain') res.write('you posted:\n') - res.end(JSON.stringify(req.body, null, 2)) + res.end(String(JSON.stringify(req.body, null, 2))) }) ``` @@ -399,24 +434,26 @@ need them. In general, this is the most recommended way to use body-parser with Express. ```js -var express = require('express') -var bodyParser = require('body-parser') +const express = require('express') +const bodyParser = require('body-parser') -var app = express() +const app = express() // create application/json parser -var jsonParser = bodyParser.json() +const jsonParser = bodyParser.json() // create application/x-www-form-urlencoded parser -var urlencodedParser = bodyParser.urlencoded({ extended: false }) +const urlencodedParser = bodyParser.urlencoded() // POST /login gets urlencoded bodies app.post('/login', urlencodedParser, function (req, res) { + if (!req.body || !req.body.username) res.sendStatus(400) res.send('welcome, ' + req.body.username) }) // POST /api/users gets JSON bodies app.post('/api/users', jsonParser, function (req, res) { + if (!req.body) res.sendStatus(400) // create user in req.body }) ``` @@ -427,10 +464,10 @@ All the parsers accept a `type` option which allows you to change the `Content-Type` that the middleware will parse. ```js -var express = require('express') -var bodyParser = require('body-parser') +const express = require('express') +const bodyParser = require('body-parser') -var app = express() +const app = express() // parse various different custom JSON types as JSON app.use(bodyParser.json({ type: 'application/*+json' })) @@ -446,11 +483,14 @@ app.use(bodyParser.text({ type: 'text/html' })) [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/body-parser.svg -[npm-url]: https://npmjs.org/package/body-parser -[coveralls-image]: https://img.shields.io/coveralls/expressjs/body-parser/master.svg +[ci-image]: https://badgen.net/github/checks/expressjs/body-parser/master?label=ci +[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml +[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/body-parser/master [coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master -[downloads-image]: https://img.shields.io/npm/dm/body-parser.svg -[downloads-url]: https://npmjs.org/package/body-parser -[github-actions-ci-image]: https://img.shields.io/github/workflow/status/expressjs/body-parser/ci/master?label=ci -[github-actions-ci-url]: https://github.com/expressjs/body-parser?query=workflow%3Aci +[node-version-image]: https://badgen.net/npm/node/body-parser +[node-version-url]: https://nodejs.org/en/download +[npm-downloads-image]: https://badgen.net/npm/dm/body-parser +[npm-url]: https://npmjs.org/package/body-parser +[npm-version-image]: https://badgen.net/npm/v/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 \ No newline at end of file diff --git a/_includes/readmes/compression.md b/_includes/readmes/compression.md index 680ece8776..df1bd78947 100644 --- a/_includes/readmes/compression.md +++ b/_includes/readmes/compression.md @@ -2,8 +2,10 @@ [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] -[![Build Status][travis-image]][travis-url] -[![Test Coverage][coveralls-image]][coveralls-url] +[![Build Status][github-actions-ci-image]][github-actions-ci-url] +[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer] +[![Funding][funding-image]][funding-url] + Node.js compression middleware. @@ -11,6 +13,9 @@ The following compression codings are supported: - deflate - gzip + - br (brotli) + +**Note** Brotli is supported only since Node.js versions v11.7.0 and v10.16.0. ## Install @@ -24,8 +29,6 @@ $ npm install compression ## API - - ```js var compression = require('compression') ``` @@ -33,7 +36,7 @@ var compression = require('compression') ### compression([options]) Returns the compression middleware using the given `options`. The middleware -will attempt to compress response bodies for all request that traverse through +will attempt to compress response bodies for all requests that traverse through the middleware, based on the given `options`. This middleware will never compress responses that include a `Cache-Control` @@ -43,18 +46,22 @@ as compressing will transform the body. #### Options `compression()` accepts these properties in the options object. In addition to -those listed below, [zlib](http://nodejs.org/api/zlib.html) options may be -passed in to the options object. +those listed below, [zlib](https://nodejs.org/api/zlib.html) options may be +passed in to the options object or +[brotli](https://nodejs.org/api/zlib.html#zlib_class_brotlioptions) options. ##### chunkSize -The default value is `zlib.Z_DEFAULT_CHUNK`, or `16384`. +Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_CHUNK`, or `16384`. -See [Node.js documentation](http://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) +See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) regarding the usage. ##### filter +Type: `Function` + A function to decide if the response should be considered for compression. This function is called as `filter(req, res)` and is expected to return `true` to consider the response for compression, or `false` to not compress @@ -65,6 +72,9 @@ module to determine if `res.getHeader('Content-Type')` is compressible. ##### level +Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_COMPRESSION`, or `-1` + The level of zlib compression to apply to responses. A higher level will result in better compression, but will take longer to complete. A lower level will result in less compression, but will be much faster. @@ -74,59 +84,71 @@ compression). The special value `-1` can be used to mean the "default compression level", which is a default compromise between speed and compression (currently equivalent to level 6). - - `-1` Default compression level (also `zlib.Z_DEFAULT_COMPRESSION`). - - `0` No compression (also `zlib.Z_NO_COMPRESSION`). - - `1` Fastest compression (also `zlib.Z_BEST_SPEED`). + - `-1` Default compression level (also `zlib.constants.Z_DEFAULT_COMPRESSION`). + - `0` No compression (also `zlib.constants.Z_NO_COMPRESSION`). + - `1` Fastest compression (also `zlib.constants.Z_BEST_SPEED`). - `2` - `3` - `4` - `5` - - `6` (currently what `zlib.Z_DEFAULT_COMPRESSION` points to). + - `6` (currently what `zlib.constants.Z_DEFAULT_COMPRESSION` points to). - `7` - `8` - - `9` Best compression (also `zlib.Z_BEST_COMPRESSION`). - -The default value is `zlib.Z_DEFAULT_COMPRESSION`, or `-1`. + - `9` Best compression (also `zlib.constants.Z_BEST_COMPRESSION`). **Note** in the list above, `zlib` is from `zlib = require('zlib')`. ##### memLevel +Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_MEMLEVEL`, or `8` + This specifies how much memory should be allocated for the internal compression state and is an integer in the range of `1` (minimum level) and `9` (maximum level). -The default value is `zlib.Z_DEFAULT_MEMLEVEL`, or `8`. - -See [Node.js documentation](http://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) +See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) regarding the usage. +##### brotli + +Type: `Object` + +This specifies the options for configuring Brotli. See [Node.js documentation](https://nodejs.org/api/zlib.html#class-brotlioptions) for a complete list of available options. + + ##### strategy +Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_STRATEGY` + This is used to tune the compression algorithm. This value only affects the compression ratio, not the correctness of the compressed output, even if it is not set appropriately. - - `zlib.Z_DEFAULT_STRATEGY` Use for normal data. - - `zlib.Z_FILTERED` Use for data produced by a filter (or predictor). + - `zlib.constants.Z_DEFAULT_STRATEGY` Use for normal data. + - `zlib.constants.Z_FILTERED` Use for data produced by a filter (or predictor). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect is to force more Huffman coding and less - string matching; it is somewhat intermediate between `zlib.Z_DEFAULT_STRATEGY` - and `zlib.Z_HUFFMAN_ONLY`. - - `zlib.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing + string matching; it is somewhat intermediate between `zlib.constants.Z_DEFAULT_STRATEGY` + and `zlib.constants.Z_HUFFMAN_ONLY`. + - `zlib.constants.Z_FIXED` Use to prevent the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. - - `zlib.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match). - - `zlib.Z_RLE` Use to limit match distances to one (run-length encoding). - This is designed to be almost as fast as `zlib.Z_HUFFMAN_ONLY`, but give + - `zlib.constants.Z_HUFFMAN_ONLY` Use to force Huffman encoding only (no string match). + - `zlib.constants.Z_RLE` Use to limit match distances to one (run-length encoding). + This is designed to be almost as fast as `zlib.constants.Z_HUFFMAN_ONLY`, but give better compression for PNG image data. **Note** in the list above, `zlib` is from `zlib = require('zlib')`. ##### threshold +Type: `Number` or `String`
+Default: `1kb` + The byte threshold for the response body size before compression is considered -for the response, defaults to `1kb`. This is a number of bytes or any string +for the response. This is a number of bytes or any string accepted by the [bytes](https://www.npmjs.com/package/bytes) module. **Note** this is only an advisory setting; if the response size cannot be determined @@ -136,11 +158,19 @@ set a `Content-Length` response header. ##### windowBits -The default value is `zlib.Z_DEFAULT_WINDOWBITS`, or `15`. +Type: `Number`
+Default: `zlib.constants.Z_DEFAULT_WINDOWBITS`, or `15` -See [Node.js documentation](http://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) +See [Node.js documentation](https://nodejs.org/api/zlib.html#zlib_memory_usage_tuning) regarding the usage. +##### enforceEncoding + +Type: `String`
+Default: `identity` + +This is the default encoding to use when the client does not specify an encoding in the request's [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header. + #### .filter The default `filter` function. This is used to construct a custom filter @@ -151,6 +181,7 @@ var compression = require('compression') var express = require('express') var app = express() + app.use(compression({ filter: shouldCompress })) function shouldCompress (req, res) { @@ -171,9 +202,9 @@ response to be flushed to the client. ## Examples -### express/connect +### express -When using this module with express or connect, simply `app.use` the module as +When using this module with express, simply `app.use` the module as high as you like. Requests that pass through the middleware will be compressed. ```js @@ -188,6 +219,36 @@ app.use(compression()) // add all routes ``` +### Node.js HTTP server + +```js +var compression = require('compression')({ threshold: 0 }) +var http = require('http') + +function createServer (fn) { + return http.createServer(function (req, res) { + compression(req, res, function (err) { + if (err) { + res.statusCode = err.status || 500 + res.end(err.message) + return + } + + fn(req, res) + }) + }) +} + +var server = createServer(function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end('hello world!') +}) + +server.listen(3000, () => { + console.log('> Listening at http://localhost:3000') +}) +``` + ### Server-Sent Events Because of the nature of compression this module does not work out of the box @@ -226,15 +287,25 @@ app.get('/events', function (req, res) { }) ``` +## Contributing + +The Express.js project welcomes all constructive contributions. Contributions take many forms, +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. + ## License [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/compression.svg +[npm-image]: https://badgen.net/npm/v/compression [npm-url]: https://npmjs.org/package/compression -[travis-image]: https://img.shields.io/travis/expressjs/compression/master.svg -[travis-url]: https://travis-ci.org/expressjs/compression -[coveralls-image]: https://img.shields.io/coveralls/expressjs/compression/master.svg -[coveralls-url]: https://coveralls.io/r/expressjs/compression?branch=master -[downloads-image]: https://img.shields.io/npm/dm/compression.svg -[downloads-url]: https://npmjs.org/package/compression +[downloads-image]: https://badgen.net/npm/dm/compression +[downloads-url]: https://npmcharts.com/compare/compression?minimal=true +[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/compression/master?label=CI +[github-actions-ci-url]: https://github.com/expressjs/compression/actions?query=workflow%3Aci +[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 +[funding-image]: https://badgen.net/badge/icon/sponsor/pink?icon=github&label=Open%20Collective \ No newline at end of file diff --git a/_includes/readmes/connect-rid.md b/_includes/readmes/connect-rid.md index 207cc44157..62c34d3788 100644 --- a/_includes/readmes/connect-rid.md +++ b/_includes/readmes/connect-rid.md @@ -1,3 +1,11 @@ +> [!CAUTION] +> **This repository is archived and no longer actively maintained.** +> +> We are no longer accepting issues, feature requests, or pull requests. +> For additional support or questions, please visit the [Express.js Discussions page](https://github.com/expressjs/express/discussions). + + + connect-rid ======= diff --git a/_includes/readmes/cookie-session.md b/_includes/readmes/cookie-session.md index 1d97e8da52..c066746b34 100644 --- a/_includes/readmes/cookie-session.md +++ b/_includes/readmes/cookie-session.md @@ -2,7 +2,7 @@ [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] -[![Build Status][travis-image]][travis-url] +[![Build Status][ci-image]][ci-url] [![Test Coverage][coveralls-image]][coveralls-url] Simple cookie-based session middleware. @@ -21,6 +21,16 @@ The following points can help you choose which to use: * `cookie-session` can be used to store a "light" session and include an identifier to look up a database-backed secondary store to reduce database lookups. +**NOTE** This module does not encrypt the session contents in the cookie, only provides +signing to prevent tampering. The client will be able to read the session data by +examining the cookie's value. Secret data should not be set in `req.session` without +encrypting it, or use a server-side session instead. + +**NOTE** This module does not prevent session replay, as the expiration set is that +of the cookie only; if that is a concern of your application, you can store an expiration +date in `req.session` object and validate it on the server, and implement any other logic +to extend the session as your application needs. + ## Install This is a [Node.js](https://nodejs.org/en/) module available through the @@ -93,6 +103,8 @@ The options can also contain any of the following (for the full list, see - `expires`: a `Date` object indicating the cookie's expiration date (expires at the end of session by default). - `path`: a string indicating the path of the cookie (`/` by default). - `domain`: a string indicating the domain of the cookie (no default). + - `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](https://expressjs.com/en/guide/behind-proxies.html) 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). @@ -125,7 +137,7 @@ altered to change cookie setting behavior on a per-request basis. To destroy a session simply set it to `null`: -``` +```js req.session = null ``` @@ -243,7 +255,7 @@ app.use(cookieSession({ ### Max Cookie Size Because the entire session object is encoded and stored in a cookie, it is -possible to exceed the maxium cookie size limits on different browsers. The +possible to exceed the maximum cookie size limits on different browsers. The [RFC6265 specification](https://tools.ietf.org/html/rfc6265#section-6.1) recommends that a browser **SHOULD** allow @@ -251,7 +263,7 @@ recommends that a browser **SHOULD** allow > the cookie's name, value, and attributes) In practice this limit differs slightly across browsers. See a list of -[browser limits here](http://browsercookielimits.squawky.net/). As a rule +[browser limits here](http://browsercookielimits.iain.guru). As a rule of thumb **don't exceed 4093 bytes per domain**. If your session object is large enough to exceed a browser limit when encoded, @@ -269,10 +281,10 @@ move to an [alternative session strategy](https://github.com/expressjs/session#c [MIT](LICENSE) +[ci-image]: https://badgen.net/github/checks/expressjs/cookie-session/master?label=ci +[ci-url]: https://github.com/expressjs/cookie-session/actions?query=workflow%3Aci [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-session/master [coveralls-url]: https://coveralls.io/r/expressjs/cookie-session?branch=master [npm-downloads-image]: https://badgen.net/npm/dm/cookie-session [npm-url]: https://npmjs.org/package/cookie-session [npm-version-image]: https://badgen.net/npm/v/cookie-session -[travis-image]: https://badgen.net/travis/expressjs/cookie-session/master -[travis-url]: https://travis-ci.org/expressjs/cookie-session diff --git a/_includes/readmes/cors.md b/_includes/readmes/cors.md index 60ab20c86e..527a0f314e 100644 --- a/_includes/readmes/cors.md +++ b/_includes/readmes/cors.md @@ -16,9 +16,8 @@ CORS is a node.js package for providing a [Connect](http://www.senchalabs.org/co * [Configuring CORS](#configuring-cors) * [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin) * [Enabling CORS Pre-Flight](#enabling-cors-pre-flight) - * [Configuring CORS Asynchronously](#configuring-cors-asynchronously) + * [Customizing CORS Settings Dynamically per Request](#customizing-cors-settings-dynamically-per-request) * [Configuration Options](#configuration-options) -* [Demo](#demo) * [License](#license) * [Author](#author) @@ -70,6 +69,8 @@ app.listen(80, function () { ### Configuring CORS +See the [configuration options](#configuration-options) for details. + ```javascript var express = require('express') var cors = require('cors') @@ -162,27 +163,45 @@ NOTE: When using this middleware as an application level middleware (for example, `app.use(cors())`), pre-flight requests are already handled for all routes. -### Configuring CORS Asynchronously +### Customizing CORS Settings Dynamically per Request -```javascript -var express = require('express') -var cors = require('cors') -var app = express() +For APIs that require different CORS configurations for specific routes or requests, you can dynamically generate CORS options based on the incoming request. The `cors` middleware allows you to achieve this by passing a function instead of static options. This function is called for each incoming request and must use the callback pattern to return the appropriate CORS options. -var allowlist = ['http://example1.com', 'http://example2.com'] -var corsOptionsDelegate = function (req, callback) { +The function accepts: +1. **`req`**: + - The incoming request object. + +2. **`callback(error, corsOptions)`**: + - A function used to return the computed CORS options. + - **Arguments**: + - **`error`**: Pass `null` if there’s no error, or an error object to indicate a failure. + - **`corsOptions`**: An object specifying the CORS policy for the current request. + +Here’s an example that handles both public routes and restricted, credential-sensitive routes: + +```javascript +var dynamicCorsOptions = function(req, callback) { var corsOptions; - if (allowlist.indexOf(req.header('Origin')) !== -1) { - corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response + if (req.path.startsWith('/auth/connect/')) { + corsOptions = { + origin: 'http://mydomain.com', // Allow only a specific origin + credentials: true, // Enable cookies and credentials + }; } else { - corsOptions = { origin: false } // disable CORS for this request + corsOptions = { origin: '*' }; // Allow all origins for other routes } - callback(null, corsOptions) // callback expects two parameters: error and options -} + callback(null, corsOptions); +}; -app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) { - res.json({msg: 'This is CORS-enabled for an allowed domain.'}) -}) +app.use(cors(dynamicCorsOptions)); + +app.get('/auth/connect/twitter', function (req, res) { + res.send('CORS dynamically applied for Twitter authentication.'); +}); + +app.get('/public', function (req, res) { + res.send('Public data with open CORS.'); +}); app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') @@ -193,7 +212,9 @@ app.listen(80, function () { * `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values: - `Boolean` - set `origin` to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as defined by `req.header('Origin')`, or set it to `false` to disable CORS. - - `String` - set `origin` to a specific origin. For example if you set it to `"http://example.com"` only requests from "http://example.com" will be allowed. + - `String` - set `origin` to a specific origin. For example, if you set it to + - `"http://example.com"` only requests from "http://example.com" will be allowed. + - `"*"` for all domains to be allowed. - `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com". - `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com". - `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second. @@ -216,16 +237,7 @@ The default configuration is the equivalent of: } ``` -For details on the effect of each CORS header, read [this](http://www.html5rocks.com/en/tutorials/cors/) article on HTML5 Rocks. - -## Demo - -A demo that illustrates CORS working (and not working) using React is available here: [https://node-cors-client.netlify.com](https://node-cors-client.netlify.com) - -Code for that demo can be found here: - -* Client: [https://github.com/troygoode/node-cors-client](https://github.com/troygoode/node-cors-client) -* Server: [https://github.com/troygoode/node-cors-server](https://github.com/troygoode/node-cors-server) +For details on the effect of each CORS header, read [this](https://web.dev/cross-origin-resource-sharing/) article on web.dev. ## License @@ -239,7 +251,7 @@ Code for that demo can be found here: [coveralls-url]: https://coveralls.io/r/expressjs/cors?branch=master [downloads-image]: https://img.shields.io/npm/dm/cors.svg [downloads-url]: https://npmjs.org/package/cors -[github-actions-ci-image]: https://img.shields.io/github/workflow/status/expressjs/cors/ci/master?label=ci +[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/cors/ci.yml?branch=master&label=ci [github-actions-ci-url]: https://github.com/expressjs/cors?query=workflow%3Aci [npm-image]: https://img.shields.io/npm/v/cors.svg [npm-url]: https://npmjs.org/package/cors diff --git a/_includes/readmes/csurf.md b/_includes/readmes/csurf.md deleted file mode 100644 index 3a9ab91c37..0000000000 --- a/_includes/readmes/csurf.md +++ /dev/null @@ -1,326 +0,0 @@ -# csurf - -[![NPM Version][npm-version-image]][npm-url] -[![NPM Downloads][npm-downloads-image]][node-url] -[![Build status][travis-image]][travis-url] -[![Test coverage][coveralls-image]][coveralls-url] - -Node.js [CSRF][wikipedia-csrf] protection middleware. - -Requires either a session middleware or [cookie-parser](https://www.npmjs.com/package/cookie-parser) to be initialized first. - - * If you are setting the ["cookie" option](#cookie) to a non-`false` value, - then you must use [cookie-parser](https://www.npmjs.com/package/cookie-parser) - before this module. - * Otherwise, you must use a session middleware before this module. For example: - - [express-session](https://www.npmjs.com/package/express-session) - - [cookie-session](https://www.npmjs.com/package/cookie-session) - -If you have questions on how this module is implemented, please read -[Understanding CSRF](https://github.com/pillarjs/understanding-csrf). - -## Installation - -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): - -```sh -$ npm install csurf -``` - -## API - - - -```js -var csurf = require('csurf') -``` - -### csurf([options]) - -Create a middleware for CSRF token creation and validation. This middleware -adds a `req.csrfToken()` function to make a token which should be added to -requests which mutate state, within a hidden form field, query-string etc. -This token is validated against the visitor's session or csrf cookie. - -#### Options - -The `csurf` function takes an optional `options` object that may contain -any of the following keys: - -##### cookie - -Determines if the token secret for the user should be stored in a cookie -or in `req.session`. Storing the token secret in a cookie implements -the [double submit cookie pattern][owsap-csrf-double-submit]. -Defaults to `false`. - -When set to `true` (or an object of options for the cookie), then the module -changes behavior and no longer uses `req.session`. This means you _are no -longer required to use a session middleware_. Instead, you do need to use the -[cookie-parser](https://www.npmjs.com/package/cookie-parser) middleware in -your app before this middleware. - -When set to an object, cookie storage of the secret is enabled and the -object contains options for this functionality (when set to `true`, the -defaults for the options are used). The options may contain any of the -following keys: - - - `key` - the name of the cookie to use to store the token secret - (defaults to `'_csrf'`). - - `path` - the path of the cookie (defaults to `'/'`). - - `signed` - indicates if the cookie should be signed (defaults to `false`). - - `secure` - marks the cookie to be used with HTTPS only (defaults to - `false`). - - `maxAge` - the number of seconds after which the cookie will expire - (defaults to session length). - - `httpOnly` - flags the cookie to be accessible only by the web server - (defaults to `false`). - - `sameSite` - sets the same site policy for the cookie(defaults to - `false`). This can be set to `'strict'`, `'lax'`, `'none'`, or `true` - (which maps to `'strict'`). - - `domain` - sets the domain the cookie is valid on(defaults to current - domain). - -##### ignoreMethods - -An array of the methods for which CSRF token checking will disabled. -Defaults to `['GET', 'HEAD', 'OPTIONS']`. - -##### sessionKey - -Determines what property ("key") on `req` the session object is located. -Defaults to `'session'` (i.e. looks at `req.session`). The CSRF secret -from this library is stored and read as `req[sessionKey].csrfSecret`. - -If the ["cookie" option](#cookie) is not `false`, then this option does -nothing. - -##### value - -Provide a function that the middleware will invoke to read the token from -the request for validation. The function is called as `value(req)` and is -expected to return the token as a string. - -The default value is a function that reads the token from the following -locations, in order: - - - `req.body._csrf` - typically generated by the `body-parser` module. - - `req.query._csrf` - a built-in from Express.js to read from the URL - query string. - - `req.headers['csrf-token']` - the `CSRF-Token` HTTP request header. - - `req.headers['xsrf-token']` - the `XSRF-Token` HTTP request header. - - `req.headers['x-csrf-token']` - the `X-CSRF-Token` HTTP request header. - - `req.headers['x-xsrf-token']` - the `X-XSRF-Token` HTTP request header. - -## Example - -### Simple express example - -The following is an example of some server-side code that generates a form -that requires a CSRF token to post back. - -```js -var cookieParser = require('cookie-parser') -var csrf = require('csurf') -var bodyParser = require('body-parser') -var express = require('express') - -// setup route middlewares -var csrfProtection = csrf({ cookie: true }) -var parseForm = bodyParser.urlencoded({ extended: false }) - -// create express app -var app = express() - -// parse cookies -// we need this because "cookie" is true in csrfProtection -app.use(cookieParser()) - -app.get('/form', csrfProtection, function (req, res) { - // pass the csrfToken to the view - res.render('send', { csrfToken: req.csrfToken() }) -}) - -app.post('/process', parseForm, csrfProtection, function (req, res) { - res.send('data is being processed') -}) -``` - -Inside the view (depending on your template language; handlebars-style -is demonstrated here), set the `csrfToken` value as the value of a hidden -input field named `_csrf`: - -```html -
- - - Favorite color: - -
-``` - -#### Using AJAX - -When accessing protected routes via ajax both the csrf token will need to be -passed in the request. Typically this is done using a request header, as adding -a request header can typically be done at a central location easily without -payload modification. - -The CSRF token is obtained from the `req.csrfToken()` call on the server-side. -This token needs to be exposed to the client-side, typically by including it in -the initial page content. One possibility is to store it in an HTML `` tag, -where value can then be retrieved at the time of the request by JavaScript. - -The following can be included in your view (handlebar example below), where the -`csrfToken` value came from `req.csrfToken()`: - -```html - -``` - -The following is an example of using the -[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to post -to the `/process` route with the CSRF token from the `` tag on the page: - - - -```js -// Read the CSRF token from the tag -var token = document.querySelector('meta[name="csrf-token"]').getAttribute('content') - -// Make a request using the Fetch API -fetch('/process', { - credentials: 'same-origin', // <-- includes cookies in the request - headers: { - 'CSRF-Token': token // <-- is the csrf token as a header - }, - method: 'POST', - body: { - favoriteColor: 'blue' - } -}) -``` - -#### Single Page Application (SPA) - -Many SPA frameworks like Angular have CSRF support built in automatically. -Typically they will reflect the value from a specific cookie, like -`XSRF-TOKEN` (which is the case for Angular). - -To take advantage of this, set the value from `req.csrfToken()` in the cookie -used by the SPA framework. This is only necessary to do on the route that -renders the page (where `res.render` or `res.sendFile` is called in Express, -for example). - -The following is an example for Express of a typical SPA response: - - - -```js -app.all('*', function (req, res) { - res.cookie('XSRF-TOKEN', req.csrfToken()) - res.render('index') -}) -``` - -### Ignoring Routes - -**Note** CSRF checks should only be disabled for requests that you expect to -come from outside of your website. Do not disable CSRF checks for requests -that you expect to only come from your website. An existing session, even if -it belongs to an authenticated user, is not enough to protect against CSRF -attacks. - -The following is an example of how to order your routes so that certain endpoints -do not check for a valid CSRF token. - -```js -var cookieParser = require('cookie-parser') -var csrf = require('csurf') -var bodyParser = require('body-parser') -var express = require('express') - -// create express app -var app = express() - -// create api router -var api = createApiRouter() - -// mount api before csrf is appended to the app stack -app.use('/api', api) - -// now add csrf and other middlewares, after the "/api" was mounted -app.use(bodyParser.urlencoded({ extended: false })) -app.use(cookieParser()) -app.use(csrf({ cookie: true })) - -app.get('/form', function (req, res) { - // pass the csrfToken to the view - res.render('send', { csrfToken: req.csrfToken() }) -}) - -app.post('/process', function (req, res) { - res.send('csrf was required to get here') -}) - -function createApiRouter () { - var router = new express.Router() - - router.post('/getProfile', function (req, res) { - res.send('no csrf to get here') - }) - - return router -} -``` - -### Custom error handling - -When the CSRF token validation fails, an error is thrown that has -`err.code === 'EBADCSRFTOKEN'`. This can be used to display custom -error messages. - -```js -var bodyParser = require('body-parser') -var cookieParser = require('cookie-parser') -var csrf = require('csurf') -var express = require('express') - -var app = express() -app.use(bodyParser.urlencoded({ extended: false })) -app.use(cookieParser()) -app.use(csrf({ cookie: true })) - -// error handler -app.use(function (err, req, res, next) { - if (err.code !== 'EBADCSRFTOKEN') return next(err) - - // handle CSRF token errors here - res.status(403) - res.send('form tampered with') -}) -``` - -## References - -- [Cross-side request forgery on Wikipedia][wikipedia-csrf] -- [OWASP Cross-Site Request Forgery Prevention Cheat Sheet][owsap-csrf] - -[owsap-csrf]: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html -[owsap-csrf-double-submit]: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie -[wikipedia-csrf]: https://en.wikipedia.org/wiki/Cross-site_request_forgery - -## License - -[MIT](LICENSE) - -[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/csurf/master -[coveralls-url]: https://coveralls.io/r/expressjs/csurf?branch=master -[node-url]: https://nodejs.org/en/download -[npm-downloads-image]: https://badgen.net/npm/dm/csurf -[npm-url]: https://npmjs.org/package/csurf -[npm-version-image]: https://badgen.net/npm/v/csurf -[travis-image]: https://badgen.net/travis/expressjs/csurf/master -[travis-url]: https://travis-ci.org/expressjs/csurf diff --git a/_includes/readmes/errorhandler.md b/_includes/readmes/errorhandler.md index f0b03c0e60..0f2661ca30 100644 --- a/_includes/readmes/errorhandler.md +++ b/_includes/readmes/errorhandler.md @@ -80,6 +80,7 @@ var errorhandler = require('errorhandler') var app = connect() +// assumes NODE_ENV is set by the user if (process.env.NODE_ENV === 'development') { // only use in development app.use(errorhandler()) @@ -100,6 +101,7 @@ var notifier = require('node-notifier') var app = connect() +// assumes NODE_ENV is set by the user if (process.env.NODE_ENV === 'development') { // only use in development app.use(errorhandler({ log: errorNotification })) diff --git a/_includes/readmes/express-master/examples.md b/_includes/readmes/express-master/examples.md index c19ed30a25..bd1f1f6310 100644 --- a/_includes/readmes/express-master/examples.md +++ b/_includes/readmes/express-master/examples.md @@ -13,7 +13,6 @@ This page contains list of examples using Express. - [hello-world](./hello-world) - Simple request handler - [markdown](./markdown) - Markdown as template engine - [multi-router](./multi-router) - Working with multiple Express routers -- [multipart](./multipart) - Accepting multipart-encoded forms - [mvc](./mvc) - MVC-style controllers - [online](./online) - Tracking online user activity with `online` and `redis` packages - [params](./params) - Working with route parameters diff --git a/_includes/readmes/method-override.md b/_includes/readmes/method-override.md index 830b2ee0a9..ce96a96c9e 100644 --- a/_includes/readmes/method-override.md +++ b/_includes/readmes/method-override.md @@ -67,9 +67,9 @@ typically be used in conjunction with `XMLHttpRequest` on implementations that do not support the method you are trying to use. ```js -var express = require('express') -var methodOverride = require('method-override') -var app = express() +const express = require('express') +const methodOverride = require('method-override') +const app = express() // override with the X-HTTP-Method-Override header in the request app.use(methodOverride('X-HTTP-Method-Override')) @@ -80,7 +80,7 @@ Example call with header override using `XMLHttpRequest`: ```js -var xhr = new XMLHttpRequest() +const xhr = new XMLHttpRequest() xhr.onload = onload xhr.open('post', '/resource', true) xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE') @@ -102,9 +102,9 @@ query value would typically be used in conjunction with plain HTML newer methods. ```js -var express = require('express') -var methodOverride = require('method-override') -var app = express() +const express = require('express') +const methodOverride = require('method-override') +const app = express() // override with POST having ?_method=DELETE app.use(methodOverride('_method')) @@ -121,9 +121,9 @@ Example call with query override using HTML `
`: ### multiple format support ```js -var express = require('express') -var methodOverride = require('method-override') -var app = express() +const express = require('express') +const methodOverride = require('method-override') +const app = express() // override with different headers; last one takes precedence app.use(methodOverride('X-HTTP-Method')) // Microsoft @@ -137,10 +137,10 @@ You can implement any kind of custom logic with a function for the `getter`. The implements the logic for looking in `req.body` that was in `method-override@1`: ```js -var bodyParser = require('body-parser') -var express = require('express') -var methodOverride = require('method-override') -var app = express() +const bodyParser = require('body-parser') +const express = require('express') +const methodOverride = require('method-override') +const app = express() // NOTE: when using req.body, you must fully parse the request body // before you call methodOverride() in your middleware stack, @@ -149,7 +149,7 @@ app.use(bodyParser.urlencoded()) app.use(methodOverride(function (req, res) { if (req.body && typeof req.body === 'object' && '_method' in req.body) { // look in urlencoded POST bodies and delete it - var method = req.body._method + const method = req.body._method delete req.body._method return method } diff --git a/_includes/readmes/morgan.md b/_includes/readmes/morgan.md index 7d4540b953..cc6379790c 100644 --- a/_includes/readmes/morgan.md +++ b/_includes/readmes/morgan.md @@ -2,8 +2,8 @@ [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] -[![Build Status][travis-image]][travis-url] -[![Test Coverage][coveralls-image]][coveralls-url] +[![Build Status][ci-image]][ci-url] +[![Coverage Status][coveralls-image]][coveralls-url] HTTP request logger middleware for node.js @@ -105,9 +105,10 @@ There are various pre-defined formats provided: ##### combined Standard Apache combined log output. - ``` :remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" +# will output +::1 - - [27/Nov/2024:06:21:42 +0000] "GET /combined HTTP/1.1" 200 2 "-" "curl/8.7.1" ``` ##### common @@ -116,6 +117,8 @@ Standard Apache common log output. ``` :remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] +# will output +::1 - - [27/Nov/2024:06:21:46 +0000] "GET /common HTTP/1.1" 200 2 ``` ##### dev @@ -127,6 +130,8 @@ for information codes. ``` :method :url :status :response-time ms - :res[content-length] +# will output +GET /dev 200 0.224 ms - 2 ``` ##### short @@ -135,6 +140,8 @@ Shorter than default, also including response time. ``` :remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms +# will output +::1 - GET /short HTTP/1.1 200 2 - 0.283 ms ``` ##### tiny @@ -143,6 +150,8 @@ The minimal output. ``` :method :url :status :res[content-length] - :response-time ms +# will output +GET /tiny 200 2 - 0.188 ms ``` #### Tokens @@ -418,10 +427,10 @@ function assignId (req, res, next) { [MIT](LICENSE) +[ci-image]: https://badgen.net/github/checks/expressjs/morgan/master?label=ci +[ci-url]: https://github.com/expressjs/morgan/actions/workflows/ci.yml [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/morgan/master [coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master [npm-downloads-image]: https://badgen.net/npm/dm/morgan [npm-url]: https://npmjs.org/package/morgan [npm-version-image]: https://badgen.net/npm/v/morgan -[travis-image]: https://badgen.net/travis/expressjs/morgan/master -[travis-url]: https://travis-ci.org/expressjs/morgan diff --git a/_includes/readmes/multer.md b/_includes/readmes/multer.md index 03951be79c..1e062ee7d3 100644 --- a/_includes/readmes/multer.md +++ b/_includes/readmes/multer.md @@ -1,24 +1,30 @@ -# Multer [![Build Status](https://travis-ci.org/expressjs/multer.svg?branch=master)](https://travis-ci.org/expressjs/multer) [![NPM version](https://badge.fury.io/js/multer.svg)](https://badge.fury.io/js/multer) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) +# Multer [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Test Coverage][test-image]][test-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer] Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written 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 +## Translations This README is also available in other languages: -- [Español](https://github.com/expressjs/multer/blob/master/doc/README-es.md) (Spanish) -- [简体中文](https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md) (Chinese) -- [한국어](https://github.com/expressjs/multer/blob/master/doc/README-ko.md) (Korean) -- [Русский язык](https://github.com/expressjs/multer/blob/master/doc/README-ru.md) (Russian) -- [Português](https://github.com/expressjs/multer/blob/master/doc/README-pt-br.md) (Portuguese Brazil) +| | | +| ------------------------------------------------------------------------------ | --------------- | +| [العربية](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 | ## Installation ```sh -$ npm install --save multer +$ npm install multer ``` ## Usage @@ -52,8 +58,8 @@ app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) // req.body will contain the text fields, if there were any }) -const cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }]) -app.post('/cool-profile', cpUpload, function (req, res, next) { +const uploadMiddleware = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }]) +app.post('/cool-profile', uploadMiddleware, function (req, res, next) { // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files // // e.g. @@ -77,14 +83,14 @@ app.post('/profile', upload.none(), function (req, res, next) { }) ``` -Here's an example on how multer is used an HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields: +Here's an example on how multer is used in a HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields: ```html
- +
``` @@ -95,9 +101,9 @@ Then in your javascript file you would add these lines to access both the file a const multer = require('multer') const upload = multer({ dest: './public/data/uploads/' }) app.post('/stats', upload.single('uploaded_file'), function (req, res) { - // req.file is the name of your file in the form above, here 'uploaded_file' - // req.body will hold the text fields, if there were any - console.log(req.file, req.body) + // req.file is the name of your file in the form above, here 'uploaded_file' + // req.body will hold the text fields, if there were any + console.log(req.file, req.body) }); ``` @@ -228,7 +234,7 @@ If no `filename` is given, each file will be given a random name that doesn't include any file extension. **Note:** Multer will not append any file extension for you, your function -should return a filename complete with an file extension. +should return a filename complete with a file extension. Each function gets passed both the request (`req`) and some information about the file (`file`) to aid with the decision. @@ -238,7 +244,7 @@ order that the client transmits fields and files to the server. For understanding the calling convention used in the callback (needing to pass null as the first param), refer to -[Node.js error handling](https://www.joyent.com/node-js/production/design/errors) +[Node.js error handling](https://web.archive.org/web/20220417042018/https://www.joyent.com/node-js/production/design/errors) #### `MemoryStorage` @@ -304,7 +310,7 @@ When encountering an error, Multer will delegate the error to Express. You can display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html). 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/master/lib/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`). +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`). ```javascript const multer = require('multer') @@ -325,8 +331,18 @@ app.post('/profile', function (req, res) { ## Custom storage engine -For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/master/StorageEngine.md). +For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md). ## License [MIT](LICENSE) + +[ci-image]: https://github.com/expressjs/multer/actions/workflows/ci.yml/badge.svg +[ci-url]: https://github.com/expressjs/multer/actions/workflows/ci.yml +[test-url]: https://coveralls.io/r/expressjs/multer?branch=main +[test-image]: https://badgen.net/coveralls/c/github/expressjs/multer/main +[npm-downloads-image]: https://badgen.net/npm/dm/multer +[npm-url]: https://npmjs.org/package/multer +[npm-version-image]: https://badgen.net/npm/v/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 \ No newline at end of file diff --git a/_includes/readmes/response-time.md b/_includes/readmes/response-time.md index e631266c06..4e26aee0fe 100644 --- a/_includes/readmes/response-time.md +++ b/_includes/readmes/response-time.md @@ -1,8 +1,9 @@ # response-time -[![NPM Version][npm-image]][npm-url] -[![NPM Downloads][downloads-image]][downloads-url] -[![Build Status][travis-image]][travis-url] +[![NPM Version][npm-version-image]][npm-url] +[![NPM Downloads][npm-downloads-image]][npm-url] +[![Node.js Version][node-image]][node-url] +[![Build Status][ci-image]][ci-url] [![Test Coverage][coveralls-image]][coveralls-url] Response time for Node.js servers. @@ -130,11 +131,12 @@ app.get('/', function (req, res) { [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/response-time.svg +[npm-version-image]: https://badgen.net/npm/v/response-time [npm-url]: https://npmjs.org/package/response-time -[travis-image]: https://img.shields.io/travis/expressjs/response-time/master.svg -[travis-url]: https://travis-ci.org/expressjs/response-time -[coveralls-image]: https://img.shields.io/coveralls/expressjs/response-time/master.svg -[coveralls-url]: https://coveralls.io/r/expressjs/response-time?branch=master -[downloads-image]: https://img.shields.io/npm/dm/response-time.svg -[downloads-url]: https://npmjs.org/package/response-time +[npm-downloads-image]: https://badgen.net/npm/dm/response-time +[node-image]: https://badgen.net/npm/node/response-time +[node-url]: https://nodejs.org/en/download +[ci-image]: https://badgen.net/github/checks/express/response-time/master?label=ci +[ci-url]: https://github.com/express/response-time/actions/workflows/ci.yml +[coveralls-image]: https://badgen.net/coveralls/c/github/express/response-time/master +[coveralls-url]: https://coveralls.io/r/express/response-time?branch=master diff --git a/_includes/readmes/serve-favicon.md b/_includes/readmes/serve-favicon.md index c359cf4a6b..a7f94b4520 100644 --- a/_includes/readmes/serve-favicon.md +++ b/_includes/readmes/serve-favicon.md @@ -2,9 +2,9 @@ [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] -[![Linux Build][travis-image]][travis-url] -[![Windows Build][appveyor-image]][appveyor-url] -[![Test Coverage][coveralls-image]][coveralls-url] +[![Linux Build Status][ci-image]][ci-url] +[![Coverage Status][coveralls-image]][coveralls-url] +[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer] Node.js middleware for serving a favicon. @@ -124,13 +124,13 @@ server.listen(3000) [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/serve-favicon.svg -[npm-url]: https://npmjs.org/package/serve-favicon -[travis-image]: https://img.shields.io/travis/expressjs/serve-favicon/master.svg?label=linux -[travis-url]: https://travis-ci.org/expressjs/serve-favicon -[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-favicon/master.svg?label=windows -[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-favicon +[ci-image]: https://badgen.net/github/checks/expressjs/serve-favicon/master?label=ci +[ci-url]: https://github.com/expressjs/serve-favicon/actions/workflows/ci.yml [coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-favicon.svg [coveralls-url]: https://coveralls.io/r/expressjs/serve-favicon?branch=master [downloads-image]: https://img.shields.io/npm/dm/serve-favicon.svg [downloads-url]: https://npmjs.org/package/serve-favicon +[npm-image]: https://img.shields.io/npm/v/serve-favicon.svg +[npm-url]: https://npmjs.org/package/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/_includes/readmes/serve-index.md b/_includes/readmes/serve-index.md index 3e124605bc..f720b0d950 100644 --- a/_includes/readmes/serve-index.md +++ b/_includes/readmes/serve-index.md @@ -2,9 +2,9 @@ [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] -[![Linux Build][travis-image]][travis-url] +[![Linux Build Status][ci-image]][ci-url] [![Windows Build][appveyor-image]][appveyor-url] -[![Test Coverage][coveralls-image]][coveralls-url] +[![Coverage Status][coveralls-image]][coveralls-url] Serves pages that contain directory listings for a given path. @@ -139,13 +139,13 @@ app.listen(3000) [MIT](LICENSE). The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons are created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/). -[npm-image]: https://img.shields.io/npm/v/serve-index.svg -[npm-url]: https://npmjs.org/package/serve-index -[travis-image]: https://img.shields.io/travis/expressjs/serve-index/master.svg?label=linux -[travis-url]: https://travis-ci.org/expressjs/serve-index [appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-index/master.svg?label=windows [appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-index +[ci-image]: https://badgen.net/github/checks/expressjs/serve-index/master?label=ci +[ci-url]: https://github.com/expressjs/serve-index/actions/workflows/ci.yml [coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-index/master.svg [coveralls-url]: https://coveralls.io/r/expressjs/serve-index?branch=master [downloads-image]: https://img.shields.io/npm/dm/serve-index.svg [downloads-url]: https://npmjs.org/package/serve-index +[npm-image]: https://img.shields.io/npm/v/serve-index.svg +[npm-url]: https://npmjs.org/package/serve-index \ No newline at end of file diff --git a/_includes/readmes/serve-static.md b/_includes/readmes/serve-static.md index 7cce428cbb..70f01c3198 100644 --- a/_includes/readmes/serve-static.md +++ b/_includes/readmes/serve-static.md @@ -2,8 +2,7 @@ [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] -[![Linux Build][travis-image]][travis-url] -[![Windows Build][appveyor-image]][appveyor-url] +[![CI][github-actions-ci-image]][github-actions-ci-url] [![Test Coverage][coveralls-image]][coveralls-url] ## Install @@ -18,8 +17,6 @@ $ npm install serve-static ## API - - ```js var serveStatic = require('serve-static') ``` @@ -47,7 +44,7 @@ true. Disabling this will ignore the `immutable` and `maxAge` options. ##### dotfiles - Set how "dotfiles" are treated when encountered. A dotfile is a file +Set how "dotfiles" are treated when encountered. A dotfile is a file or directory that begins with a dot ("."). Note this check is done on the path itself without checking if the path actually exists on the disk. If `root` is specified, only the dotfiles above the root are @@ -58,8 +55,7 @@ to "deny"). - `'deny'` Deny a request for a dotfile and 403/`next()`. - `'ignore'` Pretend like the dotfile does not exist and 404/`next()`. -The default value is similar to `'ignore'`, with the exception that this -default will not ignore the files within a directory that begins with a dot. +The default value is `'ignore'`. ##### etag @@ -141,7 +137,7 @@ var http = require('http') var serveStatic = require('serve-static') // Serve up public/ftp folder -var serve = serveStatic('public/ftp', { 'index': ['index.html', 'index.htm'] }) +var serve = serveStatic('public/ftp', { index: ['index.html', 'index.htm'] }) // Create server var server = http.createServer(function onRequest (req, res) { @@ -162,8 +158,8 @@ var serveStatic = require('serve-static') // Serve up public/ftp folder var serve = serveStatic('public/ftp', { - 'index': false, - 'setHeaders': setHeaders + index: false, + setHeaders: setHeaders }) // Set header to force download @@ -192,15 +188,15 @@ var serveStatic = require('serve-static') var app = express() -app.use(serveStatic('public/ftp', { 'index': ['default.html', 'default.htm'] })) +app.use(serveStatic('public/ftp', { index: ['default.html', 'default.htm'] })) app.listen(3000) ``` #### Multiple roots This example shows a simple way to search through multiple directories. -Files are look for in `public-optimized/` first, then `public/` second as -a fallback. +Files are searched for in `public-optimized/` first, then `public/` second +as a fallback. ```js var express = require('express') @@ -217,7 +213,7 @@ app.listen(3000) #### Different settings for paths This example shows how to set a different max age depending on the served -file type. In this example, HTML files are not cached, while everything else +file. In this example, HTML files are not cached, while everything else is for 1 day. ```js @@ -234,8 +230,8 @@ app.use(serveStatic(path.join(__dirname, 'public'), { app.listen(3000) -function setCustomCacheControl (res, path) { - if (serveStatic.mime.lookup(path) === 'text/html') { +function setCustomCacheControl (res, file) { + if (path.extname(file) === '.html') { // Custom Cache-Control for HTML files res.setHeader('Cache-Control', 'public, max-age=0') } @@ -246,14 +242,12 @@ function setCustomCacheControl (res, path) { [MIT](LICENSE) -[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/serve-static/master?label=windows -[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-static [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/serve-static/master [coveralls-url]: https://coveralls.io/r/expressjs/serve-static?branch=master +[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/serve-static/master?label=linux +[github-actions-ci-url]: https://github.com/expressjs/serve-static/actions/workflows/ci.yml [node-image]: https://badgen.net/npm/node/serve-static [node-url]: https://nodejs.org/en/download/ [npm-downloads-image]: https://badgen.net/npm/dm/serve-static [npm-url]: https://npmjs.org/package/serve-static [npm-version-image]: https://badgen.net/npm/v/serve-static -[travis-image]: https://badgen.net/travis/expressjs/serve-static/master?label=linux -[travis-url]: https://travis-ci.org/expressjs/serve-static diff --git a/_includes/readmes/session.md b/_includes/readmes/session.md index 01477c3937..b880e6b4a7 100644 --- a/_includes/readmes/session.md +++ b/_includes/readmes/session.md @@ -89,14 +89,41 @@ no maximum age is set. **Note** If both `expires` and `maxAge` are set in the options, then the last one defined in the object is what is used. +##### cookie.partitioned + +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. + +**Note** This is an attribute that has not yet been fully standardized, and may +change in the future. This also means many clients may ignore this attribute until +they understand it. + +More information about can be found in [the proposal](https://github.com/privacycg/CHIPS). + ##### cookie.path Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which is the root path of the domain. +##### cookie.priority + +Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. + + - `'low'` will set the `Priority` attribute to `Low`. + - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set. + - `'high'` will set the `Priority` attribute to `High`. + +More information about the different priority levels can be found in +[the specification][rfc-west-cookie-priority-00-4.1]. + +**Note** This is an attribute that has not yet been fully standardized, and may change in the future. +This also means many clients may ignore this attribute until they understand it. + ##### cookie.sameSite Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute. +By default, this is `false`. - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. - `false` will not set the `SameSite` attribute. @@ -242,7 +269,7 @@ With this enabled, the session identifier cookie will expire in [`maxAge`](#cookiemaxage) since the last response was sent instead of in [`maxAge`](#cookiemaxage) since the session was last modified by the server. -This is typically used in conjuction with short, non-session-length +This is typically used in conjunction with short, non-session-length [`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data with reduced potential of it occurring during on going server interactions. @@ -273,12 +300,13 @@ it to be saved. *This has been fixed in PassportJS 0.3.0* **Required option** -This is the secret used to sign the session ID cookie. This can be either a string -for a single secret, or an array of multiple secrets. 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. The -secret itself should be not easily parsed by a human and would best be a random set -of characters. A best practice may include: +This is the secret used to sign the session ID cookie. The secret can be any type +of value that is supported by Node.js `crypto.createHmac` (like a string or a +`Buffer`). This can be either a single secret, or an array of multiple secrets. 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. The secret itself should be not easily parsed by a human and +would best be a random set of characters. A best practice may include: - The use of environment variables to store the secret, ensuring the secret itself does not exist in your repository. @@ -293,6 +321,9 @@ the secret without invalidating sessions, provide an array of secrets, with the secret as first element of the array, and including previous secrets as the later elements. +**Note** HMAC-256 is used to sign the session ID. For this reason, the secret should +contain at least 32 bytes of entropy. + ##### store The session store instance, defaults to a new `MemoryStore` instance. @@ -555,6 +586,11 @@ and other multi-core embedded devices). [connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store [connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85 +[![★][connect-cosmosdb-image] connect-cosmosdb][connect-cosmosdb-url] An Azure [Cosmos DB](https://azure.microsoft.com/en-us/products/cosmos-db/)-based session store. + +[connect-cosmosdb-url]: https://www.npmjs.com/package/connect-cosmosdb +[connect-cosmosdb-image]: https://badgen.net/github/stars/thekillingspree/connect-cosmosdb?label=%E2%98%85 + [![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store. [connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase @@ -595,6 +631,11 @@ and other multi-core embedded devices). [connect-loki-url]: https://www.npmjs.com/package/connect-loki [connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85 +[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store. + +[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb +[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85 + [![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store. [connect-memcached-url]: https://www.npmjs.com/package/connect-memcached @@ -631,6 +672,16 @@ and other multi-core embedded devices). [connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2 [connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85 +[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store. + +[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j +[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85 + +[![★][connect-ottoman-image] connect-ottoman][connect-ottoman-url] A [couchbase ottoman](http://www.couchbase.com/)-based session store. + +[connect-ottoman-url]: https://www.npmjs.com/package/connect-ottoman +[connect-ottoman-image]: https://badgen.net/github/stars/noiissyboy/connect-ottoman?label=%E2%98%85 + [![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store. [connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple @@ -678,6 +729,11 @@ and other multi-core embedded devices). [dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store [dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85 +[![★][dynamodb-store-v3-image] dynamodb-store-v3][dynamodb-store-v3-url] Implementation of a session store using DynamoDB backed by the [AWS SDK for JavaScript v3](https://github.com/aws/aws-sdk-js-v3). + +[dynamodb-store-v3-url]: https://www.npmjs.com/package/dynamodb-store-v3 +[dynamodb-store-v3-image]: https://badgen.net/github/stars/FryDay/dynamodb-store-v3?label=%E2%98%85 + [![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store. [express-etcd-url]: https://www.npmjs.com/package/express-etcd @@ -717,7 +773,7 @@ a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-e [express-session-level-url]: https://www.npmjs.com/package/express-session-level [express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85 -[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerfull, flat file database. +[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerful, flat file database. [express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb [express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85 @@ -798,10 +854,10 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store [session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85 -[![★][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store. +[![★][@cyclic.sh/session-store-image] @cyclic.sh/session-store][@cyclic.sh/session-store-url] A DynamoDB-based session store for [Cyclic.sh](https://www.cyclic.sh/) apps. -[session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb -[session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85 +[@cyclic.sh/session-store-url]: https://www.npmjs.com/package/@cyclic.sh/session-store +[@cyclic.sh/session-store-image]: https://badgen.net/github/stars/cyclic-software/session-store?label=%E2%98%85 [![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store. @@ -818,7 +874,9 @@ based session store. Supports all backends supported by Fortune (MongoDB, Redis, [tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session [tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85 -## Example +## Examples + +### View counter A simple example using `express-session` to store page views for a user. @@ -856,6 +914,87 @@ app.get('/foo', function (req, res, next) { app.get('/bar', function (req, res, next) { res.send('you viewed this page ' + req.session.views['/bar'] + ' times') }) + +app.listen(3000) +``` + +### User login + +A simple example using `express-session` to keep a user log in session. + +```js +var escapeHtml = require('escape-html') +var express = require('express') +var session = require('express-session') + +var app = express() + +app.use(session({ + secret: 'keyboard cat', + resave: false, + saveUninitialized: true +})) + +// middleware to test if authenticated +function isAuthenticated (req, res, next) { + if (req.session.user) next() + else next('route') +} + +app.get('/', isAuthenticated, function (req, res) { + // this is only called when there is an authentication user due to isAuthenticated + res.send('hello, ' + escapeHtml(req.session.user) + '!' + + ' Logout') +}) + +app.get('/', function (req, res) { + res.send('
' + + 'Username:
' + + 'Password:
' + + '
') +}) + +app.post('/login', express.urlencoded({ extended: false }), function (req, res) { + // login logic to validate req.body.user and req.body.pass + // would be implemented here. for this example any combo works + + // regenerate the session, which is good practice to help + // guard against forms of session fixation + req.session.regenerate(function (err) { + if (err) next(err) + + // store user information in session, typically a user id + req.session.user = req.body.user + + // save the session before redirection to ensure page + // load does not happen before session is saved + req.session.save(function (err) { + if (err) return next(err) + res.redirect('/') + }) + }) +}) + +app.get('/logout', function (req, res, next) { + // logout logic + + // clear the user from the session object and save. + // this will ensure that re-using the old session id + // does not have a logged in user + req.session.user = null + req.session.save(function (err) { + if (err) next(err) + + // regenerate the session, which is good practice to help + // guard against forms of session fixation + req.session.regenerate(function (err) { + if (err) next(err) + res.redirect('/') + }) + }) +}) + +app.listen(3000) ``` ## Debugging @@ -881,6 +1020,8 @@ On Windows, use the corresponding command; [MIT](LICENSE) [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 +[rfc-cutler-httpbis-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 [ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci [ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master diff --git a/_includes/readmes/timeout.md b/_includes/readmes/timeout.md index 69da8a6d33..01586dd32c 100644 --- a/_includes/readmes/timeout.md +++ b/_includes/readmes/timeout.md @@ -4,7 +4,6 @@ [![NPM Downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] -[![Gratipay][gratipay-image]][gratipay-url] Times out a request in the Connect/Express application framework. @@ -164,5 +163,3 @@ app.listen(3000) [coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master [downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg [downloads-url]: https://npmjs.org/package/connect-timeout -[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg -[gratipay-url]: https://www.gratipay.com/dougwilson/ diff --git a/_includes/readmes/vhost.md b/_includes/readmes/vhost.md index f6289dc9c4..422e67f476 100644 --- a/_includes/readmes/vhost.md +++ b/_includes/readmes/vhost.md @@ -2,7 +2,7 @@ [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] -[![Build Status][travis-image]][travis-url] +[![Build Status][github-actions-ci-image]][github-actions-ci-url] [![Test Coverage][coveralls-image]][coveralls-url] ## Install @@ -13,8 +13,6 @@ $ npm install vhost ## API - - ```js var vhost = require('vhost') ``` @@ -157,9 +155,9 @@ app.listen(3000) [npm-image]: https://img.shields.io/npm/v/vhost.svg [npm-url]: https://npmjs.org/package/vhost -[travis-image]: https://img.shields.io/travis/expressjs/vhost/master.svg -[travis-url]: https://travis-ci.org/expressjs/vhost [coveralls-image]: https://img.shields.io/coveralls/expressjs/vhost/master.svg [coveralls-url]: https://coveralls.io/r/expressjs/vhost [downloads-image]: https://img.shields.io/npm/dm/vhost.svg [downloads-url]: https://npmjs.org/package/vhost +[github-actions-ci-image]: https://img.shields.io/github/actions/workflow/status/expressjs/vhost/ci.yml?branch=master&label=ci +[github-actions-ci-url]: https://github.com/expressjs/vhost/actions/workflows/ci.yml diff --git a/_includes/util-list.md b/_includes/util-list.md index e26620ddc4..8abc5d6a5d 100644 --- a/_includes/util-list.md +++ b/_includes/util-list.md @@ -32,11 +32,7 @@ - [csrf](/{{page.lang}}/resources/utils/csrf.html) - [finalhandler](/{{page.lang}}/resources/utils/finalhandler.html) - [parseurl](/{{page.lang}}/resources/utils/parseurl.html) -- [path-match](/{{page.lang}}/resources/utils/path-match.html) - [path-to-regexp](/{{page.lang}}/resources/utils/path-to-regexp.html) - [resolve-path](/{{page.lang}}/resources/utils/resolve-path.html) - [router](/{{page.lang}}/resources/utils/router.html) -- [routington](/{{page.lang}}/resources/utils/routington.html) - [send](/{{page.lang}}/resources/utils/send.html) -- [ssl-redirect](/{{page.lang}}/resources/utils/ssl-redirect.html) -- [templation](/{{page.lang}}/resources/utils/templation.html) diff --git a/_includes/warning.html b/_includes/warning.html deleted file mode 100644 index cd28c05371..0000000000 --- a/_includes/warning.html +++ /dev/null @@ -1,3 +0,0 @@ -
Warning: -{{include.content}} -
diff --git a/_layouts/3x-api.html b/_layouts/3x-api.html deleted file mode 100644 index d990ca5648..0000000000 --- a/_layouts/3x-api.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - {% include head.html %} - - - -
- - {% include header/header-{{ page.lang }}.html %} - - {% include api/en/3x/menu.md %} - -
- - {{ content }} - -
- - {% include footer/footer-{{ page.lang }}.html %} - - - - diff --git a/_layouts/404.html b/_layouts/404.html new file mode 100644 index 0000000000..84f18bfff3 --- /dev/null +++ b/_layouts/404.html @@ -0,0 +1,18 @@ + + + + {% include head.html %} + + {% if page.lang == 'en' %} + + {% else %} + + {% endif %} + {% include header.html %} +
+
+ {{ content }} +
+ {% include footer.html %} + + \ No newline at end of file diff --git a/_layouts/4x-api.html b/_layouts/4x-api.html deleted file mode 100644 index 788a944aea..0000000000 --- a/_layouts/4x-api.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - {% include head.html %} - - - -
- - {% include header/header-{{ page.lang }}.html %} - - {% include api/en/4x/menu.md %} - -
- - {{ content }} - -
- - {% include footer/footer-{{ page.lang }}.html %} - - - - diff --git a/_layouts/5x-api.html b/_layouts/5x-api.html deleted file mode 100644 index 8f8ff01342..0000000000 --- a/_layouts/5x-api.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - {% include head.html %} - - - -
- - {% include header/header-{{ page.lang }}.html %} - - {% include api/en/5x/menu.md %} - -
- - {{ content }} - -
- - {% include footer/footer-{{ page.lang }}.html %} - - - - diff --git a/_layouts/api.html b/_layouts/api.html new file mode 100644 index 0000000000..6e01f7f6cd --- /dev/null +++ b/_layouts/api.html @@ -0,0 +1,27 @@ + + + + {% include head.html %} + + + {% include header.html %} +
+ +
+ +
+ {{ content }} + {% include github-edit-btn.html %} +
+
+ + {% include footer.html %} + + + + diff --git a/_layouts/feed.xml b/_layouts/feed.xml new file mode 100644 index 0000000000..09a7aab788 --- /dev/null +++ b/_layouts/feed.xml @@ -0,0 +1,10 @@ + + + {{ page.title }} + + + {{ site.url }}{{ page.url }} + Copyright The Express Contributors + {{ site.time | date_to_xmlschema }} + {{ content }} + diff --git a/_layouts/home.html b/_layouts/home.html index 49e7d64263..8d5abafc95 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -1,9 +1,5 @@ - - + {% include head.html %} @@ -11,15 +7,23 @@ {% else %} -
- {% include i18n-notice.html %} -
{% endif %} - {{ content }} + {% include header.html %} - {% include footer/footer-{{ page.lang }}.html %} +
+ {% if page.lang != 'en' %} + + {% endif %} + +
+ {{ content }} +
+ + {% include footer.html %} diff --git a/_layouts/middleware.html b/_layouts/middleware.html index a64121de4a..07c9a7e66c 100644 --- a/_layouts/middleware.html +++ b/_layouts/middleware.html @@ -1,30 +1,39 @@ --- layout: page --- -
-
- {% if page.title contains 'middleware' %} - {% capture readme %}{% include mw-list.md %}{% endcapture %} - {% else %} - {% capture readme %}{% include util-list.md %}{% endcapture %} - {% endif %} - {{ readme | markdownify }} + + + +
{% if page.module == 'mw-home' %} {{content}} {% elsif page.module %} - + {% capture note-middleware %} + This page was generated from the {{page.module}} README. + {% endcapture %} + + {% include admonitions/note.html content=note-middleware %} {% capture included-readme %}{% include readmes/{{page.module}}.md %}{% endcapture %} - {{ included-readme | markdownify }} + + {{ included-readme | markdownify }} {% else %}

ERROR: No source specified for README {{page.module}}

{% endif %} -
-
+ + diff --git a/_layouts/page.html b/_layouts/page.html index a760250451..0a93f56c84 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -1,8 +1,4 @@ - {% if page.lang %} @@ -14,23 +10,30 @@ {% endif %} -
+ {% include header.html %} - {% include header/header-{{ page.lang }}.html %} +
-
- - {% if page.lang != 'en' %} -
+ {% if page.lang != 'en' %} + - {% endif %} -
-{{ content }}
-
+ {% endif %} + + {% if page.layout == 'middleware' %} +
+ {{ content }} +
+ {% else %} +
+
+ {{ content }} + {% include github-edit-btn.html %} +
+
+ {% endif %} - {% include footer/footer-{{ page.lang }}.html %} + {% include footer.html %} diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100644 index 0000000000..4f79504c5b --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,36 @@ + + + {% include head.html %} + + + {% include header.html %} +
+ +
+ +
+ {% if page.title %} +

{{page.title}}

+ {% endif %} + {% if page.sub_title %} +

{{page.sub_title}}

+ {% endif %} +
+ {% include blog/authors.html authors=page.authors %} +
{{page.date| date: "%d %b %Y" }}
+
+ {{ content }} + {% include github-edit-btn.html %} +
+
+ + {% include footer.html %} + + + + diff --git a/_posts/2024-07-16-welcome-post.md b/_posts/2024-07-16-welcome-post.md new file mode 100644 index 0000000000..52fc60a25a --- /dev/null +++ b/_posts/2024-07-16-welcome-post.md @@ -0,0 +1,27 @@ +--- +title: Welcome to The Express Blog! +description: Introducing the new Express blog — a primary platform for announcements, updates, and communication from the Express technical committee. +tags: site-admin +authors: + - name: Rand McKinney + github: crandmck + - name: Chris Del + github: chrisdel101 +--- + +Welcome to the new Express blog! The blog is meant to be a primary means of communication for the Express technical committee (TC). While we currently have other channels such as X, LinkedIn, and of course GitHub, there's no authoritative "soapbox" for announcements and general communication. + +Initially, the Express blog will be a venue: +- For periodic announcements of new releases, pre-releases, plans, and ongoing work on the project. +- For the Express TC to discuss issues of particular importance to the Express community. +- To highlight security issues or other urgent information. + +Eventually, we hope the blog will evolve into a more general communication hub for the entire Express community; for example to share examples, tips, and experiences with the Express ecosystem and other information that's not simply technical documentation or GitHub discussion. + +Initially, posts will be written by TC members (potentially collaborating others), mainly because we don't have bandwidth to review general posts from the broader community. Eventually, we would love to open up the blog for broader contributions, but for now the focus is on trying to release Express 5.0, and the reality of an open-source project is that everyone has finite time to contribute. + +Express TC member [Ulises Gascón](https://github.com/UlisesGascon) suggested a number of interesting topics for blog posts in [expressjs.com issue 1500](https://github.com/expressjs/expressjs.com/issues/1500), but there are undoubtedly many others. + +If you have an idea for a post, feel free to pitch the idea! You can add a comment to [expressjs.com issue 1500](https://github.com/expressjs/expressjs.com/issues/1500) or open a new issue, and then after appropriate discussion, open a PR. We've also written up simple [instructions to create a blog post](/en/blog/write-post.html). + +Happy blogging! diff --git a/_posts/2024-09-29-security-releases.md b/_posts/2024-09-29-security-releases.md new file mode 100644 index 0000000000..658fe345f5 --- /dev/null +++ b/_posts/2024-09-29-security-releases.md @@ -0,0 +1,137 @@ +--- +title: September 2024 Security Releases +description: Security releases for Express, body-parser, send, serve-static, and path-to-regexp have been published. We recommend that all users upgrade as soon as possible. +tags: security vulnerabilities +authors: + - name: Ulises Gascón + github: UlisesGascon +--- + +Recently, the Express team has been made aware of a number of security vulnerabilities in the Express project. We have released a number of patches to address these vulnerabilities. + +{% include admonitions/warning.html +content="We strongly recommend that you upgrade these modules to the recommended (or latest) version as soon as possible." +%} + +The following vulnerabilities have been addressed: + +- [High severity vulnerability CVE-2024-45590 in body-parser middleware](#high-severity-vulnerability-cve-2024-45590-in-body-parser-middleware) +- [High severity vulnerability CVE-2024-47178 in basic-auth-connect middleware](#high-severity-vulnerability-cve-2024-47178-in-basic-auth-connect-middleware) +- [Moderate severity vulnerability CVE-2024-43796 in Express core](#moderate-severity-vulnerability-cve-2024-43796-in-express-core) +- [Moderate severity vulnerability CVE-2024-43799 in send utility module](#moderate-severity-vulnerability-cve-2024-43799-in-send-utility-module) +- [Moderate severity vulnerability CVE-2024-43800 in serve-static middleware](#moderate-severity-vulnerability-cve-2024-43800-in-serve-static-middleware) +- [Moderate severity vulnerability CVE-2024-45296 in path-to-regexp utility module](#moderate-severity-vulnerability-cve-2024-45296-in-path-to-regexp-utility-module) + +## High severity vulnerability CVE-2024-45590 in body-parser middleware + +**[body-parser](https://www.npmjs.com/package/body-parser) version `<1.20.3` is vulnerable to denial of service when URL-encoding is enabled** + +A malicious actor using a specially-crafted payload could flood the server with a large number of requests, resulting in denial of service. + +**Affected versions**: `<1.20.3` + +**Patched versions**: `>=1.20.3` + +This vulnerability was discovered during the [OSTIF audit to Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team). + +For more details, see [GHSA-qwcr-r2fm-qrc7](https://github.com/expressjs/body-parser/security/advisories/GHSA-qwcr-r2fm-qrc7). + +## High severity vulnerability CVE-2024-47178 in basic-auth-connect middleware + +**[basic-auth-connect](https://www.npmjs.com/package/basic-auth-connect) uses a timing-unsafe equality comparison** + +basic-auth-connect `<1.1.0` uses a timing-unsafe equality comparison that can leak timing information + +**Affected versions** +- `<1.1.0` + +**Patched versions** +- `>=1.1.0` + +This vulnerability was discovered during the [OSTIF audit to Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express Securty triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team). + +More details area available in [GHSA-7p89-p6hx-q4fw](https://github.com/expressjs/basic-auth-connect/security/advisories/GHSA-7p89-p6hx-q4fw) + + + +## Moderate severity vulnerability CVE-2024-43796 in Express core + +The core **[express](https://www.npmjs.com/package/express) package is vulnerable to cross-site scripting (XSS) attack via `response.redirect()`**. + +In Express version <4.20.0, passing untrusted user input—even after sanitizing it—to `response.redirect()` may execute untrusted code. + +**Affected versions**: +- `<4.20.0` +- `>=5.0.0-alpha.1`, `<5.0.0` + +**Patched versions**: +- `>=4.20.0` +- `>=5.0.0` + +This vulnerability was discovered during the [OSTIF audit of Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team). + +For more details, see [GHSA-qw6h-vgh9-j6wx](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx). + + +## Moderate severity vulnerability CVE-2024-43799 in send utility module + +The **[send](https://www.npmjs.com/package/send) utility module is vulnerable to template injection that can lead to vulnerability to cross-site scripting (XSS) attack**. + +Passing untrusted user input—even after sanitizing it—to `SendStream.redirect()` can execute untrusted code. + +**Affected versions**: `< 0.19.0` + +**Patched versions**: `>=0.19.0` + +This vulnerability was discovered during the [OSTIF audit of Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team). + +For more details, see [GHSA-m6fv-jmcg-4jfg](https://github.com/pillarjs/send/security/advisories/GHSA-m6fv-jmcg-4jfg). + + +## Moderate severity vulnerability CVE-2024-43800 in serve-static middleware + +The **[serve-static](https://www.npmjs.com/package/serve-static) middleware module is vulnerable to template injection that can lead to vulnerability to cross-site scripting (XSS) attack**. + +Passing untrusted user input—even after sanitizing it—to `redirect()` can execute untrusted code. + +**Affected versions**: +- `< 1.16.0` +- `>=2.0.0`, `<2.1.0` + +**Patched versions**: +- `>=1.16.0` +- `>=2.1.0` + +This vulnerability was discovered during the [OSTIF audit of Express](https://github.com/expressjs/security-wg/issues/6) and was mitigated by [the Express security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team). + +For more details, see [GHSA-cm22-4g7w-348p](https://github.com/expressjs/serve-static/security/advisories/GHSA-cm22-4g7w-348p) + + +## Moderate severity vulnerability CVE-2024-45296 in path-to-regexp utility module + +The **[path-to-regexp](https://www.npmjs.com/package/path-to-regexp) utility module is vulnerable to regular expression denial of service (ReDoS) attack**. + +A bad regular expression is generated any time you have two parameters within a single segment, separated by something that is not a period (`.`). For example, `/:a-:b`. + +Using `/:a-:b` will produce the regular expression `/^\/([^\/]+?)-([^\/]+?)\/?$/`. This can be exploited by a path such as `/a${'-a'.repeat(8_000)}/a`. [OWASP](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) has a good example of why this occurs, but in essence, the `/a` at the end ensures this route would never match, but due to naive backtracking it will still attempt every combination of the `:a-:b` on the repeated 8,000 `-a`. + +Because JavaScript is single-threaded and regex matching runs on the main thread, poor performance will block the event loop and can lead to a DoS. In local benchmarks, exploiting the unsafe regex will result in performance that is over 1000x worse than the safe regex. In a more realistic environment, using Express v4 and ten concurrent connections results in an average latency of ~600ms vs 1ms. + +**Affected versions**: +- `>=4.0.0`, `<8.0.0` +- `>=0.2.0`, `<1.9.0` +- `<0.1.10` +- `>=2.0.0`, `<3.3.0` +- `>=4.0.0`, `<6.3.0` + +**Patched versions**: +- `>=8.0.0` +- `>=1.9.0` +- `>=0.1.10` +- `>=3.3.0` +- `>=6.3.0` + +Thanks to [Blake Embrey](https://github.com/blakeembrey) who reported and created the security patch. + +For more details, see [GHSA-9wv6-86v2-598j](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j) + diff --git a/_posts/2024-10-01-HeroDevs-partnership-announcement.md b/_posts/2024-10-01-HeroDevs-partnership-announcement.md new file mode 100644 index 0000000000..9ae9dac7a1 --- /dev/null +++ b/_posts/2024-10-01-HeroDevs-partnership-announcement.md @@ -0,0 +1,26 @@ +--- +title: Express Never Ending Support Launched by HeroDevs and Express.js +description: The Express.js team is pleased to announce a partnership with HeroDevs to launch Express Never-Ending Support (NES), providing long-term support for applications built with legacy Express. This collaboration ensures that developers relying on older versions of the framework will continue to receive critical security and compatibility updates, allowing them to maintain and scale their applications securely, even after the framework's official end-of-life. +tags: partnerships announcements +authors: + - name: Express Technical Committee + github: expressjs +--- + +The Express.js team is pleased to announce a partnership with HeroDevs to launch [Express Never-Ending Support (NES)](https://www.herodevs.com/support/express-nes), providing long-term support for applications built with legacy Express. This collaboration ensures that developers relying on older versions of the framework will continue to receive critical security and compatibility updates, allowing them to maintain and scale their applications securely, even after the framework's official end-of-life. + +Express.js is known for its minimalistic design and flexibility, offering developers a powerful yet lightweight framework for building web and mobile applications. Its extensive set of HTTP utility methods and middleware have made creating APIs both efficient and scalable—qualities that have made it a go-to choice for Node.js developers over the years. + +However, Express.js v3.x reached its end-of-life in July 2015, leaving many businesses and developers in need of support to keep their applications secure and compliant. + +> "We’re grateful to see HeroDevs stepping in to provide extended long-term support for Express +> +> Express NES ensures that the many businesses and developers who rely on Express can continue using it safely and securely, even years after its original end-of-life. This kind of ongoing commitment to the open-source ecosystem is crucial, and we’re excited to see the benefits it brings to the developer community.” — said a spokesperson for the Express Technical Committee. + +Express NES is designed as a drop-in replacement for legacy versions of Express.js, offering security patches, compatibility updates and compliance fixes. This solution ensures that developers can remain on legacy Express.js without becoming vulnerable to security risks and compliance issues. + +> “We’re thrilled to introduce Express NES as part of our continued mission to support the sustainability of key open-source tools +> +> Our partnership with OpenJS has enabled us to meet the needs of developers still relying on older versions of critical frameworks. Express NES ensures that they can continue building and maintaining their applications without the risk of security vulnerabilities or loss of compliance.” — Joe Eames, VP of Partnership at HeroDevs. + +For more information on Express NES and how to get started, visit [HeroDevs’ website](https://www.herodevs.com/support/express-nes). \ No newline at end of file diff --git a/_posts/2024-10-15-v5-release.md b/_posts/2024-10-15-v5-release.md new file mode 100644 index 0000000000..3e33233d7a --- /dev/null +++ b/_posts/2024-10-15-v5-release.md @@ -0,0 +1,131 @@ +--- +title: "Introducing Express v5: A New Era for the Node.js Framework" +tags: releases +authors: + - name: Wes Todd + github: wesleytodd + - name: Express Technical Committee + github: expressjs +description: Announcing the release of Express version 5 +--- + +Ten years ago (July 2014) the [Express v5 release pull request](https://github.com/expressjs/express/pull/2237) was opened, and now at long last it's been merged and published! + +We want to recognize the work of all our contributors, especially [Doug Wilson](https://github.com/dougwilson), who spent the last ten years ensuring Express was the most stable project around. Without his contributions and those of many others, this release could not have happened. + +Eight months ago we went public with a plan to move [Express forward](https://github.com/expressjs/discussions/issues/160). This plan included re-committing to the governance outlined years ago and adding more contributors to help kickstart progress. Many people may not realize that robust project governance is critical to the health of a large open-source project. We want to thank the [OpenJS Foundation Cross Project +Council](https://github.com/openjs-foundation/cross-project-council/) and its members for helping us put together this plan. + +## So what about v5? + +This release is designed to be boring! +That may sound odd, but we've intentionally kept it simple to unblock the ecosystem and enable more impactful changes in future releases. This is also about signaling to the Node.js ecosystem that Express is moving again. +The focus of this release is on dropping old Node.js version support, addressing security concerns, and simplifying maintenance. + +Before going into the changes in this release, let's address why it was released v5 on the `next` dist-tag. As part of reviving the project, we started a [Security working group](https://github.com/expressjs/security-wg) and [security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team) to address the growing needs around open source supply chain security. We undertook a security audit (more details to come on that) and uncovered some problems that needed to be addressed. Thus, in addition to the "normal" work done in public issues, we also did a lot of security work in private forks. +This security work required orchestration when releasing, to ensure the code and CVE reports went out together. You can find a summary of the most recent vulnerabilities patched in [our security release notes](https://expressjs.com/2024/09/29/security-releases.html). + +While we weren't able to simultaneously release v5, this blog post, the changelog, and documentation, we felt it was most important to have a secure and stable release. + +As soon as possible, we'll provide more details on our long-term support (LTS) plans, including when the release will move from `next` to `latest`. For now, if you are uncomfortable being on the bleeding edge (even if it is a rather dull edge) then you should wait to upgrade until the release is tagged `latest`. That said, we look forward to working with you to address any bugs you encounter as you upgrade. + +## Breaking changes + +The v5 release has the minimum possible number of breaking changes, listed here in order of impact to applications. + +- [Ending support for old Node.js versions](#ending-support-for-old-nodejs-versions) +- [Changes to path matching and regular expressions](#changes-to-path-matching-and-regular-expressions) +- [Promise support](#promise-support) +- [Body parser changes](#body-parser-changes) +- [Removing deprecated method signatures](#removing-deprecated-method-signatures) + +There are also a number of subtle changes: for details, see [Migrating to Express 5]({{site.url}}/{{page.lang}}/guide/migrating-5). + +### Ending support for old Node.js versions + +Goodbye Node.js 0.10, hello Node 18 and up! + +This release drops support for Node.js versions before v18. This is an important change because supporting old Node.js versions has been holding back many critical performance and maintainability changes. This change also enables more stable and maintainable continuous integration (CI), adopting new language and runtime features, and dropping dependencies that are no longer required. + +We recognize that this might cause difficulty for some enterprises with older or "parked" applications, and because of this we are working on a [partnership with HeroDevs](https://expressjs.com/2024/10/01/HeroDevs-partnership-announcement.html) to offer "never-ending support" that will include critical security patches even after v4 enters end-of-life (more on these plans soon). That said, we strongly suggest that you update to modern Node.js versions as soon as possible. + +### Changes to path matching and regular expressions + +The v5 releases updates to `path-to-regexp@8.x` from `path-to-regexp@0.x`, which incorporates many years of changes. If you were using any of the 5.0.0-beta releases, a last-minute update which greatly changed the path semantics to [remove the possibility of any ReDoS attacks](https://blakeembrey.com/posts/2024-09-web-redos/). For more detailed changes, [see the `path-to-regexp` readme](https://github.com/pillarjs/path-to-regexp?tab=readme-ov-file#express--4x). + +#### No more regex + +This release no longer supports "sub-expression" regular expressions, for example `/:foo(\\d+)`. +This is a commonly-used pattern, but we removed it for security reasons. Unfortunately, it's easy to write a regular expression that has exponential time behavior when parsing input: The dreaded regular expression denial of service (ReDoS) attack. It's very difficult to prevent this, but as a library that converts strings to regular expressions, we are on the hook for such security aspects. + +*How to migrate:* The best approach to prevent ReDoS attacks is to use a robust input validation library. [There are many on `npm`](https://www.npmjs.com/search?q=validate%20express) depending on your needs. TC member Wes Todd maintains [a middleware-based "code first" OpenAPI library](https://www.npmjs.com/package/@wesleytodd/openapi) for this kind of thing. + +#### Splats, optional, and captures oh my + +This release includes simplified patterns for common route patterns. With the removal of regular expression semantics comes other small but impactful changes to how you write your routes. + +1. `:name?` becomes `{:name}`. Usage of `{}` for optional parts of your route means you can now do things like `/base{/:optional}/:required` and what parts are actually optional is much more explicit. +2. `*` becomes `*name`. +3. New reserved characters: `(`, `)`, `[`, `]`, `?`, `+`, & `!`. These have been reserved to leave room for future improvements and to prevent mistakes when migrating where those characters mean specific things in previous versions. + +#### Name everything + +This release no longer supports ordered numerical parameters. + +In Express v4, you could get numerical parameters using regex capture groups (for example, `/user(s?)` => `req.params[0] === 's'`). Now all parameters must be named. Along with requiring a name, Express now supports all valid JavaScript identifiers or quoted (for example, `/:"this"`). + +### Promise support + +This one may be a bit contentious, but we "promise" we're moving in the right direction. We added support for returned *rejected* promises from errors raised in middleware. This *does not include* calling `next` from returned *resolved* promises. There are a lot of edge cases in old Express apps that have expectations of `Promise` behavior, and before we can run we need to walk. For most folks, this means you can now write middleware like the following: + +```javascript +app.use(async (req, res, next) => { + req.locals.user = await getUser(req); + next(); +}); +``` + +Notice that this example uses `async/await` and the `getUser` call may throw an error (if, for example, the user doesn't exist, the user database is down, and so on), but we still call `next` if it is successful. We don't need to catch the error in line anymore if we want to rely on error-handling middleware instead because the router will now catch the rejected promise and treat that as calling `next(err)`. + +NOTE: 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. + +### Body parser changes + +There are a number of `body-parser` changes: + +- Add option to customize the urlencoded body depth with a default value of 32 as mitigation for [CVE-2024-45590](https://nvd.nist.gov/vuln/detail/CVE-2024-45590) ([technical details](https://github.com/expressjs/body-parser/commit/b2695c4450f06ba3b0ccf48d872a229bb41c9bce)) +- Remove deprecated `bodyParser()` combination middleware +- `req.body` is no longer always initialized to `{}` +- `urlencoded` parser now defaults `extended` to false +- Added support for Brotli lossless data compression + +### Removing deprecated method signatures + +Express v5 removes a number of deprecated method signatures, many of which were carried over from v3. Below are the changes you need to make: + +- `res.redirect('back')` and `res.location('back')`: The magic string `'back'` is no longer supported. Use `req.get('Referrer') || '/'` explicitly instead. +- `res.send(status, body)` and `res.send(body, status)` signatures: Use `res.status(status).send(body)`. +- `res.send(status)` signature: Use `res.sendStatus(status)` for simple status responses, or `res.status(status).send()` for sending a status code with an optional body. +- `res.redirect(url, status)` signature: Use `res.redirect(status, url)`. +- `res.json(status, obj)` and `res.json(obj, status)` signatures: Use `res.status(status).json(obj)`. +- `res.jsonp(status, obj)` and `res.jsonp(obj, status)` signatures: Use `res.status(status).jsonp(obj)`. +- `app.param(fn)`: This method has been deprecated. Instead, access parameters directly via `req.params`, or use `req.body` or `req.query` as needed. +- `app.del('/', () => {})` method: Use `app.delete('/', () => {})` instead. +- `req.acceptsCharset`: Use `req.acceptsCharsets` (plural). +- `req.acceptsEncoding`: Use `req.acceptsEncodings` (plural). +- `req.acceptsLanguage`: Use `req.acceptsLanguages` (plural). +- `res.sendfile` method: Use `res.sendFile` instead. + +As a framework, we aim to ensure that the API is as consistent as possible. We've removed these deprecated signatures to make the API more predictable and easier to use. By streamlining each method to use a single, consistent signature, we simplify the developer experience and reduce confusion. + +## Migration and security guidance + +For developers looking to migrate from v4 to v5, there's a [detailed migration guide]({{site.url}}/{{page.lang}}/guide/migrating-5) to help you navigate through the changes and ensure a smooth upgrade process. + +Additionally, we’ve been working hard on a comprehensive [Threat Model](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) that helps illustrate our philosophy of a "Fast, unopinionated, minimalist web framework for Node.js." It provides critical insights into areas like user input validation and security practices that are essential for safe and secure usage of Express in your applications. + +## Our work is just starting + +We see the v5 release as a milestone toward an Express ecosystem that's a stable and reliable tool for companies, governments, educators, and hobby projects. It is our commitment as the new stewards of the Express project to move the ecosystem forward with this goal in mind. If you want to support this work, which we do on a volunteer basis, please consider supporting the project and its maintainers via [our sponsorship opportunities](https://opencollective.com/express). + +We have an [extensive working backlog](https://github.com/expressjs/discussions/issues/266) of tasks, PRs, and issues for Express and dependencies. Naturally, we expect developers will continue to report issues to add to this backlog and open PRs moving forward, and we'll continue to collaborate with the community to triage and resolve them. We look forward to continuing to improve Express and making it useful for its users across the world. diff --git a/_posts/2024-10-22-security-audit-milestone-achievement.md b/_posts/2024-10-22-security-audit-milestone-achievement.md new file mode 100644 index 0000000000..bf8bee0fca --- /dev/null +++ b/_posts/2024-10-22-security-audit-milestone-achievement.md @@ -0,0 +1,57 @@ +--- +title: "Express.js Security Audit: A Milestone Achievement" +tags: security audit releases +authors: + - name: Express Technical Committee + github: expressjs +description: Celebrating the successful completion of the Express.js security audit conducted by Ada Logics and facilitated by OSTIF. +--- + + +We are thrilled to announce the successful completion of a comprehensive security audit for Express.js, conducted by [Ada Logics](https://adalogics.com/) and facilitated by [OSTIF](https://ostif.org/). This extensive review of our framework and its core components marks a significant milestone in our commitment to ensuring the security and reliability of Express.js for our community. + +## A Collaborative Effort + +This audit was made possible through the collaboration between [the Express Security Working Group](https://github.com/expressjs/security-wg), Ada Logics, OSTIF, and the [OpenJS Foundation](https://openjsf.org/). Our focus was on thoroughly evaluating the Express.js codebase, including its dependencies and core libraries. The primary goal was to identify any potential security vulnerabilities and to strengthen the overall security posture of the framework. + +### Key Highlights of the Audit + +- **Audit Duration**: Conducted in April and May 2024. +- **Scope**: Core Express.js codebase and critical dependencies, such as `body-parser`, `basic-auth-connect`, `serve-static`, and more. +- **Findings**: A total of 5 security vulnerabilities were identified, all of which have been addressed and patched. +- **Severity**: Issues ranged from moderate to high severity, impacting components like `res.redirect` and `serve-static`. + +## A Closer Look at the Findings + +The audit identified several vulnerabilities, including potential Cross-Site Scripting (XSS) risks and a Denial of Service (DoS) vulnerability in the `body-parser` middleware. Here are the key CVEs reported: + +- **CVE-2024-43796**: XSS in `res.redirect`—fixed in versions >= 4.20.0 and >= 5.0.0. +- **CVE-2024-45590**: DoS in `body-parser`—patched in version >= 1.20.3. +- **CVE-2024-47178**: Timing vulnerability in `basic-auth-connect`—patched in version >= 1.1.0. +- **CVE-2024-43799**: XSS in the `send` utility module—patched in version >= 0.19.0. +- **CVE-2024-43800**: XSS in `serve-static`—fixed in versions >= 1.16.0 and >= 2.1.0. + +Each of these vulnerabilities was promptly addressed by our dedicated [security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team), ensuring that users remain protected against known threats. + +For full details on the audit results, you can access the [official audit report here](https://ostif.org/wp-content/uploads/2024/10/expressjs-2024-security-audit-report.pdf). + +## A Commitment to Transparency and Security + +At Express, security is a top priority, and we believe in the importance of transparency when it comes to vulnerabilities and their resolution. This audit not only highlights our proactive approach but also reinforces our ongoing commitment to building a secure web framework for all. + +We strongly recommend all users update to the latest versions of the affected packages to benefit from the recent security fixes. For more information on the patches and how to upgrade, please refer to our [September 2024 Security Release announcement](https://expressjs.com/2024/09/29/security-releases.html). + +## A Word of Thanks + +This audit would not have been possible without the efforts and expertise of many individuals and organizations. We want to extend our gratitude to: + +- The team at Ada Logics for their diligent review and insights. +- OSTIF for their coordination and support throughout the audit process. +- The OpenJS Foundation for sponsoring this important initiative. +- Our Express.js community, who continue to support and trust us with their projects. +- [Jordan Harband](https://github.com/ljharb) for his amazing support while we needed changes in [qs](https://www.npmjs.com/package/qs). + + +Together, we’ve made Express.js stronger, more resilient, and ready for the challenges ahead. We look forward to continuing to serve our community with a focus on excellence and security. + +Thank you for being a part of this journey with us! diff --git a/_posts/2025-01-09-rewind-2024-triumphs-and-2025-vision.md b/_posts/2025-01-09-rewind-2024-triumphs-and-2025-vision.md new file mode 100644 index 0000000000..cc2a734b02 --- /dev/null +++ b/_posts/2025-01-09-rewind-2024-triumphs-and-2025-vision.md @@ -0,0 +1,83 @@ +--- +title: "A New Chapter for Express.js: Triumphs of 2024 and an ambitious 2025" +tags: news rewind 2024 +authors: + - name: Express Technical Committee + github: expressjs +description: Explore the transformative journey of Express.js in 2024, marked by governance improvements, the long-awaited release of Express 5.0, and heightened security measures. Look into the ambitious plans for 2025, including performance optimizations, scoped packages, and a bold roadmap for sustained growth in the Node.js ecosystem. +--- + + +As we step into the new year, it’s almost impossible to ignore the unmistakable energy coursing through the Express.js community. The past twelve months have proven both foundational and forward-looking: an era of governance overhauls, technical triumphs, and security enhancements that not only shaped 2024 but also laid the groundwork for what promises to be a transformative 2025. +In this long-form recap and forecast, we’ll journey through the story of Express.js with its evolution, its hurdles, and the new heights it’s poised to reach. + +--- + +## A Transformative 2024 + +Few could have predicted just how pivotal 2024 would be for the Express.js project. From the revitalization of its governance structures to the unveiling of long-awaited features, it was a year that solidified the framework’s role as a mainstay in the Node.js ecosystem. + +### Governance and Community Milestones + +Central to the project’s growth was the [Express Forward Plan](https://github.com/expressjs/discussions/issues/160), devised to ensure strategic alignment and long-term sustainability. This year also saw the introduction of a new generation of Technical Committee (TC) members, each bringing fresh insights and energy to the community. Those members include [Blake Embrey](https://github.com/blakeembrey), [Chris de Almeida](https://github.com/ctcpip), [Jean Burellier](https://github.com/sheplu), [Jon Church](https://github.com/jonchurch), [Linus Unnebäck](https://github.com/LinusU), [Rand McKinney](https://github.com/crandmck), [Ulises Gascón](https://github.com/ulisesgascon), and [Wes Todd](https://github.com/wesleytodd). By defining a clear path and transparent processes, the community was able to collaborate on ambitious updates more cohesively than ever before. A revitalized release process further streamlined how new versions are planned and executed, eliminating much of the guesswork and inconsistent timing that had previously challenged contributors. + +In parallel, the [Security Working Group](https://github.com/expressjs/discussions/issues/165) took shape. Express.js, widely recognized for its importance to the broader Node.js landscape, formally introduced a [security triage team](https://github.com/expressjs/security-wg#security-triage-team) dedicated to proactively identifying and resolving vulnerabilities. This forward-thinking approach was bolstered by the adoption of a [Threat Model for Express.js](https://github.com/expressjs/express/pull/5526), underscoring the project’s commitment to robust, future-proof security. + +As if these achievements weren’t enough, Express.js proudly reached [Impact Project status](https://github.com/openjs-foundation/cross-project-council/pull/1404) under the OpenJS Foundation. This acknowledgment affirmed the significance of the framework to the JavaScript ecosystem and showcased the community’s tireless efforts in ensuring its enduring relevance. + +### Technical Advancements and the Release of Express 5.0 + +Naturally, 2024 will forever be remembered as the year when Express.js finally introduced its much-anticipated [Express 5.0](https://expressjs.com/2024/10/15/v5-release.html). After more than a decade of community discussions and behind-the-scenes experimentation, this release brought modern features and a future-oriented architecture to the framework, acting as a catalyst for the next chapter of Express.js development. + +But the story did not end there. Even before the release of Express 5.0 was fully established, the community had already begun charting the course for [Express 6.0](https://github.com/expressjs/discussions/issues/267), reflecting an unwavering commitment to innovation. Guiding critical decisions throughout 2024 were new [decision framework](https://github.com/expressjs/discussions/issues/285), which helped the Technical Committee tackle pressing matters such as [engine usage](https://github.com/expressjs/discussions/issues/286) and [dependency management](https://github.com/expressjs/discussions/issues/279). Collectively, these measures fostered transparency and agility, ensuring that Express.js continues to evolve in response to the community’s most urgent needs. + +### Maintenance, Tooling, and Collaboration + +Express.js also deepened its relationship with the Node.js community by re-integrating into the [Node.js CITGM project](https://github.com/expressjs/express/issues/5489). This move ensured broader ecosystem compatibility and provided developers with further validation that they can rely on Express.js as a dependable cornerstone of their Node.js applications. + +### A Heightened Security Posture + +Above all, 2024 will stand out for Express.js’s vigorous approach to security. In partnership with the [OpenJS Foundation](https://openjsf.org/) and [OSTIF](https://ostif.org/), the project undertook a comprehensive [security audit](https://expressjs.com/2024/10/22/security-audit-milestone-achievement.html) that yielded critical insights and propelled immediate improvements. The sense of proactive vigilance extended to the adoption of the [OSSF Scorecard](https://github.com/expressjs/discussions/issues/162), implemented at an organizational level to keep track of security metrics and maintain focus on ongoing enhancements. + +Throughout the year, maintainers rapidly responded to disclosed vulnerabilities such as [CVE-2024-43796](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-45590](https://github.com/expressjs/body-parser/security/advisories/GHSA-qwcr-r2fm-qrc7), and [CVE-2024-47178](https://github.com/expressjs/basic-auth-connect/security/advisories/GHSA-7p89-p6hx-q4fw). Each instance underscored the community’s readiness to defend the framework’s integrity and safeguard its user base. In a further demonstration of long-term commitment, Express.js teamed up with [HeroDevs](https://www.herodevs.com/) to establish [Never-Ending Support (NES)](https://openjsf.org/blog/at-the-openjs-foundation-were-excited-to-announce-), offering an extended maintenance plan that reaffirms Express.js as a reliable foundation for developers now and in the years to come. + + +--- + +## A Bold Vision for 2025 + +While 2024 laid a sturdy bedrock, the Express.js Technical Committee is not resting on its laurels. The newly revealed roadmap for 2025—bolstered by the [Sovereign Tech Fund (STF)](https://www.sovereign.tech/)—embodies a spirit of forward momentum. It promises notable strides in security, performance, and general developer experience, with each initiative building on the insights gained over the past year. + +### Automating npm Releases + +At the forefront of this plan is the automation of npm releases, an endeavor designed to free maintainers from manual steps and human error. By streamlining the publishing process, the project can achieve faster turnaround times for patches and new features, preserving the stability that developers have come to expect from Express.js. It’s an internal shift with massive external benefits: smoother upgrades, more frequent releases, and a deeper reservoir of confidence for users. + +### Introducing Scoped Packages + +Express.js will also explore a transition toward scoped packages. By clearly delineating which modules fall under the Express.js umbrella, the maintainers hope to reduce confusion and foster an environment more conducive to organized expansion. As new packages and features are proposed, scoping will make it simpler to track official tools and ensure that community contributions meet consistent quality standards. + +### Strengthening Security Reporting and Procedures + +Since security remains one of the project’s primary pillars, 2025 will see a significant push to refine how vulnerabilities are reported and managed. Building upon the success of the Security Working Group, the new process will introduce transparent guidelines for reporting potential issues and a consistent triage routine for mitigating them. Additional training for both the Security Triage group and the Technical Committee will further cultivate a shared culture of readiness. Moreover, Express.js is poised to integrate [OSSF Scorecard](https://github.com/expressjs/discussions/issues/162) even more deeply into daily operations, ensuring that both maintainers and users have real-time insights into the project’s health. + +### Performance Monitoring and Deep-Level Optimizations + +Performance is another focal point. By systematically monitoring the framework’s speed and responsiveness—along with that of its dependencies—the Express.js team aims to pinpoint bottlenecks more rapidly. Over time, insights from these monitoring efforts will drive deeper optimizations in the core Express.js code and its core libraries. These improvements, expected to come to fruition by mid-2026, promise a faster, more scalable framework that can handle the heaviest production workloads with ease. + +### Phasing Out Legacy Techniques and Enhancing Documentation + +A future of agility and resilience depends on eliminating outdated techniques that invite complexity and fragility. As a result, Express.js will begin phasing out monkey-patching and passthrough APIs that rely too heavily on Node.js internals. This modernization strategy not only reduces technical debt but also ensures that Express.js remains aligned with Node.js updates going forward. + +In tandem, the project will make a concerted effort to bolster its security documentation. Through updated guides and best practices, maintainers hope to demystify crucial topics like secure session handling, input validation, and access control. The goal is to arm developers—from novices to seasoned engineers—with the knowledge they need to protect their applications against an ever-evolving threat landscape. + +--- + +## The Road Ahead + +As Express.js steps into 2025, it does so with a powerful sense of purpose. The achievements of the past year—culminating in the official release of Express 5.0 and wide-reaching governance enhancements—serve as a sturdy foundation for what’s to come. Yet, the framework’s leadership knows there is always more to build, more to secure, and more to imagine. + +Through automated releases, scopes for packages, rigorous security protocols, performance monitoring, and an ongoing effort to modernize core APIs, Express.js is evolving in real-time. And it isn’t just about technology; it’s about forging a collaborative environment where contributors can rely on transparent processes, robust training, and a supportive governance structure. + +Whether you’re a seasoned maintainer, an occasional contributor, or a newcomer to this thriving ecosystem, your voice matters. Join the [Express.js GitHub Discussions](https://github.com/expressjs/discussions), attend open meetings, and stay tuned for updates on [Express.js blog](https://expressjs.com/) as we finalize timetables for these initiatives. Each advancement, no matter how technical, flows from a common aspiration: to sustain Express.js as a fast, safe, and influential framework for millions of developers worldwide. +Together, we’ll keep the spirit of 2024 alive—pushing boundaries, refining practices, and laying the path to a future where Express.js remains at the heart of modern web development. + diff --git a/_posts/2025-03-31-v5-1-latest-release.md b/_posts/2025-03-31-v5-1-latest-release.md new file mode 100644 index 0000000000..9a1ee879dc --- /dev/null +++ b/_posts/2025-03-31-v5-1-latest-release.md @@ -0,0 +1,170 @@ +--- +title: "Express@5.1.0: Now the Default on npm with LTS Timeline" +tags: news release +authors: + - name: Express Technical Committee + github: expressjs +description: Express 5.1.0 is now the default on npm, and we're introducing an official LTS schedule for the v4 and v5 release lines. +--- + +Express v5.0.0 was released on September 9th last year, but we didn't make it the `latest` release on npm. Many asked us +why and when it would be, and frankly we were not ready at the time to take that jump. If you have not followed the news +from the project this past year, we have been [hard at work reviving the project](https://expressjs.com/2025/01/09/rewind-2024-triumphs-and-2025-vision.html) +and when we pushed the initial v5 release there were many loose ends still hanging. So first lets quickly go over some +of those loose ends. + +### Documentation updates + +We had not updated the docs, provided migration guides, or even fully reviewed some of the stagnated v4/5 docs in a long +time. Since then we have had tons of great contributors help get things into better shape. As with any volunteer based +Open Source project, we love contributions to help us improve so as you upgrade please continue to open PRs to fix +anything we missed. + +You can find our [v5 docs](https://expressjs.com/en/5x/api.html) and our [migration guide](https://expressjs.com/en/guide/migrating-5.html) on the website. + +### Migration Support + +We know that migrating between versions can be challenging, especially when it involves significant changes in a widely used framework like Express. That's why we have worked on a solution to simplify part of the process and reduce the impact on developers. + +Thanks to the incredible efforts of [Sebastian](https://github.com/bjohansebas) and [Filip](https://github.com/kjugi), we have developed a new [codemod package](https://www.npmjs.com/package/@expressjs/codemod) specifically designed to facilitate the transition from Express v4 to v5, as well as future major versions. This package automates many of the necessary code changes, minimizing manual effort and making the upgrade as smooth and efficient as possible. + +However, we understand that not all changes can be automated. Some breaking changes, such as the [new Path Route Matching syntax](https://expressjs.com/en/guide/migrating-5.html#path-syntax), require manual modifications by developers. You can read more about all of the breaking changes which came with v5 in our [original release announcement](https://expressjs.com/2024/10/15/v5-release.html). + +For more details on the migration process and how to use the codemod package, check the [repository’s README](https://github.com/expressjs/codemod#readme) and the [migration guide](https://expressjs.com/en/guide/migrating-5.html). + +### Ecosystem compatibility + +The Express ecosystem is one of its strongest assets. It goes back to the early days of Node.js and is the backbone +that keeps express popular. When it goes [10 years without a major release](https://expressjs.com/2024/10/15/v5-release.html) +everything from middleware to documentation needed updates. We wanted to make sure folks had +some time to get all of that updated before we had everyone moving over. Particularly we care about our very large +beginner user base who may not know the blog post they are reading is not compatible with what they get from +`npm i express`. + +We recognize that some friction is inevitable during major upgrades, but thanks to work from ecosystem partners +like [Kamil](https://github.com/kamilmysliwiec) from NestJS [working to update `express` before we went `latest`](https://github.com/expressjs/express/issues/5944#issuecomment-2523074127) +we will hopefully be ahead of the curve. And as I said above, we always welcome help to make this transition easier for +those who follow after you, PRs are the best support you can give. + +### Long Term Support + +We had been discussing how to support v4 now that v5 was out, but we had not defined a clear guideline or expectation, +and we had (still don't have) end user docs on our plans here. While we still have progress to make here, we have a +[proposed LTS strategy ](https://github.com/expressjs/discussions/pull/352) which will be the basis for our forthcoming +docs. Input is very welcome on this so we can make sure it is clearly communicated and acceptable to the community. + +Additionally since then [we have announced a partnership with HeroDevs](https://expressjs.com/2024/10/01/HeroDevs-partnership-announcement.html) to help companies who are less capable of +updating. More information on how this will work when v4 EOL will come when we get closer to that time. + +--- + +## Support Phases and Going latest + +What does it mean to "go latest"? If you are unfamiliar with how npm `dist-tags` work, the `latest` tag is what users +will get when they run `npm install express`. This is important because it means it is the "default installed version" +and will trigger the transition of nearly 17 million weekly downloads from our current latest v4.21.2 to v5. As we start +this transition we want users, companies, and other organizations to know exactly what it means for support. To help +with this we have developed an LTS strategy which defines our 3 support phases and set's target dates for when v4 will +enter EOL. + +Express major versions will go through three supported phases: + + - `CURRENT`: A new major version is designated as `CURRENT` upon release. It is available but not the `latest` version + on npm for a minimum of 3 months. + - `ACTIVE`: After the minimum 3 month period and the TC agrees it is stable and secure, the `ACTIVE` version is + tagged `latest` on npm for a minimum of 12 months. + - `MAINTENANCE`: When a new major version becomes `ACTIVE`, the previous major version enters `MAINTENANCE` for 12 months. + +### CURRENT + +- New majors will go through a short period of hardening to ensure stability, security, and ecosystem libraries/resources + compatibility. +- We will strive to ensure no breaking changes are included, but reserve the right to make security or high priority + fixes of breaking nature within this period. +- `CURRENT` lines will receive all types of active work including: bug fixes, security patches, new features, and + deprecation notices. +- Users are recommended to use `CURRENT` lines and to upgrade as quickly as their risk profile allows + +### ACTIVE + +- `ACTIVE` lines will receive all types of active work including: bug fixes, security patches, new features, and + deprecation notices. +- For users, `ACTIVE` lines are considered the most stable and well supported version at any given time. + +### MAINTENANCE + +- `MAINTENANCE` lines will only receive security patches or high priority bug fixes. +- Users are highly encouraged to upgrade to a `CURRENT` or `ACTIVE` release. + +### Proposed Schedule + +For the existing release lines, we will set the following phase dates: + +
+ +| Major | CURRENT | ACTIVE | MAINTENANCE | EOL | +| ----- | ------- | ------ | ----------- | --- | +| 4.x | | | 2025-04-01 | *no sooner than 2026-10-01 | +| 5.x | 2024-09-11 | 2025-03-31 | **no sooner than 2026-04-01 | **no sooner than 2027-04-01 | +| 6.x | ***no sooner than 2026-01-01 | | | | + +
+ +As you can see, this means that v5.1.0 being tagged `latest` indicates that we moved from `CURRENT` to `ACTIVE` which +starts the clock on EOL for v4 by moving it to `MAINTENANCE`. We recognize that v4 is a special case having been the +only major version for most of the history of Node.js itself. Because of this, we want to remain flexible and also +provide a bit longer support. We want to do what is best for the ecosystem, so consider these goals not commitments. + +\*: v4 is a special case, and we may extend MAINTENENCE support +\*\*: v5 MAINTENENCE and EOL dates are determined by when v6 is released, these dates reflect the earliest dates if we +were to ship v6 on 2025-10-01 +\*\*\* : v6 work has not officially started yet, this is simply the earliest date we can ship based on our proposed policy + +--- + +## Finally, what changed in v5.1.0 + +This release primarily focused on tech debt from supporting so many old Node.js versions and other things that stagnated but were not landed before v5.0.0 went out. + +### Express 5.1.0 Main Changes + +* Add support for `Uint8Array` in `res.send()` +* Transitioned all remaining dependencies to use `^` ranges instead of locked versions +* Add package.json funding field to highlight our OpenCollective +* Added support for ETag option in `res.sendFile()` +* Added support for adding multiple links with the same rel with `res.links()` +* Performance: Use loop for acceptParams +* See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### Dependencies updated + +We also invested time to prepare several releases in the packages that Express depend on. Most of this packages are used by other libraries and framework as individual libraries. + +* [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + * Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + * Remove `unpipe` & `destroy` +* [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + * Restore `debug`. Now with the `router` scope instead of `express`. + * Remove legacy node.js support checks for `setImmediate` + * Deprecate non-native promise support + * Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +* [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + * Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + * Remove `unpipe` +* [serve-static@2.2.0](https://github.com/expressjs/serve-static/releases/tag/v2.2.0) + +--- + +## Thanks and What's Next + +Thanks so much to everyone involved in Express over the past year, the work all our contributors have put in is +incredible, and we couldn't do it without them. If you are not able to become a contributor yourself, please consider +asking your companies to support the project financially on [OpenCollective](https://opencollective.com/express). + +As we look ahead, we’re excited to keep building momentum. If you haven’t read it yet, our [Rewind 2024 + 2025 Vision blog post](https://expressjs.com/2025/01/09/rewind-2024-triumphs-and-2025-vision.html) lays out where we’ve been and where we're headed. This includes performances scoped packages, better automation, security hardening, and more. + +One major initiative is our new [Performance Working Group](https://github.com/expressjs/discussions/pull/306), focused on identifying and fixing long-standing bottlenecks in Express. We're grateful to be kicking this off with support from the [Sovereign Tech Fund (STF)](https://openjsf.org/sovereign-tech-fund/), who are helping us invest in long-term sustainability and performance of core infrastructure. Additionally, we will be working to [improve our Typescript DX](https://github.com/expressjs/discussions/issues/192) and taking next steps to [improve the website](https://github.com/expressjs/expressjs.com/issues/1787). + +And yes, v6 discussions are already starting to heat up. Keep an eye out for updates, and as always, see you in the issues! + +Big thanks to [@wesleytodd](https://github.com/wesleytodd), [@blakeembrey](https://github.com/blakeembrey), [@bjohansebas](https://github.com/bjohansebas), [@UlisesGascon](https://github.com/UlisesGascon), [@Phillip9587](https://github.com/Phillip9587), [@carpasse](https://github.com/carpasse), [@jonchurch](https://github.com/jonchurch), [@ctcpip](https://github.com/ctcpip), [@inigomarquinez](https://github.com/inigomarquinez), [@carlosstenzel](https://github.com/carlosstenzel), [@crandmck](https://github.com/crandmck), [@chrisdel101](https://github.com/chrisdel101), [@dpopp07](https://github.com/dpopp07), [@Ayoub-Mabrouk](https://github.com/Ayoub-Mabrouk), [@jonkoops](https://github.com/jonkoops), [@IamLizu](https://github.com/IamLizu), [@marco-ippolito](https://github.com/marco-ippolito), [@ipreencekmr](https://github.com/ipreencekmr), [@ShubhamOulkar](https://github.com/ShubhamOulkar), [@raksbisht](https://github.com/raksbisht), [@jeffreybaird](https://github.com/jeffreybaird), [@dougwilson](https://github.com/dougwilson), [@mertcanaltin](https://github.com/mertcanaltin), [@GeorgeShvab](https://github.com/GeorgeShvab), [@RobinTail](https://github.com/RobinTail), [@EvanHahn](https://github.com/EvanHahn), [@rhodgkins](https://github.com/rhodgkins), [@cengizcmataraci](https://github.com/cengizcmataraci), [@Shantanugupta43](https://github.com/Shantanugupta43), [@italojs](https://github.com/italojs), [@ljharb](https://github.com/ljharb), [@MaoShizhong](https://github.com/MaoShizhong), [@aroyan](https://github.com/aroyan), [@Binilkks](https://github.com/Binilkks), [@danielgindi](https://github.com/danielgindi), [@papandreou](https://github.com/papandreou), [@jsoref](https://github.com/jsoref), [@bigbigDreamer](https://github.com/bigbigDreamer), [@broofa](https://github.com/broofa), [@CommanderRoot](https://github.com/CommanderRoot), [@andvea](https://github.com/andvea), [@juanarbol](https://github.com/juanarbol), [@agungjati](https://github.com/agungjati), [@alexandercerutti](https://github.com/alexandercerutti), [@pr4j3sh](https://github.com/pr4j3sh), [@hamirmahal](https://github.com/hamirmahal), [@slagiewka](https://github.com/slagiewka), [@Abdel-Monaam-Aouini](https://github.com/Abdel-Monaam-Aouini), [@sazk07](https://github.com/sazk07), [@bhavya3024](https://github.com/bhavya3024), [@joshbuker](https://github.com/joshbuker), [@almic](https://github.com/almic), [@FDrag0n](https://github.com/FDrag0n), [@Dmitry-Kondar](https://github.com/Dmitry-Kondar), [@attrid](https://github.com/attrid), [@kristof-low](https://github.com/kristof-low), [@gireeshpunathil](https://github.com/gireeshpunathil), [@UzairJ99](https://github.com/UzairJ99), [@choi2021](https://github.com/choi2021), [@hayden36](https://github.com/hayden36), [@joharkhan99](https://github.com/joharkhan99), [@peterh-capella](https://github.com/peterh-capella), [@johnburnett](https://github.com/johnburnett), [@nicolasgandrade](https://github.com/nicolasgandrade), [@axhuwastaken](https://github.com/axhuwastaken), [@abhijeetpandit7](https://github.com/abhijeetpandit7), [@peterdanwan](https://github.com/peterdanwan), [@rehmansheikh222](https://github.com/rehmansheikh222), [@corydalis10](https://github.com/corydalis10), [@mgsantos177](https://github.com/mgsantos177), [@wilyJ80](https://github.com/wilyJ80), [@LuiGeeDev](https://github.com/LuiGeeDev), [@juliogarciape](https://github.com/juliogarciape), [@aelmardhi](https://github.com/aelmardhi), [@Ahmed1monm](https://github.com/Ahmed1monm), [@erensarac](https://github.com/erensarac), [@tomasz13nocon](https://github.com/tomasz13nocon), [@tianbuyung](https://github.com/tianbuyung), [@GreyTearsDev](https://github.com/GreyTearsDev), [@aastha-cse](https://github.com/aastha-cse), [@krzysdz](https://github.com/krzysdz), [@Miguelrom](https://github.com/Miguelrom), [@bnoordhuis](https://github.com/bnoordhuis), [@MehfoozurRehman](https://github.com/MehfoozurRehman), [@EasonLin0716](https://github.com/EasonLin0716), [@grjan7](https://github.com/grjan7), [@mishrasur7](https://github.com/mishrasur7), [@gregfenton](https://github.com/gregfenton), [@zareefhasan](https://github.com/zareefhasan), [@Tejas150](https://github.com/Tejas150), [@jpricardo](https://github.com/jpricardo), [@nikeee](https://github.com/nikeee), [@dotnetCarpenter](https://github.com/dotnetCarpenter), [@engpetermwangi](https://github.com/engpetermwangi), [@msimerson](https://github.com/msimerson), [@fetsorn](https://github.com/fetsorn), [@manoharreddyporeddy](https://github.com/manoharreddyporeddy), [@lancatlin](https://github.com/lancatlin), [@mifi](https://github.com/mifi), [@meowingwhitey](https://github.com/meowingwhitey), [@sheplu](https://github.com/sheplu), [@krsriq](https://github.com/krsriq), [@ravibisht](https://github.com/ravibisht), [@wojtekmaj](https://github.com/wojtekmaj), [@aqeelat](https://github.com/aqeelat), [@melikhov-dev](https://github.com/melikhov-dev), [@alexstrat](https://github.com/alexstrat), [@isnifer](https://github.com/isnifer), [@TorstenDittmann](https://github.com/TorstenDittmann), [@Uzlopak](https://github.com/Uzlopak), [@gurgunday](https://github.com/gurgunday), [@kurtextrem](https://github.com/kurtextrem), [@hdtmccallie](https://github.com/hdtmccallie), [@proudparrot2](https://github.com/proudparrot2), [@bewinsnw](https://github.com/bewinsnw), [@jonboulle](https://github.com/jonboulle), [@alexander-akait](https://github.com/alexander-akait), [@alxndrsn](https://github.com/alxndrsn), [@DimitriPapadopoulos](https://github.com/DimitriPapadopoulos), [@greggman](https://github.com/greggman), [@jkbach](https://github.com/jkbach), [@julien-c](https://github.com/julien-c), [@risu729](https://github.com/risu729), [@JohnSimumatik](https://github.com/JohnSimumatik), [@dhouck](https://github.com/dhouck), [@pedro-php](https://github.com/pedro-php), [@aminerol](https://github.com/aminerol), [@robertsky](https://github.com/robertsky), [@ipetrouchtchak-fi](https://github.com/ipetrouchtchak-fi), [@tinhochu](https://github.com/tinhochu), [@Lord-Kamina](https://github.com/Lord-Kamina), [@joshkel](https://github.com/joshkel), [@raiandexter0607](https://github.com/raiandexter0607), [@NateEag](https://github.com/NateEag), [@rmhaiderali](https://github.com/rmhaiderali), [@ljeda](https://github.com/ljeda) diff --git a/_posts/2025-05-16-express-cleanup-legacy-packages.md b/_posts/2025-05-16-express-cleanup-legacy-packages.md new file mode 100644 index 0000000000..eee24e3bb1 --- /dev/null +++ b/_posts/2025-05-16-express-cleanup-legacy-packages.md @@ -0,0 +1,48 @@ +--- +title: "Spring Cleaning in Express.js: Deprecations and the Path Ahead" +tags: news +authors: + - name: Express Technical Committee + github: expressjs +description: As part of a broader effort to modernize and streamline Express.js, we’ve deprecated several outdated packages including csurf, connect-multiparty, and path-match. Learn why we made these changes and what it means for the future of the framework. +--- + +As Express.js continues to power web applications across the world, it's important that we maintain a clean, reliable, and modern codebase. In that spirit, we've done a bit of spring cleaning. + +Over the past few weeks, we've evaluated legacy packages within the Express.js ecosystem — some of which have become outdated, unmaintained, or misaligned with modern best practices. As a result, we’ve officially deprecated several of them. + +## 🚨 Packages Deprecated + +Here are the key packages we’ve deprecated: + +- [`csurf`](https://www.npmjs.com/package/csurf): A CSRF middleware that’s long been difficult to maintain and is better handled today through frameworks or custom implementations that align with your architecture. +- [`connect-multiparty`](https://www.npmjs.com/package/connect-multiparty): A multipart form-data parser that relies on deprecated libraries and hasn’t aged well. +- [`path-match`](https://www.npmjs.com/package/path-match): A route-matching utility that has been superseded by more modern and maintained alternatives. + +Each of these packages was originally created to solve real problems—but time has moved on, and the ecosystem has evolved. + +## 🤔 Why This Matters + +Maintaining deprecated or inactive dependencies introduces technical debt and security risk. By formally deprecating these packages, we: + +- Encourage developers to adopt better-maintained and more secure solutions. +- Reduce confusion around which tools are actively supported by Express. +- Focus our efforts on modernizing the core and surrounding ecosystem. + +## 🗂️ What You Should Do + +If your application depends on any of these packages, now is a great time to look for alternatives. For instance: + +- Consider finding a modern CSRF protection strategy on [npm](https://www.npmjs.com/search?q=csurf) that aligns with your specific needs. +- Use up-to-date multipart parsers like [`multer`](https://www.npmjs.com/package/multer). +- Replace path-match logic with standard [`path-to-regexp`](https://www.npmjs.com/package/path-to-regexp). + +## 📘 What's Next + +We're not stopping here. This cleanup is part of a broader effort to streamline Express.js, prepare for the future, and clarify what is and isn’t officially supported. + +👉 A full discussion of these changes can be found [expressjs/discussions#134](https://github.com/expressjs/discussions/issues/134). + +📢 Stay tuned—we'll continue to post updates and insights as we modernize the Express ecosystem. + +💚Thanks to the community for your continued trust and support. diff --git a/_posts/2025-05-19-security-releases.md b/_posts/2025-05-19-security-releases.md new file mode 100644 index 0000000000..bfab761a5b --- /dev/null +++ b/_posts/2025-05-19-security-releases.md @@ -0,0 +1,51 @@ +--- +title: May 2025 Security Releases +description: Security release for Multer has been published. We recommend that all users upgrade as soon as possible. +tags: security vulnerabilities +authors: + - name: Ulises Gascón + github: UlisesGascon +--- + +The Express team has released a new major version of [Multer](https://www.npmjs.com/package/multer) addressing two high-severity security vulnerabilities. This update improves the reliability and security of handling file uploads in Express applications. + +{% include admonitions/warning.html +content="We strongly recommend that you upgrade to Multer v2.0.0 or later as soon as possible." +%} + +The following vulnerabilities have been addressed: + +- [High severity vulnerability CVE-2025-47935 in Multer middleware](#high-severity-vulnerability-cve-2025-47935-in-multer-middleware) +- [High severity vulnerability CVE-2025-47944 in Multer middleware](#high-severity-vulnerability-cve-2025-47944-in-multer-middleware) + +## High severity vulnerability CVE-2025-47935 in Multer middleware + +**[Multer](https://www.npmjs.com/package/multer) versions `<2.0.0` are vulnerable to denial of service due to a memory leak caused by improper stream handling.** + +When the HTTP request stream emits an error, the internal `busboy` stream is not closed, violating Node.js stream safety guidance. + +This leads to unclosed streams accumulating over time, consuming memory and file descriptors. Under sustained or repeated failure conditions, this can result in denial of service, requiring manual server restarts to recover. All users of Multer handling file uploads are potentially impacted. + +**Affected versions**: `<2.0.0` +**Patched version**: `>=2.0.0` + +For more details, see [GHSA-44fp-w29j-9vj5](https://github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5). + +## High severity vulnerability CVE-2025-47944 in Multer middleware + +**[Multer](https://www.npmjs.com/package/multer) versions `>=1.4.4-lts.1` and `<2.0.0` are vulnerable to a denial of service via a malformed multipart request.** + +A specially crafted request can cause an unhandled exception inside Multer, resulting in a crash of the server process. + +**Affected versions**: `>=1.4.4-lts.1` and `<2.0.0` +**Patched version**: `>=2.0.0` + +For more details, see [GHSA-4pg4-qvpc-4q3h](https://github.com/expressjs/multer/security/advisories/GHSA-4pg4-qvpc-4q3h). + +--- + +**Multer v2.0.0** also introduces a breaking change: + +- The minimum supported Node.js version is now **10.16.0**. + +We recommend upgrading to the latest version of Multer immediately to secure your applications. diff --git a/_posts/2025-06-05-vulnerability-reporting-process-overhaul.md b/_posts/2025-06-05-vulnerability-reporting-process-overhaul.md new file mode 100644 index 0000000000..28f654a598 --- /dev/null +++ b/_posts/2025-06-05-vulnerability-reporting-process-overhaul.md @@ -0,0 +1,86 @@ +--- +title: How Express.js Rebuilt Its Vulnerability Reporting Process +description: Express.js has overhauled its vulnerability reporting workflow with a unified process, consolidated documentation, and GitHub Security Advisories enabled across all repositories. +tags: security vulnerabilities process governance +authors: + - name: Ulises Gascón + github: UlisesGascon +--- + + +The Express.js project has completed a major milestone in its ongoing commitment to security: the implementation of a formal, centralized vulnerability reporting and response process. + +Until recently, security reports were typically handled over email — an approach that worked in the early days but no longer scaled with the growing complexity and user base of Express. This informal system introduced potential delays, inconsistent handling, and increased the risk of issues being missed or misunderstood. + +Thanks to support from the [Sovereign Tech Fund](https://sovereign.tech), the Express.js Security Working Group has now completed a ground-up overhaul of how we manage vulnerability reports. + + +## 🛠️ Key Improvements + +### Formalized Vulnerability Reporting Workflow + +A comprehensive runbook and process flow have been created to guide maintainers through each step of triaging, confirming, and addressing reported security issues. +- [View the documentation](https://github.com/expressjs/security-wg/blob/main/docs/handle_security_reports.md) +- [Security Report Handling Flowchart](https://github.com/expressjs/security-wg/blob/main/docs/handle_security_reports.md#security-report-handling-flowchart) + +### Unified Security Policy Across Repositories + +All Express.js repositories now share a single, unified `SECURITY.md` policy to ensure consistency and remove confusion for reporters and maintainers alike. + +- [View the unified Security Policy](https://github.com/expressjs/.github/blob/master/SECURITY.md) + +### GitHub Security Advisories Enabled + +Security Advisories are now enabled across all Express.js repositories, allowing for secure, private vulnerability reporting through GitHub’s built-in system. + +- [How to report a security bug using GitHub Security Advisory](https://github.com/expressjs/.github/blob/master/SECURITY.md#reporting-security-bugs-via-github-security-advisory-preferred) + +### Clear Maintainer Responsibilities + +Expectations around ownership and response timelines have been clarified and published to reduce ambiguity and improve responsiveness. + +> A [Security triage team member](https://github.com/expressjs/security-wg#security-triage-team) or [the repo captain](https://github.com/expressjs/express/blob/master/Contributing.md#active-projects-and-captains) will acknowledge your report as soon as possible. +> +> After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. +> +> _[Security Policy](https://github.com/expressjs/.github/blob/master/SECURITY.md)_ + + +## 🛡️ Express is Now Covered Under the OpenJS Foundation CNA + +As of June 2025, the [OpenJS Foundation](https://openjsf.org/) is officially a [CVE Numbering Authority (CNA)](https://openjsf.org/blog/openjs-foundation-cna), empowered to assign CVE identifiers for security vulnerabilities across its hosted projects—including Express. + +What this means for the community: + +- Security vulnerabilities in Express can now receive official CVE IDs through OpenJS, improving transparency and coordination. +- The foundation provides support and tooling to streamline the vulnerability disclosure process, particularly for maintainers and security researchers. +- For critical issues, the CNA helps ensure that disclosures follow best practices and are recorded in global vulnerability databases. + + +Please refer to [Express’s Security Policy](https://github.com/expressjs/express/security/policy) for the correct disclosure process. If needed, escalation routes through the OpenJS CNA are now available. + +This advancement is part of a broader effort to strengthen the security of JavaScript’s open-source ecosystem—especially for widely used, community-driven projects like Express. + +Learn more: +- [OpenJS Foundation is now a CNA – Official Blog Post](https://openjsf.org/blog/openjs-foundation-cna) +- [Socket.dev Coverage: OpenJS Foundation Becomes a CNA](https://socket.dev/blog/openjs-foundation-is-now-a-cna) + +## 👀 Coming Soon: Bug Bounty Program in the Works + +To further enhance the security of our ecosystem and encourage responsible vulnerability disclosure, the Express.js team has begun exploring participation in a community-focused bug bounty initiative—powered by the [Sovereign Tech Resilience program](https://www.sovereign.tech/programs/bug-resilience). + +This collaboration aims to: + +- Reward contributors for discovering and responsibly reporting security issues +- Improve our ability to address vulnerabilities quickly and transparently +- Strengthen long-term resilience for users and maintainers alike + +Join the conversation and share your thoughts in [expressjs/discussions#345 – Bug Bounty Proposal](https://github.com/expressjs/discussions/issues/345) + +## Why This Matters + +Security is a shared responsibility — and one that must evolve as the project grows. With these updates, Express.js has laid the foundation for a more reliable, scalable, and transparent vulnerability response system. + +We’re grateful to the [OpenJS Foundation](https://openjsf.org/) and the [Sovereign Tech Fund](https://www.sovereign.tech/) for their support and are excited to share this progress with the broader community. diff --git a/_posts/2025-07-18-security-releases.md b/_posts/2025-07-18-security-releases.md new file mode 100644 index 0000000000..e6e4d86033 --- /dev/null +++ b/_posts/2025-07-18-security-releases.md @@ -0,0 +1,29 @@ +--- +title: June 2025 Security Releases +description: Security update for Multer released. All users are encouraged to upgrade. +tags: security vulnerabilities +authors: + - name: Ulises Gascón + github: UlisesGascon +--- + +The Express team has released a new patch version of [Multer](https://www.npmjs.com/package/multer), addressing a high-severity vulnerability that could lead to a Denial of Service (DoS) attack. + +{% include admonitions/warning.html +content="We strongly recommend that all users upgrade to Multer v2.0.1 or later immediately." +%} + +This release addresses the following vulnerability: + +### High severity vulnerability CVE-2025-48997 in Multer middleware + +**[Multer](https://www.npmjs.com/package/multer) versions `>=1.4.4-lts.1` and `<2.0.1` are vulnerable to a Denial of Service (DoS) attack.** + +An attacker can trigger this vulnerability by sending an upload request with an empty string as the field name. This malformed request causes an unhandled exception, leading to a crash of the server process. + +**Affected versions**: `>=1.4.4-lts.1` and `<2.0.1` +**Patched version**: `2.0.1` + +For more details, see [GHSA-g5hg-p3ph-g8qg](https://github.com/expressjs/multer/security/advisories/GHSA-g5hg-p3ph-g8qg). + + diff --git a/_posts/2025-07-31-security-releases.md b/_posts/2025-07-31-security-releases.md new file mode 100644 index 0000000000..6582649097 --- /dev/null +++ b/_posts/2025-07-31-security-releases.md @@ -0,0 +1,46 @@ +--- +title: July 2025 Security Releases +description: Security releases for Multer and On-headers has been published. We recommend that all users upgrade as soon as possible. +tags: security vulnerabilities +authors: + - name: Ulises Gascón + github: UlisesGascon +--- + +The Express team has released a new patch version of [Multer](https://www.npmjs.com/package/multer) addressing a high-severity security vulnerability, and a new minor version of [on-headers](https://www.npmjs.com/package/on-headers) addressing a low-severity security vulnerability. + + +{% include admonitions/warning.html +content="We recommend upgrading to the latest version of Multer and On-headers immediately to secure your applications." +%} + +The following vulnerabilities have been addressed: + +- [High severity vulnerability CVE-2025-7338 in Multer middleware](#high-severity-vulnerability-cve-2025-7338-in-multer-middleware) +- [Low severity vulnerability CVE-2025-7339 in On-header middleware](#low-severity-vulnerability-cve-2025-7339-in-on-header-middleware) + +## High severity vulnerability CVE-2025-7338 in Multer middleware + +**[Multer](https://www.npmjs.com/package/multer) versions `>=1.4.4-lts.1` and `<2.0.2` are vulnerable to denial of service via unhandled exception from malformed request.** + +This request causes an unhandled exception, leading to a crash of the process. + +**Affected versions**: `>=1.4.4-lts.1, <2.0.2` +**Patched version**: `2.0.2` + +For more details, see [GHSA-fjgf-rc76-4x9p](https://github.com/expressjs/multer/security/advisories/GHSA-fjgf-rc76-4x9p). + +## Low severity vulnerability CVE-2025-7339 in On-header middleware + +**[On-headers](https://www.npmjs.com/package/on-headers) versions `<1.1.0` is vulnerable to http response header manipulation** + +A bug in on-headers versions `<1.1.0` may result in response headers being inadvertently modified when an array is passed to `response.writeHead()` + +**Affected versions**: `<1.1.0` +**Patched version**: `1.1.0` + +For more details, see [GHSA-76c9-3jph-rj3q](https://github.com/jshttp/on-headers/security/advisories/GHSA-76c9-3jph-rj3q). + +--- + +We recommend upgrading to the latest version of Multer and On-headers immediately to secure your applications. diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 0000000000..9d7061f080 --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,13 @@ +files: + - source: /en/**/*.* + ignore: + - /en/blog/**/*.* + translation: /%two_letters_code%/**/%original_file_name% + - source: /_data/en/**/*.* + translation: /_data/%two_letters_code%/**/%original_file_name% + - source: /index.md + translation: /%two_letters_code%/index.md +preserve_hierarchy: true +project_id_env: CROWDIN_PROJECT_ID +base_url: 'https://express.api.crowdin.com' +api_token_env: CROWDIN_PERSONAL_TOKEN diff --git a/css/de.css b/css/de.css deleted file mode 100644 index fd7af0c21a..0000000000 --- a/css/de.css +++ /dev/null @@ -1,18 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 135px;} - -#callout5 {top: 150px;} - -#callout6 {top: 160px;} - diff --git a/css/dropit.css b/css/dropit.css deleted file mode 100644 index 2cde3fc6a4..0000000000 --- a/css/dropit.css +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Dropit v1.1.0 - * http://dev7studios.com/dropit - * - * Copyright 2012, Dev7studios - * Free to use and abuse under the MIT license. - * http://www.opensource.org/licenses/mit-license.php - */ - -/* These styles assume you are using ul and li */ -.dropit { - list-style: none; - padding: 0; - margin: 0; -} - -.dropit .dropit-trigger { - position: relative; - margin-bottom: 6px; -} - -.dropit .dropit-submenu { - position: absolute; - top: 100%; - left: 0; /* dropdown left or right */ - z-index: 1000; - display: none; - min-width: 215px; - list-style: none; - padding: 0; - margin: 0; -} - -.dropit .dropit-open .dropit-submenu { display: block; } diff --git a/css/en.css b/css/en.css deleted file mode 100644 index 1b920cecdf..0000000000 --- a/css/en.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 170px;} - -#callout6 {top: 195px;} diff --git a/css/es.css b/css/es.css deleted file mode 100644 index dfc300a126..0000000000 --- a/css/es.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 140px;} - -#callout5 {top: 150px;} - -#callout6 {top: 160px;} diff --git a/css/font-awesome.min.css b/css/font-awesome.min.css deleted file mode 100644 index ec53d4d6d5..0000000000 --- a/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/css/fr.css b/css/fr.css deleted file mode 100644 index 5538ccfee6..0000000000 --- a/css/fr.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 165px;} - -#callout6 {top: 185px;} diff --git a/css/it.css b/css/it.css deleted file mode 100644 index 750fecaef0..0000000000 --- a/css/it.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 150px;} - -#callout6 {top: 160px;} diff --git a/css/ja.css b/css/ja.css deleted file mode 100644 index b4b5f80056..0000000000 --- a/css/ja.css +++ /dev/null @@ -1,19 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -.callout {position: relative;} - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 165px;} - -#callout6 {top: 185px;} diff --git a/css/ko.css b/css/ko.css deleted file mode 100644 index b4b5f80056..0000000000 --- a/css/ko.css +++ /dev/null @@ -1,19 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -.callout {position: relative;} - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 165px;} - -#callout6 {top: 185px;} diff --git a/css/langs/de.css b/css/langs/de.css new file mode 100644 index 0000000000..df6795b5a2 --- /dev/null +++ b/css/langs/de.css @@ -0,0 +1,14 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 135px;} + +#callout5 {top: 150px;} + +#callout6 {top: 160px;} + diff --git a/css/langs/en.css b/css/langs/en.css new file mode 100644 index 0000000000..8f2e5ac2dd --- /dev/null +++ b/css/langs/en.css @@ -0,0 +1,13 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 145px;} + +#callout5 {top: 170px;} + +#callout6 {top: 195px;} diff --git a/css/langs/es.css b/css/langs/es.css new file mode 100644 index 0000000000..dd8a578f8e --- /dev/null +++ b/css/langs/es.css @@ -0,0 +1,13 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 140px;} + +#callout5 {top: 150px;} + +#callout6 {top: 160px;} diff --git a/css/langs/fr.css b/css/langs/fr.css new file mode 100644 index 0000000000..1c9938c3f7 --- /dev/null +++ b/css/langs/fr.css @@ -0,0 +1,13 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 145px;} + +#callout5 {top: 165px;} + +#callout6 {top: 185px;} diff --git a/css/langs/it.css b/css/langs/it.css new file mode 100644 index 0000000000..6b0bbc10b8 --- /dev/null +++ b/css/langs/it.css @@ -0,0 +1,13 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 145px;} + +#callout5 {top: 150px;} + +#callout6 {top: 160px;} diff --git a/css/langs/ja.css b/css/langs/ja.css new file mode 100644 index 0000000000..1c162162cd --- /dev/null +++ b/css/langs/ja.css @@ -0,0 +1,15 @@ +/* For image callouts in writing-middleware.md */ + +.callout {position: relative;} + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 145px;} + +#callout5 {top: 165px;} + +#callout6 {top: 185px;} diff --git a/css/langs/ko.css b/css/langs/ko.css new file mode 100644 index 0000000000..d4c2b2ac66 --- /dev/null +++ b/css/langs/ko.css @@ -0,0 +1,19 @@ +/* For image callouts in writing-middleware.md */ + +@import url('../../fonts/ko/pretendard.css'); + +html, body {font-family: Pretendard, Arial, sans-serif;} + +.callout {position: relative;} + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 145px;} + +#callout5 {top: 165px;} + +#callout6 {top: 185px;} diff --git a/css/langs/pt-br.css b/css/langs/pt-br.css new file mode 100644 index 0000000000..dd8a578f8e --- /dev/null +++ b/css/langs/pt-br.css @@ -0,0 +1,13 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 140px;} + +#callout5 {top: 150px;} + +#callout6 {top: 160px;} diff --git a/css/langs/zh-cn.css b/css/langs/zh-cn.css new file mode 100644 index 0000000000..8f2e5ac2dd --- /dev/null +++ b/css/langs/zh-cn.css @@ -0,0 +1,13 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 145px;} + +#callout5 {top: 170px;} + +#callout6 {top: 195px;} diff --git a/css/langs/zh-tw.css b/css/langs/zh-tw.css new file mode 100644 index 0000000000..8f2e5ac2dd --- /dev/null +++ b/css/langs/zh-tw.css @@ -0,0 +1,13 @@ +/* For image callouts in writing-middleware.md */ + +#callout1 {top: 40px; } + +#callout2 {top: 60px;} + +#callout3 {top: 75px;} + +#callout4 {top: 145px;} + +#callout5 {top: 170px;} + +#callout6 {top: 195px;} diff --git a/css/nodeinteractive.css b/css/nodeinteractive.css deleted file mode 100644 index 423d13c824..0000000000 --- a/css/nodeinteractive.css +++ /dev/null @@ -1,91 +0,0 @@ -#nodeinteractive { - max-width: 1024px; - margin-left: 5%; - margin-right: 5%; - border-radius: 7px; - background-color: rgba(231, 238, 219, 0.6); - display: inline-flex; - overflow: hidden; -} - -#nodeinteractive h3 { - font-weight: 100; - font-size: 1.3em; - line-height: 1.2em; -} - -#nodeinteractive p { - font-weight: normal; - font-size: 0.95em; - margin: 3px; -} - -#nodeinteractive-details { - padding: 15px 20px; -} - -#nodeinteractive-details ul { - padding: 0; -} - -#nodeinteractive-details li { - display: inline-flex; - list-style: none; - background: rgba(255, 255, 255, 0.9); - margin-bottom: 5px; - padding: 3px; -} - -#nodeinteractive-details img { - display: block; - width: 70px; - height: 70px; - margin-right: 5px; -} - -#nodeinteractive-details li p { - padding-right: 3px; -} - -#nodeinteractive-details h4 { - padding: 0; - margin: 3px 2px; -} - -#nodeinteractive-img { - width: 300px; -} - -.nodeinteractive-div { - height: 250px; -} - -/* responsive */ - -@media all and (max-width: 899px) { - - #nodeinteractive { - margin-top: 20px; - } - - #nodeinteractive-img { - display: none; - } - -} - -@media all and (max-width: 700px) { - #nodeinteractive img { - display: none; - } - - #nodeinteractive-details { - height: auto; - } - - #nodeinteractive-details h4 { - font-weight: bold; - margin-bottom: 7px; - } - -} diff --git a/css/prism.css b/css/prism.css deleted file mode 100644 index a941010f8a..0000000000 --- a/css/prism.css +++ /dev/null @@ -1,142 +0,0 @@ -/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash */ -/** - * prism.js default theme for JavaScript, CSS and HTML - * Based on dabblet (http://dabblet.com) - * @author Lea Verou - */ - -code[class*="language-"], -pre[class*="language-"] { - color: black; - text-shadow: 0 1px white; - font-family: Consolas, Monaco, 'Andale Mono', monospace; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - line-height: 1.5; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, -code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { - text-shadow: none; - background: #b3d4fc; -} - -pre[class*="language-"]::selection, pre[class*="language-"] ::selection, -code[class*="language-"]::selection, code[class*="language-"] ::selection { - text-shadow: none; - background: #b3d4fc; -} - -@media print { - code[class*="language-"], - pre[class*="language-"] { - text-shadow: none; - } -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #F7F7F7; -} - -pre.language-sh { - background-color: #272727; -} - -code.language-sh { - color: #4fbf40; - text-shadow: none; -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; -} - -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: slategray; -} - -.token.punctuation { - color: #999; -} - -.namespace { - opacity: .7; -} - -.token.property, -.token.tag, -.token.boolean, -.token.number, -.token.constant, -.token.symbol, -.token.deleted { - color: #905; -} - -.token.selector, -.token.attr-name, -.token.string, -.token.char, -.token.builtin, -.token.inserted { - color: #690; -} - -.token.operator, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string { - color: #a67f59; - background: hsla(0, 0%, 100%, .5); -} - -.token.atrule, -.token.attr-value, -.token.keyword { - color: #07a; -} - -.token.function { - color: #DD4A68; -} - -.token.regex, -.token.important, -.token.variable { - color: #e90; -} - -.token.important { - font-weight: bold; -} - -.token.entity { - cursor: help; -} - diff --git a/css/pt-br.css b/css/pt-br.css deleted file mode 100644 index dfc300a126..0000000000 --- a/css/pt-br.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 140px;} - -#callout5 {top: 150px;} - -#callout6 {top: 160px;} diff --git a/css/ru.css b/css/ru.css deleted file mode 100644 index 23c6a2ab7f..0000000000 --- a/css/ru.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 160px;} - -#callout6 {top: 180px;} diff --git a/css/sintax.css b/css/sintax.css new file mode 100644 index 0000000000..e33e6fbee9 --- /dev/null +++ b/css/sintax.css @@ -0,0 +1,141 @@ +:root { + --orange: #953800; + --green: #116329; + --blue-light: #0550ae; + --blue-darker: #0a3069; + --pupple: #8250df; + --gray: #6e7781; + --red: #cf222e; + --red-darker: #82071e; +} + +.dark-mode:root { + --orange: #ffa657; + --green: #79c0ff; + --blue-light: #a5d6ff; + --blue-darker: #1f6feb; + --pupple: #d2a8ff; + --gray: #8b949e; + --red: #ff7b72; + --red-darker: #8e1519; +} + +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } + +.highlight, .highlight .w { + color: #24292f; + background-color: var(--code-bg); +} + +.highlight .k, .highlight .kd, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kt, .highlight .kv { + color: var(--red); +} + +.highlight .gr { + color: #f6f8fa; +} + +.highlight .gd { + color: var(--red-darker); + background-color: #ffebe9; +} + +.highlight .nb, +.highlight .nc, +.highlight .no, +.highlight .nn { + color: var(--orange); +} + +.highlight .sr,.highlight .na, .highlight .nt, .highlight .gi { + color: var(--green); +} + +.highlight .gi { + background-color: #dafbe1; +} + +.highlight .ges { + font-weight: bold; + font-style: italic; +} + +.highlight .l, +.highlight .ld, +.highlight .m, +.highlight .mb, +.highlight .mf, +.highlight .mh, +.highlight .mi, +.highlight .il, +.highlight .mo, +.highlight .mx, +.highlight .kc, +.highlight .sb, +.highlight .bp, +.highlight .ne, +.highlight .nl, +.highlight .py +.highlight .nv, +.highlight .vc, +.highlight .vg, +.highlight .vi, +.highlight .vm, +.highlight .s1, +.highlight .o, +.highlight .ow, +.highlight .gh, +.highlight .gu, +.highlight .s2, +.highlight .dl { + color: var(--blue-light); +} + +.highlight .gh { + font-weight: bold; +} +.highlight .gu { + font-weight: bold; +} +.highlight .s, .highlight .sa, .highlight .sc, .highlight .sd, .highlight .se, .highlight .sh, .highlight .sx, .highlight .ss { + color: var(--blue-darker); +} +.highlight .nd, .highlight .nf, .highlight .fm { + color: var(--pupple); +} + +.highlight .err { + color: #f6f8fa; + background-color: #82071e; +} +.highlight .c, +.highlight .gl +.highlight .ch, +.highlight .cd, +.highlight .cm, +.highlight .cp, +.highlight .cpf, +.highlight .cs, +.highlight .gt { + color: var(--gray); +} + +.highlight .c1 { + color: var(--green); +} + +.highlight .ni, +.highlight .ge, +.highlight .si, +.highlight .gs { + color: #24292f; +} + +.highlight .ge { + font-style: italic; +} + +.highlight .gs { + font-weight: bold; +} diff --git a/css/sk.css b/css/sk.css deleted file mode 100644 index 6959da6c31..0000000000 --- a/css/sk.css +++ /dev/null @@ -1,21 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 170px;} - -#callout6 {top: 195px;} - -.dropit .dropit-submenu { - min-width: 250px; -} \ No newline at end of file diff --git a/css/style.css b/css/style.css index 3736a9ca6f..1226c519a8 100644 --- a/css/style.css +++ b/css/style.css @@ -1,23 +1,50 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ - -/* general */ - * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; - -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-tap-highlight-color: transparent; + scroll-behavior: smooth; +} + +/* handle header offset with scroll-margin */ +h1, h2, h3, h4, h5, h6, +[id] { + scroll-margin-top: 60px; +} + +/* Respect user motion preferences for access */ +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } } body { font: 400 14px/1.6 "Open Sans", sans-serif; - background: url(/images/bg.jpg); + background: var(--bg); margin: 0; padding: 0; - color: #555; + color: var(--fg); + display: grid; + grid-template-areas: + 'header' + 'i18n' + 'content' + 'footer' +} + +header { + grid-area: header; +} + +.content { + grid-area: content; +} + +footer { + grid-area: footer; +} + +body.no-scroll{ + overflow: hidden; } h1 { @@ -25,23 +52,28 @@ h1 { line-height: 36px; } -#intro h3, #api-doc h1 { +#intro h2, #api-doc h1 { font-weight: normal; } h1, h2, h3 { margin: 5px 0; - color: #353535; + color: var(--card-fg); -webkit-font-smoothing: antialiased; + } .content h1 { margin-bottom: 20px; } +.content table a.ignore-underline { + text-decoration: none; +} + p em { font-weight: bold; - color: #353535; + color: var(--card-fg); } p { @@ -50,25 +82,29 @@ p { } strong, th { - color: #353535; + color: var(--card-fg); } #overlay { position: fixed; left: 0; top: 0; - background: #fff; - opacity: 0.8; + opacity: 0.6; width: 100%; height: 100%; display: none; z-index: 1; + background-color: var(--bg); +} + +main.home { + max-width: 75rem; + margin: 40px auto 2%; + padding-inline: 5%; + grid-area: content; } #home-content { - margin: 183px 0 2% 5%; - max-width: 900px; - padding-right: 9%; display: flex; } @@ -90,13 +126,16 @@ strong, th { } #announcements { - margin: 3px 5% 32px; - max-width: 1005px; + margin-top: 40px; padding: 0 16px; - background: #fdfae6; - border: 1px solid #ebdbb7; + background: var(--notice-bg); + border: 1px solid var(--notice-accent); border-radius: 3px; font-size: 0.9em; + & a { + color: var(--notice-accent); + text-decoration: underline; + } } #announcements ul { @@ -117,40 +156,48 @@ strong, th { margin-right: 12px; } -#announcements p:first-child { +.announcement-title { font-weight: bold; - padding-left: 20px; - background-image: url(/images/announcement-icon.png); - background-position: 0 3px; - background-repeat: no-repeat; - background-size: 14px 14px; margin-bottom: 11px; + display: flex; + align-items: center; + column-gap: 8px } -#install-command { +.install-command { font-family: Consolas, Monaco, "Andale Mono", monospace; - padding: 5px 10px; - background: #fff; - border: 1px solid #eee; + padding: 10px; + border: 1px solid var(--border); border-radius: 3px; max-width: 375px; + background-color: inherit; + + code { + background-color: inherit; + } } .content { - margin: 153px 3% 7%; - max-width: 1090px; - padding-left: 225px; + display: flex; + flex-direction: row-reverse; + padding-inline-start: 1rem; + margin-block-start: 3.5rem; } -span.block-section { - display: block; +.content main { + max-width: 900px; + margin-inline: auto; +} + +.flex-row-content { + flex-direction: row; } -li code { - color: #333; +span.block-section { + display: block; } -#intro h3 { +#intro h2 { font-size: 25px; margin-bottom: 10px; } @@ -164,7 +211,7 @@ li code { padding-bottom: 5px; font-weight: bold; font-size: 24px; - color: #888; + color: var(--menu-grey) } #api-doc h2 { @@ -188,54 +235,54 @@ li code { #api-doc h5 { font-size: 14px; font-weight: bold; - color: #666; + color: var(--menu-grey) } -/* links */ +/* scroll */ -a { - color: #259dff; - text-decoration: none; +*::-webkit-scrollbar { + background-color: opacity(var(--box-fg), 0.145); + width: 16px; } -.h2:target { - display: block; - padding-top: 40px; +*::-webkit-scrollbar-thumb { + border-radius: 8px; + border: 4px solid transparent; + background-clip: content-box; + background-color: var(--menu-grey); } -#api-doc *:target, #page-doc *:target { - margin-top: -120px; - padding-top: 120px; - z-index: -1; +*::-webkit-scrollbar-thumb:hover { + background-color: var(--hover-bg); } -.outlined-img { - border: 1px solid #eaeaea; - width: 90%; +*::-webkit-scrollbar-thumb:active { + background-color: var(--menu-grey); } -.current { - background: #e0f5ff; +/* links */ + +a { + color: var(--link); + text-decoration: underline; } -/* logo */ +.h2:target { + display: block; + padding-top: 40px; +} -#logo { - position: fixed; - top: 2px; - margin: 0; - padding: 10px 25px; - width: auto; - border-left: none; - z-index: 1; + +/* logo */ +.logo-container a { + text-decoration: none; + display: flex; + justify-content: center; + align-items : center; } -#logo .express { - margin-top: 63px; - display: block; - font: 25px "Helvetica Neue", "Open Sans", sans-serif; - font-weight: 100; - color: #444; +.express-logo { + fill : var(--card-fg); } #description .express { @@ -245,15 +292,16 @@ a { margin-bottom: .25em; } -#description .express a { - color: #353535; +#description .express > span { + color: var(--card-fg); } -#express-version { +#description .express a#express-version { font-size: 0.2em; margin-left: 0.5em; - color: #259dff !important; + color: var(--link); font-weight: 400; + text-decoration: underline; } #description { @@ -265,109 +313,201 @@ a { position: relative; top: -5px; font: 100 4.1em "Helvetica Neue", "Open Sans", sans-serif; - color: #aeaeae; + color: var(--menu-grey); line-height: .87; + margin: unset } -#description em { - font-style: normal; - font-weight: 100; - font-size: 9px; - color: #999; - margin-left: 5px; +#description .description a { + text-decoration-thickness: 1px; + text-underline-offset: 3px; } -#conference { - display: inline; - float: right; - margin-left: 10px; +.header-right { + display: flex; + align-items: center; + gap: 20px; } -#intro { - margin-left: 5%; +header { + background: var(--card-bg); + height: 57px; + display: flex; + align-items: center; + justify-content: space-between; + padding-inline: 1rem; + border-bottom: 1px solid var(--hover-fg); } -#doc-langs { - text-align: center; - font-size: 12px; +.scroll header { + box-shadow: 0 0 4px var(--card-bg); } -#doc-langs p { - margin: 3px 0; +/* code */ + +code { + background-color: var(--code-bg); + color: var(--card-fg); + margin-block: -.125rem; + font-size: 13px; + padding: .125rem .375rem; + border-radius: 6px; } -header { - position: fixed; - top: 0; - left: 0; - background: #eee; - width: 100%; - height: 120px; - z-index: 100; - border-bottom: 1px solid #ddd; +pre { + padding: 16px; + border-radius: 3px; + border: 1px solid var(--border); + background-color: var(--code-bg); +/* keyboard focus offset improve visibility */ + &:focus { + border-color: var(--hover-border); + } } -.scroll header { - border-bottom: 1px solid #ddd; - box-shadow: 0 0 4px #eee; +pre code { + padding: 0; } -/* companies using express */ +pre:has(code) { + position: relative; -img.memberlogo { - vertical-align: middle; - width: 240px; - padding: 10px 20px; + &:is(:hover, :focus) { + button { + display: flex; + } + } + /* focus copy btn by keyboard */ + &:focus-within button { + display: flex; + } } -/* code */ +pre:has(code) button { + position: absolute; + top: 5px; + right: 5px; + border: none; + z-index: 100; + display: none; + cursor: pointer; + background-color: inherit; + padding: 2px; + border-radius: 5px; + + &::after { + content: ""; + background-color: var(--card-fg); + mask-image: url("/images/copy-btn.svg"); + mask-size: 1.5rem; + mask-repeat: no-repeat; + width: 1.5rem; + height: 1.5rem; + } -p code, td code { - color: #333; + &:is(:hover, :focus) { + background-color: var(--hover-bg); + outline: 2px solid var(--hover-border); + } + + @media all and (max-width: 370px) { + padding: 1px; + + &::after { + mask-size: 1rem; + width: 1rem; + height: 1rem; + } + } } -pre { - color: #555; - font-size: 14px; - line-height: 1.4; - padding: 16px; - border-radius: 3px; - overflow: auto; - border: 1px solid #ddd; +pre:has(code) button.copied { + outline-color: var(--supported-fg); + + &::after { + background-color: var(--supported-fg); + } + + &::before { + font-size: 0.85rem; + position: absolute; + left: -58px; + content: "copied!"; + + width: fit-content; + height: fit-content; + padding: 4px; + border-radius: 2px; + color: var(--card-fg); + background-color: var(--card-bg); + outline: 1px solid var(--supported-fg); + } + + @media all and (max-width: 400px) { + &::before { + left: -50px; + font-size: 0.7rem; + padding: 3px; + } + } } -pre code { - overflow: scroll; - word-break: break-all; +pre:has(code) button.failed { + outline-color: var(--eol-fg); + + &::after { + background-color: var(--eol-fg); + } + + &::before { + font-size: 0.85rem; + position: absolute; + left: -58px; + content: "failed!"; + + width: fit-content; + height: fit-content; + padding: 4px; + border-radius: 2px; + color: var(--card-fg); + background-color: var(--card-bg); + outline: 1px solid var(--eol-fg); + } + + @media all and (max-width: 400px) { + &::before { + left: -50px; + font-size: 0.7rem; + padding: 3px; + } + } } -/* top button */ +/* scroll to top button */ .scroll #top { - opacity: .2; + opacity: .5; + display: initial +} + +.scroll #top:hover { + opacity: 1; } #top { line-height: 0; - background: black; - -webkit-border-radius: 2px; + border-radius: 2px; position: fixed; bottom: 15px; right: 15px; padding: 8px; text-decoration: none; - color: white; opacity: 0; - -webkit-transition: opacity 300ms; -} - -#top:hover { - opacity: 1; -} - -#top img { - width: 8px; - height: 5px; + transition: opacity 300ms; + border: 1px solid var(--border); + background-color: var(--card-bg); + color: var(--card-fg); + display: none; } /* clearfix */ @@ -396,124 +536,73 @@ html[xmlns] .clearfix { /* boxes */ #boxes { + display: grid; + grid-template-columns: repeat(4, 1fr); + row-gap: 20px; + column-gap: 50px; margin-top: 30px; } -#boxes h3 { +#boxes h2 { line-height: 1.25em; -} - -#boxes div { - width: 215px; - margin-right: 50px; - float: left; - list-style: none; - padding-bottom: 20px; -} - -#boxes div:last-child { - margin-right: 0; -} - - -#boxes h3 { + color: var(--card-fg); background: none; margin-top: 0; padding-top: 0; } -#boxes section p { - width: 100%; - margin-top: 5px; - margin-bottom: 20px; -} - -/* applications page */ - -#applications .section { - display: block; - margin-bottom: 50px; -} - -.application h2 { - margin: 0; -} - -.application { - padding: 80px 0; - height: 600px; - position: relative; -} - -.application p { - float: left; - width: 30%; -} - -.application img { - float: right; -} - -.application .link { - position: absolute; - bottom: 15px; - left: 15px; +#boxes h2 a { + text-decoration: none; + color: var(--card-fg); } -.application .link a { - margin-left: 4px; +#boxes div { + list-style: none; } +/* tables specific */ -/* doc specific */ - -.doctable, section table { - margin: 1em 1em 1em 0; - border: 1px solid #c6c6c6; +table { + margin: 1em 0; + border: 1px solid var(--border); border-collapse: collapse; - empty-cells: show; width: 100%; + @media screen and (max-width:600px) { + font-size: smaller; + } } -.doctable td, .doctable th, section table td, section table th { +table td, table th { padding: 7px; line-height: 120%; vertical-align: top; - border: 1px solid #c6c6c6; + border: 1px solid var(--border); } -.doctable tr th, section table tr th { - background-color: #dadada; +table tr th { + background: var(--card-bg); font-size: 110%; } -.doctable td p:first-child { +table td p:first-child { margin-top: 0; } -.doctable td p, li p { +table td p, li p { width: 100% !important; } -.doctable ul { +table ul { margin: 20px 0 } /* doc boxes */ .doc-box { - font-size: 12px; - line-height: 14px; - padding: 10px; - border-radius: 3px; - margin: 20px 3% 20px 3%; -} - -.doc-box pre { - font-size: 12px; - line-height: 14px; - padding: 0; - margin: 0; + padding: 16px; + color: var(--box-fg); + border-radius: 0 6px 6px 0; + margin-bottom: 1rem; } .doc-box p { @@ -524,53 +613,62 @@ html[xmlns] .clearfix { margin: 0; } -.doc-box pre[class*="language-"] { - background: none repeat scroll 0 0 #fff; +.doc-title { + display: flex; + align-items: center; + gap: 3px; + font-weight: 600; } -/* English pages use backticks for code blocks */ -.en-doc .page pre[class*="language-"] { - padding-top: 10px !important; +/* i18n box */ +.doc-notice { + padding-block: 1rem; + padding-inline: 2.5rem; + color: var(--box-fg); + border-radius: 0 6px 6px 0; + background: var(--notice-bg); + border-left: 3px solid var(--notice-accent); + margin-inline: auto; + margin-block-start: 2rem; + position: relative; + grid-area: i18n; + display: block; } -/* Non-English pages use pre and code tags for code blocks */ -.non-en-doc .page pre[class*="language-"] { - padding-top: 0 !important; - padding-bottom: 0 !important; +.doc-notice a{ + color: var(--notice-accent); + text-decoration: underline; } - -.page pre.plain-text, .page code.plain-text { - padding-top: 0 !important; - color: #000; +.doc-notice[hidden] { + display: none; } - -.doc-notice { - background: #faf6e8; - border: 1px solid #ded8c1; +.doc-info { + background: var(--info-bg); + border-left: 3px solid var(--info-accent); } -.doc-info { - background: #f7faec; - border: 1px solid #dfe2d3; +.doc-info a{ + color: var(--info-accent); + text-decoration: underline; } .doc-warn { - background: #f9f1f1; - border: 1px solid #e2d3d3; + background: var(--warn-bg); + border-left: 3px solid var(--warn-accent); } -#i18n-notice-box { - margin-top: 150px; - position: relative; +.doc-warn a { + color: var(--warn-accent); + text-decoration: underline; } #close-i18n-notice-box { position: absolute; top: 3px; - right: 4px; - color: #550000; + right: 9px; + color: var(--notice-accent); cursor: pointer; } @@ -580,215 +678,347 @@ html[xmlns] .clearfix { width: 200px; } -.button { - display: block; - padding: 3px 5px; - border: 1px solid #ccc; +div.header-btn { + display: flex; + padding: 3px; border-radius: 3px; cursor: pointer; - color: #555; + color: var(--box-fg); +} + +a.edit-github-btn{ + display: flex; + gap: 0.5rem; + align-items: center; + width: fit-content; + padding: 0.5rem; + border-radius: 0.3rem; + + &:is(:hover, :active, :focus) { + color: var(--fg); + background-color: var(--hover-bg); + outline: 1px solid var(--card-fg); + } } #mobile-menu { display: none; position: relative; - top: 9px; - left: 0; -} - -#nav-button { - position: absolute; - left: 16px; } pre, code { white-space: pre-wrap !important; } -#strongloop-header { - font-size: 0.7em; - display: block; - position: absolute; - right: 2%; - top: 11px; - width: 150px; - border-radius: 3px; - color: #08592B; - padding: 3px; -} +/* footer */ footer { - font-size: 11px; - margin: 60px 10px 30px 10px; - padding-left: 5%; - max-width: 1090px; + font-size: 12px; + display: flex; + gap: 24px; + flex-direction: column; + padding-block: 2rem; + padding-inline: 3rem; + + @media screen and (max-width : 360px) { + padding: 1rem; + } } #footer-content { - display: table; - margin: 20px auto 0; + width: 100%; + justify-content: space-between; + gap: 32px; + display: flex; } -#footer-content div { - float: left; - margin-right: 20px; - background-repeat: no-repeat; - background-position: 0 1px; - padding-bottom: 4px; +#footer-copyright { + display: flex; + flex-direction: column; + justify-content: center; + gap: 20px; } -#github { - margin-right: 5px !important; +#footer-policy { + display: flex; + flex-wrap: wrap; + column-gap: 20px; + row-gap: 8px; + justify-content: center; + font-size: 15px; } -#license { - text-align: center; - margin-top: -5px; +#footer-links { + display: flex; + gap: 20px; + flex-wrap: wrap; + align-items: center; + justify-content: center; } -#license img { - position: relative; - top: 3px; +.footer-social { + display: flex; + gap: 20px; } -#fork { - background-image: url(/images/fork-icon.png); - background-size: 11px 16px; - padding-left: 15px; +.footer-social a { + color: inherit; } -@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-devicepixel-ratio: 1.5), only screen and (min-resolution: 1.5dppx) { +/* icons */ +a.openjs-logo { + display: inline-block; + width: 125px; + height: 39px; + cursor: pointer; +} - #fork { - background-image: url(/images/fork-icon@2x.png); - } +/* theme and lang btn */ +button.theme-btn { + width: 2rem; + height: 2rem; + border: none; + cursor: pointer; + color: var(--fg); + background-color: inherit; + display: flex; + justify-content: center; + align-items: center; +} - #announcements p:first-child { - background-image: url(/images/announcement-icon@2x.png); - } +#icon-moon, +#icon-sun { + display: none; + align-self: center; +} +html.light-mode #icon-moon { + display: inline; +} +button.lang-btn { + appearance: none; + background-color: inherit; + border: 0; + cursor: pointer; + color: var(--card-fg); + padding: 0.2rem; + width: fit-content; + aspect-ratio: 1; } -/* navigation */ +div.desktop-lang-switcher { + position: relative; + + > ul.lang-list { + display: none; + opacity: 0; + position: absolute; + list-style: none; + visibility: hidden; + left: -75px; + z-index: 100; + background-color: var(--card-bg); + border: 1px solid; + border-radius: 10px; + padding: 0px; + min-width: max-content; + + li a { + display: block; + padding: 5px 20px 5px 20px; + text-decoration: none; + color: var(--card-fg); + &:is(:hover, :focus) { + background: var(--hover-bg); + } + } + + > li:first-child > a { + border-start-start-radius: 10px; + border-start-end-radius: 10px; + } + + > li:last-child > a { + border-end-start-radius: 10px; + border-end-end-radius: 10px; + } + } + + > ul.lang-list.open { + display: block; + opacity: 1; + visibility: visible; + } +} +/* navigation */ #navbar { - padding-left: 5%; - max-width: 1000px; - position: relative; + line-height: 30px; display: flex; - justify-content: flex-end; - align-items: flex-start; - top: 15px; - box-sizing: content-box; + align-items: center; } #navbar a { - color: #666; - padding-left: 20px; - -webkit-font-smoothing: subpixel-antialiased; + color: var(--card-fg); + text-decoration: none; } #navbar a.active { font-weight: bold; - color: #353535; } - -/* dropdown menu */ +#navbar ul { + list-style: none; +} #navmenu { - padding: 0; - margin: 0; - right: 0px; - z-index: 1000; - margin-right: 15px; + display: flex; + gap: 20px; } -#navmenu > li { - list-style: none; - padding: 0; - float: left; +/* content doc */ + +#blog-doc { + padding: 0.5rem; + width: fit-content; } -#navmenu a:hover { - text-decoration: none; +/* dropdown menu */ + +.submenu { + position: relative; + list-style: none; } -.menu ul { +.submenu-content { + position: absolute; + top: 100%; + left: 50%; + transform: translate(-50%); + margin: auto; + box-shadow: 1px 2px var(--hover-fg); + z-index: 1000; + min-width: max-content; + width: fit-content; + border: 1px solid var(--border); + border-radius: 12px; + background-color: var(--bg); + padding: 0; display: none; } -.menu ul.dropit-submenu { - background-color: #fcfcfa; - border: 1px solid #b2b2b2; - padding: 6px 0; - margin: 0 0 0 1px; - border-radius: 3px; - box-shadow: 0px 1px 3px rgba(0,0,0,0.15); +.submenu-content li:first-child a { + border-radius: 12px 12px 0 0; +} + +.submenu-content li:last-child a { + border-radius: 0px 0px 12px 12px; } -.menu ul.dropit-submenu a { +.submenu.open .submenu-content { + display: initial; +} + +#navmenu { + padding: 0; + margin: 0; + right: 0px; + z-index: 1000; + margin-right: 15px; +} + +.submenu-content li a { display: block; - color: #777; - padding: 0 8px 2px 8px; + padding: 2px 20px 2px 20px; } -.menu ul.dropit-submenu a:hover { - background: #259dff; - color: #fff !important; +#navbar .submenu-content a:hover { + background: var(--hover-bg); text-decoration: none; } -/* secondary menu */ + +/* TOC side menu */ + +.toc-container { + position: sticky; + top: 100px; + width: 270px +} #menu { - position: fixed; - margin: 0; - padding: 0 10px 0 0; - top: 153px; - left: 30px; - height: 500px; - text-align: left; - font-size: 13px; + min-width: 13rem; + padding-inline: 0.5rem; + font-size: 1rem; overflow-y: auto; + max-height: 65vh; + padding-block-end: 0.5rem; + margin-block: 0; +} + +#menu.blog-side-menu { + max-width: 20rem; + max-height: fit-content; +} + +#menu ul a, +#menu > li > a { + display: block; + color: var(--menu-grey); + padding-inline: 0.5rem; + text-decoration: none; + + &:is(:hover,:active,:focus) { + border-radius: 0.3rem; + color: var(--fg); + outline: 1px solid var(--card-fg); + } +} + +#menu ul a.active { + border-radius: 0.3rem; + color: var(--fg); + outline: 1px solid var(--card-fg); } #menu em { font-weight: bold; - color: #888; + color: var(--menu-em); + font-size: 1rem; } #menu li { + cursor: pointer; list-style: none; + margin-block-start: 0.3rem; } -#menu ul { +#menu ul, +ul#side-menu { + display: none; + opacity: 0; height: 0; overflow: hidden; } -#menu ul.active { +#menu ul.active, +ul#side-menu.active { height: auto; - padding: 0; + padding-inline: 0.5rem; + display: block; + opacity: 1; + padding-block: 0.5rem; } #menu > li > a { - color: #353535; font-weight: bold; - font-size: 15px; -} - -#menu ul a { - color: #555; - padding-right: 7px; -} - -#menu ul a.active { - color: #259dff; + font-size: 1rem; + padding-inline-start: 1rem; } +/* can't find this in proj*/ h2 a { - color: #353535 !important; + color: var(--card-fg) !important; } /* search */ @@ -796,33 +1026,180 @@ h2 a { #q { display: none; height: 2.5em; - min-width: 100%; + max-width: 100%; padding: 5px; -} +} .algolia-autocomplete { - min-width: 12em; - top: -0.2em; + max-width: 9em; + > input { + color: var(--fg); + background-color: var(--bg); + } + > input::placeholder { + color: var(--fg); + } + #q { + display: initial; + border-radius: 8px; + border: 1px solid var(--border); + transition: color .3s ease; + padding-inline: 12px; + outline: none; + &:focus-visible, + &:focus { + border-color: var(--hover-border); + border-width: 2px; + } + } +} + + #navbar { + .ds-dropdown-menu .ds-dataset-1 { + background-color: var(--bg); + .ds-suggestions { + /* background-color: var(--bg); */ + color: var(--fg); + } + .ds-suggestion a { + background-color: var(--bg); + color: var(--fg); + } + .ds-suggestion a { + background-color: var(--bg); + color: var(--fg); + } + .algolia-docsearch-suggestion--category-header { + color: var(--fg); + } + .algolia-docsearch-suggestion--wrapper { + background-color: var(--bg); + .algolia-docsearch-suggestion--subcategory-column { + color: var(--menu-grey); + + } + .algolia-docsearch-suggestion--title, + .algolia-docsearch-suggestion--text { + color: var(--fg); + } + .algolia-docsearch-suggestion--highlight { + color: var(--link); + background-color: initial; + } + } + .algolia-docsearch-suggestion { + background-color: initial; + } + .algolia-docsearch-suggestion--content .algolia-docsearch-suggestion--no-results{ + background-color: initial; + } + + } + .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--title, + .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { + background-color: var(--hover-bg); + } + } + + +.content-404 { + height: 70vh; + padding: 153px 32px 7%; + text-align: center; + display: flex; + justify-content: center; + flex-direction: column; + grid-area: content; } -.algolia-autocomplete #q { - display: initial +.content-404 p { + font-size: 16px; +} + +/* search-bar desktop re-sizing */ +@media all and (min-width: 950px) { + .algolia-autocomplete { + margin-right:15px; + max-width: 12em; + } +} + +/* toc title */ +.toc-heading { + display: block; + cursor: default; + padding-inline-start: 1rem; + & > em { + font-weight: bold; + color: var(--menu-em); + font-size: 1rem; + } +} + + +/* TOC btn */ + +#menu-toggle { + cursor: pointer; + display: none; + font-size: 1rem; + padding: 0.5rem; + opacity: 0; + width: fit-content; + border: 1px solid #000; + border-radius: 0.3rem; + color: #000; + background-color: #fff; + + &::after { + content: ""; + display: block; + width: 0.8em; + height: 0.5em; + background-color: var(--card-bg); + clip-path: polygon(100% 0%, 0 0%, 50% 100%); + cursor: pointer; + pointer-events: none; + transition: transform 0.2s ease-in-out; + transform: rotate(-90deg); + } + + &:is(:hover, :active, :focus) { + background-color: #ebf2f5; + } +} + +/* routing methods columns */ +.methods-columns { + display: flex; + gap: 2rem; + justify-content: space-between; + flex-wrap: wrap; + + @media screen and (max-width: 460px) { + flex-direction: column; + gap: 0.3rem; + } } /* responsive */ -@media all and (max-width: 899px) { +@media all and (max-width: 1440px) { + #menu{ + top: 75px; + } +} - #conference a img { - width: 150px; - margin-right: 10px; +@media all and (max-width: 1110px) { + #boxes { + grid-template-columns: 1fr 1fr; } #home-content { flex-direction: column; } - #install-command { + .install-command { display: none; } @@ -843,20 +1220,13 @@ h2 a { .table-scroller { width: 100%; overflow: scroll; - } - - #api-doc section { - padding-left: 0; + scrollbar-width: thin; } code { word-break: break-all; } - .menu ul.dropit-submenu a { - font-size: 16px !important; - } - ul { padding-left: 5%; } @@ -883,16 +1253,8 @@ h2 a { font-weight: normal; } - #menu { - display: none; - } - - .content { - padding-left: 0; - } - #home-content { - margin: 150px 0 0 5%; + margin: 60px 0 0 5%; padding-right: 5%; } @@ -900,310 +1262,477 @@ h2 a { margin-bottom: 35px; } - #description .express { - display: none; - } - #description .description { font-size: 3em; line-height: .9em; font-weight: 200; } - #install-command { - width: 100%; - margin-right: 5%; + .logo-container { + margin-inline: auto; } - #logo { - position: static; - width: 100%; + #home-menu { + display: block; + position: absolute; + top: 7px; } - #logo a { - display: table !important; - margin: 0 auto; + #overlay.blurs{ + display: block; } - #logo .express { - margin-top: 0px; - font-weight: bold; + .menu ul { + display: block; } - .github-fork-ribbon-wrapper { - display: none; + #footer-content { + flex-wrap: wrap; + justify-content: center; } - #mobile-menu { - display: block; + #footer-copyright > a { + width: 100%; + display: flex; + justify-content: center; } - #boxes div { - width: 90%; + .header-right { + display: flex; + gap: 8px; } +} - .content p img { - width: 98%; - height: 98%; +/* TOC responsive */ +@media all and (max-width: 800px) { + .content { + flex-direction: column; + padding-inline-start : 0; + margin-block-start: 1rem; } - #home-menu { - display: block; - position: absolute; - top: 7px; + .content main { + padding-inline: 1rem; + width: 100vw; + margin-top: 0; + margin-inline: 0; + } + + #api-doc, + #blog-doc, + #page-doc { + width: 100%; } - #navbar { - padding: 0; - top: 1px; + #api-doc section { + padding-left: 0; } - #navbar a { - font-size: 19px; - margin: 0; - padding-left: 5%; + .toc-container { + display: flex; + flex-direction: column; + gap: 0; + padding: 1rem; } - #navmenu { - left: 0; - padding: 0; - top: 2px; - background: #fff; - width: 100%; + #menu { display: none; + opacity: 0; + max-height: 0; + background-color: var(--card-bg); + min-width: 100%; } - #navmenu > li { - float: none; - border-bottom: 1px solid #ccc; - margin: 0; - min-height: 47px; - position: relative; - background: #eee; - cursor: pointer; + #menu.open { + display: block; + opacity: 1; + max-height: 35vh; + padding-inline: 1rem; + border-left: 2px solid var(--border); + margin-top: 0.3rem; + border-bottom-right-radius: 0.5rem; + border-top-right-radius: 0.5rem; } - #navmenu > li:first-child { - display: none; + .toc-container { + width: 100%; } - #navmenu > li:hover { - background: #e9e9e9; + #menu-toggle.show { + display: flex; + gap: 0.5rem; + align-items: center; + opacity: 1; } - #navmenu > li > ul { - position: static; + #menu-toggle.show.rotate::after { + transform: rotate(0deg); } - .dropit .dropit-submenu { - position: static !important; + #menu > li > a, + #menu ul a { + padding: 0.5rem; + &:is(:hover,:active,:focus) { + background: var(--hover-bg); + } } - .dropit .dropit-trigger { - padding-top: 7px; - } + #menu li ul li > em { + font-size: 0.8rem; + padding-inline: 1rem; + padding-block: 0.3rem; + background-color: var(--hover-bg); + border-radius: 0.3rem; + } - .menu ul.dropit-submenu { - margin-top: 7px; - background: #ddd; - padding: 0; - margin: 0; - border: none; - border-radius: 0; - box-shadow: none; - max-height: 190px; - overflow-y: scroll; - overflow-x: hidden; + .toc-heading{ + display: none; } +} - .dropit-trigger > a { - display: block; - margin-bottom: 8px !important; - } - .menu ul.dropit-submenu a { - padding: 5px 5px 5px 5%; +@media all and (max-width: 540px) { + #boxes { + grid-template-columns: 1fr; } +} - .dropit-submenu li { - border-bottom: 1px solid #cdcdcd; +@media all and (max-width: 420px) { + #app-settings-property { + width: auto; } +} - .dropit-submenu a { - padding-left: 10% !important; - } - .menu ul { - display: block; - } +@media print { - .active-mobile-menu { - border-bottom: none !important; + header { + position: absolute; } +} - .active-mobile-menu .dropit-trigger { - margin-bottom: 0 !important; - } +/* For image callouts in writing-middleware.md */ - .menu ul.dropit-submenu a:hover { - background: #cccccc; - color: #666 !important; - } +.callout {position: relative;} - footer { - margin: 60px 0px 30px 0px; - padding: 0 5%; - } +#mw-fig { + border-collapse: separate; + padding: 0; + border: 0; + width: 960px; + margin-bottom: 20px; +} +#mw-fig-imgcell { + margin: 0; + padding: 0px; + border: 0; + width: 410px; +} +#mw-fig-img { + margin: 0px; + padding: 0px; + width: 410px; + height: 308px; +} - #footer-content { +.mw-fig-callouts { + margin: 0; + padding: 0 0 0 5px; + border: 0; + width: 550px; +} + +/* Blog page styles*/ +#blog-doc { + margin: 0 1rem; + @media all and (max-width: 800px) { + margin: 0; + } +} +#blog-doc:has(> h1#express-blog), +#blog-doc:has(> h1#write-a-blog-post) { + min-height: 300px; +} +#blog-doc .blog-details ~ p > img { + width: 200px; + float: right; + margin: 0.5rem; +} +#blog-doc p { + font-size: 1.1em; +} +.blog-posts { + display: flex; + flex-direction: column; + row-gap: 10px; +} +.blog-post { + width: 100%; + background-color: var(--card-bg); + display: flex; + padding: 10px; + flex-direction: column; + justify-content: space-between; + border-radius: 5px; + border: 1px solid var(--border); + box-shadow: 2px 3px var(--hover-fg); + transition: 0.3s; +} +.blog-post:hover { + background-color: var(--hover-bg); + border: 1px solid var(--hover-border); + box-shadow: 2px 3px var(--menu-grey); +} +.blog-post img { + max-width: 100%; + max-height: 100%; + object-fit: cover; +} +.blog-post .blog-details { + display: flex; + flex-direction: column; +} +.blog-details div:first-child { + margin-bottom: 5px; +} +.blog-tag { + font-size: 12px; +} +.blog-title { + font-size: 1.3rem; + line-height: 1.5rem; + font-weight: 500; + padding-right: .2em; +} +.blog-title a { + color: var(--card-fg) +} +.blog-excerpt { + font-size: .75rem; +} +.blog-img { + max-width: 100%; + margin: auto; +} +.blog-authors { + font-style: italic; +} +.blog-author-link { + color: inherit; + margin-left: 0.5ch; + text-decoration: none; +} +.blog-author-link-label { + text-decoration: underline; +} +.blog-author-avatar { + border-radius: 50%; + display: inline-block; + vertical-align: middle; + width: 1.5em; + height: 1.5em; +} +.blog-date { + font-weight: bold; + font-size: 85%; +} +/* mobile-only */ +@media (max-width: 500px) { + #blog-doc { display: flex; flex-wrap: wrap; - justify-content: center; + flex-direction: column; align-items: center; + margin-right: 0; + padding-right: 10px; + } + #blog-doc .blog-details + p > img { + margin-bottom: 15px; } +} - #footer-content div { + + +/* blog tablet and up*/ +@media (min-width: 768px) { + .blog-post { + margin: auto; + } + .blog-tags { + margin-bottom: 20px; + } + .blog-title { + font-size: 1.3rem; + margin-bottom: 20px; + line-height: 1.5rem; + } + .blog-post .blog-details { display: flex; - flex-wrap: wrap; - align-items: center; - white-space: nowrap; + flex-direction: row; + margin-left: 1rem; + font-size: 90%; } - - #footer-content div#sponsor { - display: block; + .blog-post .blog-details div:first-child { + margin-right: 20px; } - - #doc-langs { - font-size: 11px; + .blog-details { + font-size: 1rem; } - - .algolia-autocomplete { - display: none !important; + .blog-excerpt { + line-height: initial; + font-size: .85rem; + font-weight: 300; + margin-top: auto; + margin-bottom: 10px; + max-width: 80%; } +} + +strong.supported { + color: var(--supported-fg) ; +} +strong.eol { + color: var(--eol-fg) ; +} +.logo-table { + display: flex; + flex-wrap: wrap; + row-gap: 8px; + column-gap: 48px; } +.logo-table h3{ + margin-bottom: 12px; +} -@media all and (max-width: 420px) { +blockquote { + margin-left: 0; + font-weight: 600; + font-style: italic; + padding-left: 1.2em; + border-left: .25rem solid var(--border); +} - #conference { - display:none; +@media all and (max-width: 1110px) { + .algolia-autocomplete { + display: none !important; } - #app-settings-property { - width: auto; + #mobile-menu { + display: block; } - #strongloop-header { - display: none; + #navbar { + padding: 0; + top: 1px; + position: static; } - #description .express { + #navmenu>li:first-child { display: none; } - footer { - margin-top: 14px; + #navmenu>li { + border-bottom: 1px solid var(--border); + margin: 0; + min-height: 47px; + background: var(--card-bg); + cursor: pointer; + display: flex; + align-items: center; } - #footer-content { - margin-left: 5%; + #navmenu>li.open:hover { + background: var(--card-bg); } - - #footer-content div { - clear: both; + #navmenu>li:hover { + background: var(--hover-bg); + & ul { + background-color: var(--card-bg); + } } - #footer-content div:nth-child(4) { - white-space: pre-line; - text-align: center; + #navmenu { + left: 0; + padding: 0; + top: 57px; + width: 100%; + position: absolute; + display: none; } - #fork { - margin-left: 7px; - margin-top: 2px; - margin-bottom: 30px; - padding-left: 18px; + #navmenu.opens { + display: block; } -} - -@media all and (max-width: 320px) { - - #install-command { - font-size: 12px; + #navbar a { + font-size: 19px; + margin: 0; + width: 100%; + height: 100%; + padding-left: 5%; } -} -@media print { - - header { - position: absolute; + #navbar .submenu.open { + flex-direction: column; + align-items: initial; + > a { + border-bottom: 1px solid var(--border); + } } - #mobile-menu { - display:none; + .submenu.open > a { + display: flex; + align-items: center; + min-height: 47px; } -} - -/* For image callouts in writing-middleware.md */ - -.callout {position: relative;} - -#mw-fig { border-collapse: separate; padding: 0; border: 0; width: 960px; margin-bottom: 20px;} -#mw-fig-imgcell {margin: 0; padding: 0px; border: 0; width: 410px;} -#mw-fig-img {margin: 0px; padding: 0px; width: 410px; height: 308px;} -.mw-fig-callouts {margin: 0; padding: 0 0 0 5px; border: 0; width: 550px;} - -/* For middleware pages */ -/* -#mw-list { - float: left; - width: 180px; - margin: 0; - padding: 0 10px 0 10px; - font-size: 13px; - } + .submenu-content { + width: 100%; + position: static; + display: none; + margin-top: 7px; + background-color: var(--card-bg); + padding: 0; + margin: 0; + border: none; + border-radius: 0; + box-shadow: none; + max-height: 190px; + overflow-y: auto; + overflow-x: hidden; + transform: none; + cursor: pointer; + } -#middleware { - min-width: 300px; -} -*/ + .submenu-content li > a { + width: 100%; + } -#mw-container { - display: flex; - display: -webkit-flex; /* Safari */ - width: 100%; -} + .submenu-content li:first-child a { + border-radius: 0; + } -#mw-list { - min-width: 180px; - margin: 0; - padding: 0 10px 0 10px; - font-size: 13px; - overflow-y: auto; - } + .submenu-content li:last-child { + border-bottom: 0; + } -#middleware-content { - /* flex: 0.85; */ - margin-left: 10px; -} + .submenu-content li:last-child a { + border-radius: 0; + } -#mw-list ul li { - margin-left: -20px; -} + .submenu-content.open { + display: inline-block; + } -#blm-banner { - text-align: center; - background: #010101; - color: #f1f1f1; - padding: 5px; - font-size: 16px; - width: 100%; -} + #navbar .submenu-content li a { + font-size: 16px; + padding: 5px 5px 5px 5%; + padding-left: 10%; + } -#blm-donate { - color: #5E80F7; - text-decoration: none; + .submenu-content li { + border-bottom: 1px solid var(--border); + } } diff --git a/css/th.css b/css/th.css deleted file mode 100644 index c999ef4688..0000000000 --- a/css/th.css +++ /dev/null @@ -1,18 +0,0 @@ -@font-face { - font-family: 'TH SarabunNew'; - src: url("../fonts/th/THSarabunNew.woff") -} - -#description .description { - position: relative; - top: -5px; - font: 100 4.1em "TH SarabunNew", "Helvetica Neue", "Open Sans", sans-serif; - color: #aeaeae; - line-height: .87; - } - - /* Non-English pages use pre and code tags for code blocks */ -.non-en-doc .page pre[class*="language-"] { - padding-top: 10px !important; - padding-bottom: 10px !important; -} \ No newline at end of file diff --git a/css/themes/dark-theme.css b/css/themes/dark-theme.css new file mode 100644 index 0000000000..0c6a563696 --- /dev/null +++ b/css/themes/dark-theme.css @@ -0,0 +1,21 @@ +html.dark-mode { + + #icon-sun { + display: inline; + } + + .submenu-content { + box-shadow: 1px 2px var(--hover-bg); + background-color: var(--card-bg); + } + + #navmenu>li:hover { + ul { + background-color: var(--card-bg); + } + } + + .blog-excerpt { + color: var(--notice-accent); + } +} \ No newline at end of file diff --git a/css/tr.css b/css/tr.css deleted file mode 100644 index 1b920cecdf..0000000000 --- a/css/tr.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 170px;} - -#callout6 {top: 195px;} diff --git a/css/uk.css b/css/uk.css deleted file mode 100644 index b4b5f80056..0000000000 --- a/css/uk.css +++ /dev/null @@ -1,19 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -.callout {position: relative;} - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 165px;} - -#callout6 {top: 185px;} diff --git a/css/variables.css b/css/variables.css new file mode 100644 index 0000000000..5680810934 --- /dev/null +++ b/css/variables.css @@ -0,0 +1,52 @@ +:root.light-mode { + --grey-fg: #aeaeae; + --bg: #ffffff; + --fg: #383838; + --card-bg: #f0f1f3; + --card-fg: #383838; + /* text (api side menus h3...) */ + --menu-grey: #888; + --hover-border: #484848; + --hover-bg: #D3D3D3; + --hover-fg: #fafafa; + --border: #d9e1e4; + --link: #0e78ce; + /* docs related */ + --box-fg: #181818; + --info-bg: #cfd4fc; + --info-accent: #0f1c8a; + --notice-bg: #fceac5; + --notice-accent: #2E1D00; + --warn-bg: #fad1df; + --warn-accent: #8a0f3a; + --code-bg: #f0f1f3; + /* support page related */ + --supported-fg: #009000; + --eol-fg: #ff0000; +} +:root.dark-mode { + --bg: #0c0c0c; + --fg: #fafafa; + --card-bg: #181818; + --card-fg: #f7f4f4; + --hover-bg: #262626; + --hover-fg: #f2f2f2; + --hover-border: #fafafa; + --border: #d9e1e4; + /* text (api side menus h3...) */ + --menu-grey: silver; + --link: #259dff; + --menu-em: #a2a0a0eb; + /* docs related */ + --box-fg: #ffffff; + --info-bg: #171d4f; + --info-accent: #bdc3ff; + --notice-bg: #4e4022; + --notice-accent: #f9e8c3; + --warn-bg: #4e2232; + --warn-accent: #f9c3d6; + --code-bg: #2b2b2b; + /* support page related */ + --supported-fg:#299009; + --eol-fg: #ff1a1a; +} diff --git a/css/zh-cn.css b/css/zh-cn.css deleted file mode 100644 index 1b920cecdf..0000000000 --- a/css/zh-cn.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 170px;} - -#callout6 {top: 195px;} diff --git a/css/zh-tw.css b/css/zh-tw.css deleted file mode 100644 index 1b920cecdf..0000000000 --- a/css/zh-tw.css +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ -/* For image callouts in writing-middleware.md */ - -#callout1 {top: 40px; } - -#callout2 {top: 60px;} - -#callout3 {top: 75px;} - -#callout4 {top: 145px;} - -#callout5 {top: 170px;} - -#callout6 {top: 195px;} diff --git a/de/3x/api.md b/de/3x/api.md old mode 100755 new mode 100644 index 6520d8a199..e3655297ab --- a/de/3x/api.md +++ b/de/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - API-Referenz +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: de +redirect_from: " " --- +
**Express 3.x WIRD NICHT MEHR GEWARTET** - Bekannte und unbekannte Probleme bei Sicherheit und Leistung in 3.x wurden seit dem letzten Update (1. August 2015) noch nicht behoben. Es wird dringend empfohlen, die aktuelle Version von Express zu verwenden. -
- -

3.x-API

+Bekannte und unbekannte Probleme bei Sicherheit und Leistung in 3.x wurden seit dem letzten Update (1. August 2015) noch nicht behoben. Es wird dringend empfohlen, die aktuelle Version von Express zu verwenden. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
- - {% include api/en/3x/res.md %} +

3.x-API

- - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %} diff --git a/de/4x/api.md b/de/4x/api.md old mode 100755 new mode 100644 index b29bca87c9..4db5c42322 --- a/de/4x/api.md +++ b/de/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - API-Referenz +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: de +redirect_from: " " --- +

4.x-API

- - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
diff --git a/de/5x/api.md b/de/5x/api.md new file mode 100644 index 0000000000..a7dbfff302 --- /dev/null +++ b/de/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - API-Referenz +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
+ +

5.x API

+ +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
diff --git a/de/advanced/best-practice-performance.md b/de/advanced/best-practice-performance.md old mode 100755 new mode 100644 index 84462670c7..c66899b35d --- a/de/advanced/best-practice-performance.md +++ b/de/advanced/best-practice-performance.md @@ -1,41 +1,48 @@ --- layout: page title: Leistungsspezifische Best Practices für Express-Anwendungen in Produktionsumgebungen +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: de +redirect_from: " " --- # Best Practices in Produktionsumgebungen: Leistung und Zuverlässigkeit -## Überblick - In diesem Beitrag werden Best Practices in Bezug auf Leistung und Zuverlässigkeit für Express-Anwendungen behandelt, die in der Produktionsumgebung bereitgestellt werden. Dieses Thema gehört sicherlich zur "DevOps"-Welt und deckt traditionelle Entwicklungs- und Betriebsprozesse ab. Entsprechend sind die Informationen hier in zwei Teile unterteilt: -* [Empfehlungen für Maßnahmen an Ihrem Code](#code) (Entwicklung). -* [Empfehlungen für Maßnahmen an Ihrer Umgebung/Ihrem Setup](#env) (Betrieb). - - - -## Empfehlungen für Maßnahmen an Ihrem Code +- Things to do in your code (the dev part): + - Für statische Dateien Middleware verwenden + - Keine synchronen Funktionen verwenden + - [Do logging correctly](#do-logging-correctly) + - [Handle exceptions properly](#handle-exceptions-properly) +- Things to do in your environment / setup (the ops part): + - NODE_ENV auf "production" festlegen + - Automatischen Neustart Ihrer Anwendung sicherstellen + - Anwendung in einem Cluster ausführen + - Anforderungsergebnisse im Cache speichern + - Load Balancer verwenden + - Reverse Proxy verwenden + +## Things to do in your code {#in-code} Dies sind einige Beispiele für Maßnahmen, die Sie an Ihrem Code vornehmen können, um die Anwendungsleistung zu verbessern: -* GZIP-Komprimierung verwenden -* Keine synchronen Funktionen verwenden -* Für statische Dateien Middleware verwenden -* Auf ordnungsgemäße Protokollierung achten -* Ausnahmebedingungen ordnungsgemäß handhaben +- Für statische Dateien Middleware verwenden +- Keine synchronen Funktionen verwenden +- [Do logging correctly](#do-logging-correctly) +- [Handle exceptions properly](#handle-exceptions-properly) ### GZIP-Komprimierung verwenden Mit der GZIP-Komprimierung lässt sich die Größe des Antworthauptteils deutlich verringern und somit die Geschwindigkeit der Webanwendung erhöhen. Verwenden Sie die Middleware [compression](https://www.npmjs.com/package/compression) für die GZIP-Komprimierung in Ihrer Express-Anwendung. Beispiel: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` @@ -47,19 +54,11 @@ Synchrone Funktionen und Methoden belasten den Ausführungsprozess, bis sie zur Auch wenn Node und viele andere Module synchrone und asynchrone Versionen ihrer Funktionen bieten, sollten Sie in Produktionsumgebungen immer die asynchrone Version verwenden. Nur beim ersten Systemstart ist die Verwendung einer synchronen Funktion begründet. -Wenn Sie Node.js 4.0 und höher oder io.js 2.1.0 und höher verwenden, können Sie über das Befehlszeilenflag `--trace-sync-io` eine Warnung und einen Stack-Trace ausgeben, wenn Ihre Anwendung eine synchrone API verwendet. Auch wenn Sie diese natürlich nicht in der Produktionsumgebung verwenden werden, soll dadurch trotzdem sichergestellt werden, dass Ihr Code in der Produktionsumgebung eingesetzt werden kann. Weitere Informationen hierzu siehe [Wöchentliches Update für io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0). - -### Für statische Dateien Middleware verwenden +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. Auch wenn Sie diese natürlich nicht in der Produktionsumgebung verwenden werden, soll dadurch trotzdem sichergestellt werden, dass Ihr Code in der Produktionsumgebung eingesetzt werden kann. Weitere Informationen hierzu siehe [Wöchentliches Update für io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0). -Bei der Entwicklung können Sie [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) für statische Dateien verwenden. Dies gilt jedoch nicht für die Produktionsumgebung, da diese Funktion bei jeder Dateianforderung aus dem Dateisystem lesen muss. Dadurch kommt es zu deutlichen Latenzen, die sich negativ auf die Gesamtleistung der Anwendung auswirken. Beachten Sie, dass `res.sendFile()` *nicht* mit dem Systemaufruf [sendfile](http://linux.die.net/man/2/sendfile) implementiert wird, wodurch dieser deutlich effizienter wäre. +### Do logging correctly -Verwenden Sie stattdessen die Middleware [serve-static](https://www.npmjs.com/package/serve-static) (oder etwas Vergleichbares), die für die Bereitstellung von Dateien für Express-Anwendungen optimiert ist. - -Die bessere Option wäre, für statische Dateien einen Reverse Proxy zu verwenden. Weitere Informationen siehe [Reverse Proxy verwenden](#proxy). - -### Auf ordnungsgemäße Protokollierung achten - -Im Allgemeinen gibt es für die Protokollierung Ihrer Anwendung zwei Gründe: 1) Debugging und 2) Protokollierung von Anwendungsaktivitäten (im Wesentlichen alles andere, außer Debugging). Die Verwendung von`console.log()` oder `console.err()` zur Ausgabe von Protokollnachrichten an das Terminal ist in der Entwicklung gängige Praxis. [Diese Funktionen sind jedoch synchron](https://nodejs.org/api/console.html#console_console_1), wenn das Ziel ein Terminal oder eine Datei ist. Sie sind also für Produktionsumgebungen nicht geeignet, es sei denn, Sie leiten die Ausgabe per Pipe zu einem anderen Programm um. +Im Allgemeinen gibt es für die Protokollierung Ihrer Anwendung zwei Gründe: 1) Debugging und 2) Protokollierung von Anwendungsaktivitäten (im Wesentlichen alles andere, außer Debugging). Die Verwendung von`console.log()` oder `console.err()` zur Ausgabe von Protokollnachrichten an das Terminal ist in der Entwicklung gängige Praxis. 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. #### Für Debuggingzwecke @@ -67,51 +66,37 @@ Wenn Sie die Protokollierung für Debuggingzwecke nutzen, sollten Sie statt `con #### Für Anwendungsaktivitäten -Wenn Sie Anwendungsaktivitäten protokollieren (z. B. den Datenverkehr oder API-Aufrufe aufzeichnen), sollten Sie statt `console.log()` eine Protokollierungsbibliothek wie [Winston](https://www.npmjs.com/package/winston) oder [Bunyan](https://www.npmjs.com/package/bunyan) verwenden. Einen ausführlichen Vergleich dieser beiden Bibliotheken finden Sie im StrongLoop-Blogbeitrag [Vergleich von Winston und Bunyan für die Node.js-Protokollierung](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - - +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. ### Ausnahmebedingungen ordnungsgemäß handhaben -Node-Anwendungen stürzen ab, wenn eine nicht abgefangene Ausnahmebedingung vorkommt. Wenn diese Ausnahmebedingungen nicht behandelt und entsprechende Maßnahmen eingeleitet werden, stürzt Ihre Express-Anwendung ab und geht offline. Wenn Sie dem nachfolgenden Rat in [Sicherstellen, dass Ihre Anwendung automatisch neu gestartet wird](#restart) folgen, wird Ihre Anwendung nach einem Absturz wiederhergestellt. Glücklicherweise haben Express-Anwendungen nur eine kurze Initialisierungszeit. Nichtsdestotrotz sollten Sie in erster Linie solche Abstürze vermeiden. Und hierzu müssen Sie Ausnahmebedingungen ordnungsgemäß handhaben. +Node-Anwendungen stürzen ab, wenn eine nicht abgefangene Ausnahmebedingung vorkommt. Wenn diese Ausnahmebedingungen nicht behandelt und entsprechende Maßnahmen eingeleitet werden, stürzt Ihre Express-Anwendung ab und geht offline. Wenn Sie dem nachfolgenden Rat in [Sicherstellen, dass Ihre Anwendung automatisch neu gestartet wird](#restart) folgen, wird Ihre Anwendung nach einem Absturz wiederhergestellt. Glücklicherweise haben Express-Anwendungen nur eine kurze Initialisierungszeit. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. Mit folgenden Verfahren stellen Sie sicher, dass alle Ausnahmebedingungen gehandhabt werden: -* ["try-catch" verwenden](#try-catch) -* ["Promises" verwenden](#promises) +- ["try-catch" verwenden](#try-catch) +- ["Promises" verwenden](#promises) Um näher auf diese Themen eingehen zu können, müssen Sie sich ein grundlegendes Verständnis der Fehlerbehandlung in Node und Express aneignen: Verwendung von Error-first-Callbacks und Propagieren von Fehlern in Middleware. Node verwendet die Konvention "Error-first-Callback" für die Rückgabe von Fehlern von asynchronen Funktionen, bei denen der erste Parameter zur Callback-Funktion das Fehlerobjekt ist, gefolgt von Ergebnisdaten in den nachfolgenden Parametern. Um anzugeben, dass kein Fehler vorliegt, müssen Sie "null" als ersten Parameter übergeben. Die Callback-Funktion muss der Konvention "Error-first-Callback" folgen, um den Fehler sinnvoll bearbeiten zu können. In Express hat sich bewährt, die Funktion "next()" zu verwenden, um Fehler über die Middleware-Chain zu propagieren. Weitere Informationen zu den Grundlagen der Fehlerbehandlung siehe: -* [Fehlerbehandlung in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Aufbau leistungsfähiger Node-Anwendungen: Fehlerbehandlung](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop-Blog) - -#### Was Sie unterlassen sollten - -Sie sollten *auf keinen* Fall per Listener das Ereignis `uncaughtException` überwachen, das ausgegeben wird, wenn eine Ausnahmebedingung bis zurück zur Ereignisschleife bestehen bleibt. Durch das Hinzufügen eines Ereignislisteners für `uncaughtException` verändert sich das Standardverhalten des Prozesses, über das eine Ausnahmebedingung festgestellt wird. Der Prozess läuft dann trotz der Ausnahmebedingung weiter. Dies mag sich vielleicht gut anhören, um einem Absturz Ihrer Anwendung vorzubeugen. Das Ausführen einer Anwendung nach einer nicht abgefangenen Ausnahmebedingung ist aber eine durchaus riskante Vorgehensweise und wird nicht empfohlen, da der Prozessstatus störanfällig und unvorhersehbar wird. - -Außerdem wird die Verwendung von `uncaughtException` offiziell als [grobes Vorgehen](https://nodejs.org/api/process.html#process_event_uncaughtexception) angesehen, sodass es den [Vorschlag](https://github.com/nodejs/node-v0.x-archive/issues/2582) gibt, die Funktion aus dem Kern zu entfernen. Das Überwachen von `uncaughtException` per Listener ist also keine gute Idee. Daher empfehlen wir Dinge wie Mehrfachprozesse und Supervisoren: Ein Absturz und anschließender Neustart ist häufig die zuverlässigste Art der Fehlerbehebung. - -Zudem empfehlen wir, [domains](https://nodejs.org/api/domain.html) nicht zu verwenden. Mit diesem Modul, das zudem veraltet ist, lässt sich das Problem in der Regel nicht lösen. - - +- [Fehlerbehandlung in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### "try-catch" verwenden "try-catch" ist ein JavaScript-Sprachkonstrukt, mit dem Sie Ausnahmebedingungen in synchronem Code abfangen können. Verwenden Sie "try-catch" beispielsweise, um JSON-Parsing-Fehler wie unten gezeigt zu bearbeiten. -Verwenden Sie ein Tool wie [JSHint](http://jshint.com/) oder [JSLint](http://www.jslint.com/), um implizite Ausnahmebedingungen wie [Referenzfehler bei nicht definierten Variablen](http://www.jshint.com/docs/options/#undef) zu finden. - -Dies ist ein Beispiel zur Verwendung von "try-catch", um eine potenzielle "process-crashing"-Ausnahmebedingung zu handhaben. Diese Middlewarefunktion akzeptiert einen Abfragefeldparameter mit dem Namen "params", der ein JSON-Objekt ist. +Dies ist ein Beispiel zur Verwendung von "try-catch", um eine potenzielle "process-crashing"-Ausnahmebedingung zu handhaben. +Diese Middlewarefunktion akzeptiert einen Abfragefeldparameter mit dem Namen "params", der ein JSON-Objekt ist. ```js app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -122,107 +107,84 @@ app.get('/search', (req, res) => { "try-catch" funktioniert jedoch nur in synchronem Code. Da die Node-Plattform primär asynchron ist (insbesondere in einer Produktionsumgebung), lassen sich mit "try-catch" nicht besonders viele Ausnahmebedingungen abfangen. - - #### "Promises" verwenden -Mit "Promises" werden alle Ausnahmebedingungen (explizite und implizite) in asynchronen Codeblöcken gehandhabt, die `then()` verwenden. Sie müssen nur `.catch(next)` am Ende der Promises-Ketten hinzufügen. Beispiel: +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -Jetzt werden alle asynchronen und synchronen Fehler zur Middleware "error" propagiert. - -Es gibt jedoch zwei Vorbehalte: - -1. Der gesamte asynchrone Code muss "Promises" zurückgeben (außer Emitter). Wenn eine bestimmte Bibliothek keine "Promises" zurückgibt, müssen Sie das Basisobjekt mit einer Helper-Funktion wie [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html) konvertieren. -2. Ereignisemitter (wie Streams) können nach wie vor nicht abgefangene Ausnahmebedingungen verursachen. Sie müssen also sicherstellen, dass Sie das Fehlerereignis ordnungsgemäß handhaben. Beispiel: +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -Weitere Informationen zur Fehlerbehandlung mithilfe von "Promises" siehe: +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 -* [Asynchrone Fehlerbehandlung in Express mit "Promises", Generatoren und ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* ["Promises" in Node.js mit Q – eine Alternative zu Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +Sie sollten _auf keinen_ Fall per Listener das Ereignis `uncaughtException` überwachen, das ausgegeben wird, wenn eine Ausnahmebedingung bis zurück zur Ereignisschleife bestehen bleibt. Durch das Hinzufügen eines Ereignislisteners für `uncaughtException` verändert sich das Standardverhalten des Prozesses, über das eine Ausnahmebedingung festgestellt wird. Das Ausführen einer Anwendung nach einer nicht abgefangenen Ausnahmebedingung ist aber eine durchaus riskante Vorgehensweise und wird nicht empfohlen, da der Prozessstatus störanfällig und unvorhersehbar wird. + +Außerdem wird die Verwendung von `uncaughtException` offiziell als [grobes Vorgehen](https://nodejs.org/api/process.html#process_event_uncaughtexception) angesehen, sodass es den [Vorschlag](https://github.com/nodejs/node-v0.x-archive/issues/2582) gibt, die Funktion aus dem Kern zu entfernen. Das Überwachen von `uncaughtException` per Listener ist also keine gute Idee. Daher empfehlen wir Dinge wie Mehrfachprozesse und Supervisoren: Ein Absturz und anschließender Neustart ist häufig die zuverlässigste Art der Fehlerbehebung. - +Zudem empfehlen wir, [domains](https://nodejs.org/api/domain.html) nicht zu verwenden. Mit diesem Modul, das zudem veraltet ist, lässt sich das Problem in der Regel nicht lösen. -## Empfehlungen für Maßnahmen an Ihrer Umgebung/Ihrem Setup +## Things to do in your environment / setup {#in-environment} Dies sind einige Beispiele für Maßnahmen, die Sie an Ihrer Systemumgebung vornehmen können, um die Anwendungsleistung zu verbessern: -* NODE_ENV auf "production" festlegen -* Automatischen Neustart Ihrer Anwendung sicherstellen -* Anwendung in einem Cluster ausführen -* Anforderungsergebnisse im Cache speichern -* Load Balancer verwenden -* Reverse Proxy verwenden +- NODE_ENV auf "production" festlegen +- Automatischen Neustart Ihrer Anwendung sicherstellen +- Anwendung in einem Cluster ausführen +- Anforderungsergebnisse im Cache speichern +- Load Balancer verwenden +- Reverse Proxy verwenden ### NODE_ENV auf "production" festlegen -In der Umgebungsvariablen NODE_ENV wird die Umgebung angegeben, in der eine Anwendung ausgeführt wird (in der Regel ist dies die Entwicklungs- oder Produktionsumgebung). Am einfachsten lässt sich die Leistung verbessern, indem NODE_ENV auf "production" festgelegt wird. +In der Umgebungsvariablen NODE_ENV wird die Umgebung angegeben, in der eine Anwendung ausgeführt wird (in der Regel ist dies die Entwicklungs- oder Produktionsumgebung). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. Durch das Festlegen von NODE_ENV auf "production" führt Express Folgendes aus: -* Speichern von Anzeigevorlagen im Cache. -* Speichern von CSS-Dateien, die aus CSS-Erweiterungen generiert wurden, im Cache. -* Generieren von weniger ausführlichen Fehlernachrichten. - -[Tests deuten darauf hin](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/), dass alleine dadurch die Anwendungsleistung um den Faktor 3 verbessert werden kann! - -Wenn Sie umgebungsspezifischen Code schreiben müssen, können Sie den Wert von NODE_ENV mit `process.env.NODE_ENV` überprüfen. Beachten Sie, dass die Überprüfung des Werts seiner Umgebungsvariablen eine leistungsbezogene Penalisierung nach sich zieht. Sie sollten also sehr sparsam damit umgehen. +- Speichern von Anzeigevorlagen im Cache. +- Speichern von CSS-Dateien, die aus CSS-Erweiterungen generiert wurden, im Cache. +- Generieren von weniger ausführlichen Fehlernachrichten. -In einer Entwicklungsumgebung wird die Umgebungsvariable in der Regel in Ihrer interaktiven Shell festgelegt, indem Sie beispielsweise `export` oder Ihre Datei `.bash_profile` verwenden. Im Allgemeinen sollten Sie dies nicht auf dem Produktionsserver vornehmen. Verwenden Sie stattdessen das Init-System (systemd oder Upstart) Ihres Betriebssystems. Der nächste Abschnitt enthält weitere Details zur Verwendung des Init-Systems im Allgemeinen. Die Festlegung von NODE_ENV ist jedoch für das Leistungsverhalten so wichtig (und so einfach durchzuführen), dass hier besonders darauf eingegangen wird. +[Tests indicate](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! -Verwenden Sie bei Upstart das Schlüsselwort `env` in Ihrer Jobdatei. Beispiel: +Wenn Sie umgebungsspezifischen Code schreiben müssen, können Sie den Wert von NODE_ENV mit `process.env.NODE_ENV` überprüfen. Beachten Sie, dass die Überprüfung des Werts seiner Umgebungsvariablen eine leistungsbezogene Penalisierung nach sich zieht. -
-
-# /etc/init/env.conf
- env NODE_ENV=production
-
-
- -Weitere Informationen hierzu siehe [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). +In einer Entwicklungsumgebung wird die Umgebungsvariable in der Regel in Ihrer interaktiven Shell festgelegt, indem Sie beispielsweise `export` oder Ihre Datei `.bash_profile` verwenden. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). Der nächste Abschnitt enthält weitere Details zur Verwendung des Init-Systems im Allgemeinen. Die Festlegung von NODE_ENV ist jedoch für das Leistungsverhalten so wichtig (und so einfach durchzuführen), dass hier besonders darauf eingegangen wird. Verwenden Sie bei systemd die Anweisung `Environment` in Ihrer Einheitendatei. Beispiel: -
-
+```sh
 # /etc/systemd/system/myservice.service
 Environment=NODE_ENV=production
-
-
- -Weitere Informationen siehe [Umgebungsvariablen in systemd-Einheiten verwenden](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). +``` -Wenn Sie StrongLoop Process Manager verwenden, können Sie auch die [Umgebungsvariable festlegen, wenn Sie StrongLoop Process Manager als Service installieren](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### Automatischen Neustart Ihrer Anwendung sicherstellen In der Produktionsumgebung sollte die Anwendung nie offline sein. Das bedeutet, dass Sie sicherstellen müssen, dass die Anwendung bei einem Absturz der Anwendung oder des Servers immer wieder neu gestartet wird. Auch wenn man hofft, das keines dieser Ereignisse jemals eintritt, muss man doch mit beiden Möglichkeiten rechnen und: -* einen Prozessmanager verwenden, um die Anwendung (und Node) bei einem Absturz neu zu starten. -* das Init-System Ihres Betriebssystems verwenden, um den Prozessmanager bei einem Absturz des Betriebssystems neu zu starten. Außerdem kann das Init-System auch ohne einen Prozessmanager verwendet werden. +- einen Prozessmanager verwenden, um die Anwendung (und Node) bei einem Absturz neu zu starten. +- das Init-System Ihres Betriebssystems verwenden, um den Prozessmanager bei einem Absturz des Betriebssystems neu zu starten. Außerdem kann das Init-System auch ohne einen Prozessmanager verwendet werden. Node-Anwendungen stürzen ab, wenn eine nicht abgefangene Ausnahmebedingung auftritt. Als Erstes müssen Sie in einem solchen Fall sicherstellen, dass Ihre Anwendung ausreichend getestet wurde und in der Lage ist, alle Ausnahmebedingungen zu handhaben (weitere Informationen siehe [Ausnahmebedingungen ordnungsgemäß handhaben](#exceptions)). Die sicherste Maßnahme ist jedoch, einen Mechanismus zu implementieren, über den bei einem Absturz der Anwendung ein automatischer Neustart der Anwendung ausgeführt wird. @@ -232,55 +194,35 @@ In Entwicklungumgebungen wird die Anwendung einfach über die Befehlszeile mit ` Neben einem Neustart der Anwendung nach einem Absturz bietet ein Prozessmanager noch weitere Möglichkeiten: -* Einblicke in die Laufzeitleistung und die Ressourcennutzung -* Dynamische Änderung der Einstellungen zur Verbesserung des Leistungsverhaltens -* Steuerung des Clustering (StrongLoop PM und PM2) - -Die gängigsten Prozessmanager für Node sind: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -Einen Vergleich der Features und Funktionen dieser Prozessmanager finden Sie hier: [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Eine ausführliche Einführung in diese drei Prozessmanager finden Sie hier: [Prozessmanager für Express-Anwendungen](/{{ page.lang }}/advanced/pm.html). - -Die Verwendung eines dieser Prozessmanager reicht aus, um Ihre Anwendung betriebsbereit zu halten, selbst wenn sie hin und wieder abstürzt. +- Einblicke in die Laufzeitleistung und die Ressourcennutzung +- Dynamische Änderung der Einstellungen zur Verbesserung des Leistungsverhaltens +- Control clustering (pm2). -StrongLoop PM verfügt jedoch über zahlreiche Features und Funktionen, die sich speziell auf Implementierungen in der Produktionsumgebung beziehen. Sie können diesen Prozessmanager und die zugehörigen StrongLoop-Tools für folgende Zwecke verwenden: - -* Lokales Erstellen und Packen Ihrer Anwendung mit anschließender sicherer Bereitstellung auf Ihrem Produktionssystem -* Automatischer Neustart Ihrer Anwendung nach einem Absturz aus irgendeinem Grund -* Verwaltung Ihrer Cluster über Fernzugriff -* Anzeige von CPU-Profilen und Heapspeichermomentaufnahmen (Heap-Snapshots) zur Optimierung der Leistung und Diagnose von Speicherlecks -* Anzeige von Leistungsmessdaten für Ihre Anwendung -* Einfache Skalierung auf mehrere Hosts mit integrierter Steuerung für Nginx Load Balancer - -Wie unten beschrieben, erfolgt ein automatischer Neustart beim Systemwiederanlauf, wenn Sie StrongLoop Process Manager über Ihr Init-System als Betriebssystemservice installieren. Dadurch bleiben Ihre Anwendungsprozesse und Cluster dauerhaft betriebsbereit. +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. #### Init-System verwenden -Als nächste Ebene der Zuverlässigkeit müssen Sie sicherstellen, dass Ihre Anwendung bei einem Serverneustart neu gestartet wird. Systeme können immer wieder aus verschiedenen Gründen abstürzen. Um sicherzustellen, dass Ihre Anwendung bei einem Serverabsturz neu gestartet wird, können Sie das in Ihr Betriebssystem integrierte Init-System verwenden. Die beiden wichtigsten Init-Systeme sind aktuell [systemd](https://wiki.debian.org/systemd) und [Upstart](http://upstart.ubuntu.com/). +Als nächste Ebene der Zuverlässigkeit müssen Sie sicherstellen, dass Ihre Anwendung bei einem Serverneustart neu gestartet wird. Systeme können immer wieder aus verschiedenen Gründen abstürzen. Um sicherzustellen, dass Ihre Anwendung bei einem Serverabsturz neu gestartet wird, können Sie das in Ihr Betriebssystem integrierte Init-System verwenden. The main init system in use today is [systemd](https://wiki.debian.org/systemd). Es gibt zwei Möglichkeiten, Init-Systeme mit Ihrer Express-Anwendung zu verwenden: -* Ausführung Ihrer Anwendung in einem Prozessmanager und Installation des Prozessmanagers als Service mit dem Init-System. Der Prozessmanager wird neu gestartet, wenn Ihre Anwendung abstürzt. Das Init-System startet dann den Prozessmanager neu, sobald das Betriebssystem neu gestartet wird. Dies ist die empfohlene Vorgehensweise. -* Ausführung Ihrer Anwendung (und von Node) direkt mit dem Init-System. Diese Vorgehensweise ist zwar etwas einfacher, Sie profitieren jedoch nicht von den zusätzlichen Vorteilen des Einsatzes eines Prozessmanagers. +- Ausführung Ihrer Anwendung in einem Prozessmanager und Installation des Prozessmanagers als Service mit dem Init-System. Der Prozessmanager wird neu gestartet, wenn Ihre Anwendung abstürzt. Dies ist die empfohlene Vorgehensweise. +- Ausführung Ihrer Anwendung (und von Node) direkt mit dem Init-System. Diese Vorgehensweise ist zwar etwas einfacher, Sie profitieren jedoch nicht von den zusätzlichen Vorteilen des Einsatzes eines Prozessmanagers. ##### systemd "systemd" ist ein Linux-System und Service-Manager. Die meisten wichtigen Linux-Distributionen haben "systemd" als Init-Standardsystem übernommen. -Eine "systemd"-Servicekonfigurationsdatei wird als *Einheitendatei* bezeichnet, die die Endung ".service" hat. Dies ist ein Beispiel für eine Einheitendatei zur direkten Verwaltung einer Node-Anwendung (ersetzen Sie den Text in Fettdruck durch Werte für Ihr System und Ihre Anwendung): +Eine "systemd"-Servicekonfigurationsdatei wird als _Einheitendatei_ bezeichnet, die die Endung ".service" hat. Dies ist ein Beispiel für eine Einheitendatei zur direkten Verwaltung einer Node-Anwendung (ersetzen Sie den Text in Fettdruck durch Werte für Ihr System und Ihre Anwendung): Replace the values enclosed in `` for your system and app: -
-
+```sh
 [Unit]
-Description=Awesome Express App
+Description=
 
 [Service]
 Type=simple
-ExecStart=/usr/local/bin/node /projects/myapp/index.js
-WorkingDirectory=/projects/myapp
+ExecStart=/usr/local/bin/node 
+WorkingDirectory=
 
 User=nobody
 Group=nogroup
@@ -301,111 +243,15 @@ Restart=always
 
 [Install]
 WantedBy=multi-user.target
-
-
-Weitere Informationen zu "systemd" siehe [systemd-Referenz (Man-Page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). -##### StrongLoop Process Manager als "systemd"-Service - -Sie können StrongLoop Process Manager problemlos als "systemd"-Service installieren. Dadurch wird beim Serverneustart StrongLoop Process Manager automatisch neu gestartet. Dadurch wiederum werden alle Anwendungen neu gestartet, die von diesem Prozessmanager verwaltet werden. - -So installieren Sie StrongLoop Process Manager als "systemd"-Service: - -
-
-$ sudo sl-pm-install --systemd
-
-
- -Starten Sie dann den Service mit: - -
-
-$ sudo /usr/bin/systemctl start strong-pm
-
-
- -Weitere Informationen hierzu finden Sie im Thema [Produktionshost einrichten (in der StrongLoop-Dokumentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -"Upstart" ist ein Systemtool, das auf vielen Linux-Distributionen verfügbar ist. Mit diesem Tool können Aufgaben (Tasks) und Services beim Systemstart gestartet, beim Herunterfahren gestoppt und auch überwacht werden. Sie können Ihre Express-Anwendung oder einen Prozessmanager als Service konfigurieren. "Upstart" startet diese dann bei einem Absturz automatisch neu. - -Ein "Upstart"-Service wird als Jobkonfigurationsdatei (auch als "Job" bezeichnet) definiert, deren Dateiname mit `.conf` endet. Das folgende Beispiel zeigt, wie ein Job namens "myapp" für eine Anwendung namens "myapp" erstellt wird, wobei sich die Hauptdatei im Verzeichnis `/projects/myapp/index.js` befindet. - -Erstellen Sie eine Datei namens `myapp.conf` unter `/etc/init/` mit dem folgenden Inhalt (ersetzen Sie den Text in Fettdruck durch Werte für Ihr System und Ihre Anwendung): - -
-
-# When to start the process
-start on runlevel [2345]
-
-# When to stop the process
-stop on runlevel [016]
-
-# Increase file descriptor limit to be able to handle more requests
-limit nofile 50000 50000
-
-# Use production mode
-env NODE_ENV=production
-
-# Run as www-data
-setuid www-data
-setgid www-data
-
-# Run from inside the app dir
-chdir /projects/myapp
-
-# The process to start
-exec /usr/local/bin/node /projects/myapp/index.js
-
-# Restart the process if it is down
-respawn
-
-# Limit restart attempt to 10 times within 10 seconds
-respawn limit 10 10
-
-
- -Hinweis: Dieses Script erfordert Upstart 1.4 oder höher mit Unterstützung auf Ubuntu 12.04-14.10. - -Da der Job so konfiguriert ist, dass er beim Systemstart ausgeführt wird, wird Ihre Anwendung zusammen mit dem Betriebssystem gestartet und automatisch neu gestartet, wenn die Anwendung abstürzt oder das System heruntergefahren wird. - -Neben dem automatischen Neustart der Anwendung können Sie mit Upstart die folgenden Befehle verwenden: - -* `start myapp` – Anwendung starten -* `restart myapp` – Anwendung neu starten -* `stop myapp` – Anwendung stoppen - -Weitere Informationen zu "Upstart" siehe [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop Process Manager als "Upstart"-Service - -Sie können StrongLoop Process Manager problemlos als "Upstart"-Service installieren. Dadurch wird beim Serverneustart StrongLoop Process Manager automatisch neu gestartet. Dadurch wiederum werden alle Anwendungen neu gestartet, die von diesem Prozessmanager verwaltet werden. - -So installieren Sie StrongLoop Process Manager als "Upstart 1.4"-Service: - -
-
-$ sudo sl-pm-install
-
-
- -Fühen Sie dann den Service aus mit: - -
-
-$ sudo /sbin/initctl start strong-pm
-
-
+``` -Hinweis: Auf Systemen, die Upstart 1.4 nicht unterstützen, sind die Befehle leicht unterschiedlich. Weitere Informationen hierzu siehe das -Thema [Einrichtung eines Produktionshosts (in der StrongLoop-Dokumentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10). +Weitere Informationen zu "systemd" siehe [systemd-Referenz (Man-Page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). ### Anwendung in einem Cluster ausführen -In einem Multi-Core-System können Sie die Leistung einer Node-Anwendung mehrmals erhöhen, indem Sie einen Cluster von Prozessen starten. Ein Cluster führt mehrere Instanzen der Anwendung aus, idealerweise eine Instanz auf jedem CPU-Core. Dadurch werden die Arbeitslasten und die Tasks auf die Instanzen verteilt. +In einem Multi-Core-System können Sie die Leistung einer Node-Anwendung mehrmals erhöhen, indem Sie einen Cluster von Prozessen starten. Ein Cluster führt mehrere Instanzen der Anwendung aus, idealerweise eine Instanz auf jedem CPU-Core. - +![Balancing between application instances using the cluster API](/images/clustering.png) Wichtig. Da die Anwendungsinstanzen als separate Prozesse ausgeführt werden, nutzen sie nicht dieselbe Hauptspeicherkapazität gemeinsam. Das heißt, Objekte befinden sich für jede Instanz der Anwendung auf lokaler Ebene. Daher kann der Status im Anwendungscode nicht beibehalten werden. Sie können jedoch einen speicherinternen Datenspeicher wie [Redis](http://redis.io/) verwenden, um sitzungsrelevante Daten und Statusinformationen zu speichern. Diese Einschränkung trifft im Wesentlichen auf alle Formen der horizontalen Skalierung zu, unabhängig davon, ob es sich um Clustering mit mehreren Prozessen oder mehreren physischen Servern handelt. @@ -413,45 +259,52 @@ Bei in Gruppen zusammengefassten Anwendungen (geclusterte Anwendungen) können V #### Clustermodule von Node verwenden -Das Clustering erfolgt über das [Clustermodul](https://nodejs.org/docs/latest/api/cluster.html) von Node. Dadurch wird ein Masterprozess eingeleitet, um Verarbeitungsprozesse zu starten und eingehende Verbindungen auf die Verarbeitungsprozesse zu verteilen. Anstatt dieses Modul jedoch direkt zu verwenden, ist es deutlich besser, eines der vielen angebotenen Tools einzusetzen, das diesen Vorgang automatisch für Sie ausführt, wie beispielsweise [node-pm](https://www.npmjs.com/package/node-pm) oder [cluster-service](https://www.npmjs.com/package/cluster-service). +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). Dadurch wird ein Masterprozess eingeleitet, um Verarbeitungsprozesse zu starten und eingehende Verbindungen auf die Verarbeitungsprozesse zu verteilen. -#### StrongLoop Process Manager verwenden +#### Using PM2 -Wenn Sie Ihre Anwendung auf StrongLoop Process Manager (PM) bereitstellen, können Sie die Vorteile des Clustering nutzen, *ohne* Ihren Anwendungscode ändern zu müssen. +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). -Wenn StrongLoop Process Manager (PM) eine Anwendung ausführt, wird diese automatisch in einem Cluster ausgeführt. Die Anzahl der Verarbeitungsprozesse entspricht dabei der Anzahl der CPU-Cores im System. Sie können die Anzahl der Verarbeitungsprozesse manuell im Cluster ändern. Hierfür verwenden Sie das Befehlszeilentool "slc", ohne die Anwendung stoppen zu müssen. +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. -Beispiel: Angenommen, Sie haben Ihre Anwendung auf prod.foo.com bereitgestellt, und StrongLoop PM ist auf Port 8701 (Standardport) empfangsbereit. Dann müssen Sie die Clustergröße mithilfe von "slc" auf "8" einstellen. +To enable cluster mode, start your application like so: -
-
-$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
-
-
+```bash +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ pm2 start npm --name my-app -i max -- start +``` -Weitere Informationen zum Clustering mit StrongLoop PM finden Sie im Thema [Clustering](https://docs.strongloop.com/display/SLC/Clustering) in der StrongLoop-Dokumentation. +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 +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ 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. ### Anforderungsergebnisse im Cache speichern Eine weitere Strategie zur Verbesserung des Leistungsverhaltens in Produktionsumgebungen ist das Speichern von Anforderungergebnissen im Cache. Ihre Anwendung muss also diese Operation nicht wiederholt ausführen, um dieselbe Anforderung wiederholt zu bedienen. -Mithilfe eines Caching-Servers wie [Varnish](https://www.varnish-cache.org/) oder [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (siehe auch [Nginx Caching](https://serversforhackers.com/nginx-caching/)) lassen sich Geschwindigkeit und Leistung Ihrer Anwendung hervorragend verbessern. +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### Load Balancer verwenden -Unabhängig davon, wie gut eine Anwendung optimiert wurde, kann eine Einzelinstanz nur eine begrenzte Arbeitslast oder einen begrenzten Datenverkehr handhaben. Eine Möglichkeit, eine Anwendung zu skalieren, ist die Ausführung mehrerer Instanzen dieser Anwendung und die Verteilung des Datenverkehrs über eine Lastausgleichsfunktion (Load Balancer) vorzunehmen. Die Einrichtung eines solchen Load Balancer kann helfen, Leistung und Geschwindigkeit Ihrer Anwendung zu verbessern. Zudem lässt sich dadurch die Anwendung besser skalieren als mit einer Einzelinstanz. - -Ein Load Balancer ist in der Regel ein Reverse Proxy, der den Datenverkehr zu und von mehreren Anwendungsinstanzen und Servern koordiniert. Sie können ohne großen Aufwand einen Load Balancer für Ihre Anwendung einrichten. Verwenden Sie hierzu [Nginx](http://nginx.org/en/docs/http/load_balancing.html) oder [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). - -Bei einer solchen Lastverteilung müssen Sie sicherstellen, dass Anforderungen, die einer bestimmten Sitzungs-ID zugeordnet sind, mit dem Prozess verbunden sind, von dem sie ursprünglich stammen. Dies wird auch als *Sitzungsaffinität* oder *Affine Sitzungen* bezeichnet und kann durch den obigen Vorschlag, einen Datenspeicher wie Redis für Sitzungsdaten zu verwenden (je nach Anwendung), umgesetzt werden. Eine Beschreibung hierzu siehe [Mehrere Knoten verwenden](http://socket.io/docs/using-multiple-nodes/). +Unabhängig davon, wie gut eine Anwendung optimiert wurde, kann eine Einzelinstanz nur eine begrenzte Arbeitslast oder einen begrenzten Datenverkehr handhaben. Eine Möglichkeit, eine Anwendung zu skalieren, ist die Ausführung mehrerer Instanzen dieser Anwendung und die Verteilung des Datenverkehrs über eine Lastausgleichsfunktion (Load Balancer) vorzunehmen. Die Einrichtung eines solchen Load Balancer kann helfen, Leistung und Geschwindigkeit Ihrer Anwendung zu verbessern. -#### StrongLoop Process Manager mit einem Nginx Load Balancer verwenden +Ein Load Balancer ist in der Regel ein Reverse Proxy, der den Datenverkehr zu und von mehreren Anwendungsinstanzen und Servern koordiniert. 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). -[StrongLoop Process Manager](http://strong-pm.io/) lässt sich in einen Nginx-Controller integrieren und erleichtert dadurch das Konfigurieren von Produktionsumgebungen mit mehreren Hosts. Weitere Informationen finden Sie im Thema zum [Skalieren auf mehrere Server](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (in der StrongLoop-Dokumentation). - +Bei einer solchen Lastverteilung müssen Sie sicherstellen, dass Anforderungen, die einer bestimmten Sitzungs-ID zugeordnet sind, mit dem Prozess verbunden sind, von dem sie ursprünglich stammen. Dies wird auch als _Sitzungsaffinität_ oder _Affine Sitzungen_ bezeichnet und kann durch den obigen Vorschlag, einen Datenspeicher wie Redis für Sitzungsdaten zu verwenden (je nach Anwendung), umgesetzt werden. Eine Beschreibung hierzu siehe [Mehrere Knoten verwenden](https://socket.io/docs/v4/using-multiple-nodes/). ### Reverse Proxy verwenden -Ein Reverse Proxy befindet sich vor einer Webanwendung und führt Unterstützungsoperationen für die Anforderungen aus (außer das Weiterleiten von Anforderungen an die Anwendung). Er kann u. a. Fehlerseiten, Komprimierungen und Caching bearbeiten, Dateien bereitstellen und Lastverteilungen vornehmen. +Ein Reverse Proxy befindet sich vor einer Webanwendung und führt Unterstützungsoperationen für die Anforderungen aus (außer das Weiterleiten von Anforderungen an die Anwendung). Fehlerseiten, Komprimierungen und Caching bearbeiten, Dateien bereitstellen und Lastverteilungen vornehmen. -Durch die Übergabe von Tasks, die keine Kenntnis des Anwendungsstatus erfordern, an einen Reverse Proxy muss Express keine speziellen Anwendungstasks mehr ausführen. Aus diesem Grund wird empfohlen, in Produktionsumgebungen Express hinter einem Reverse Proxy wie [Nginx](https://www.nginx.com/) oder [HAProxy](http://www.haproxy.org/) auszuführen. +Durch die Übergabe von Tasks, die keine Kenntnis des Anwendungsstatus erfordern, an einen Reverse Proxy muss Express keine speziellen Anwendungstasks mehr ausführen. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/de/advanced/best-practice-security.md b/de/advanced/best-practice-security.md old mode 100755 new mode 100644 index 7d6fd4cba5..8f4f23219d --- a/de/advanced/best-practice-security.md +++ b/de/advanced/best-practice-security.md @@ -1,20 +1,46 @@ --- layout: page title: Sicherheitsspezifische Best Practices für Express-Anwendungen in Produktionsumgebungen +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: de +redirect_from: " " --- # Best Practices in Produktionsumgebungen: Sicherheit ## Überblick -Der Begriff *"Produktion"* bezieht sich auf die Phase im Softwarelebenszyklus, in der eine Anwendung oder API für Endbenutzer oder Verbraucher allgemein verfügbar ist. Im Gegensatz dazu wird in der Phase *"Entwicklung"* noch aktiv Code geschrieben und getestet. Die Anwendung ist in dieser Phase noch nicht für externen Zugriff verfügbar. Die entsprechenden Systemumgebungen werden als *Produktionsumgebungen* und *Entwicklungsumgebungen* bezeichnet. +Der Begriff _"Produktion"_ bezieht sich auf die Phase im Softwarelebenszyklus, in der eine Anwendung oder API für Endbenutzer oder Verbraucher allgemein verfügbar ist. Im Gegensatz dazu wird in der Phase _"Entwicklung"_ noch aktiv Code geschrieben und getestet. Die Anwendung ist in dieser Phase noch nicht für externen Zugriff verfügbar. Die entsprechenden Systemumgebungen werden als _Produktionsumgebungen_ und _Entwicklungsumgebungen_ bezeichnet. Entwicklungs- und Produktionsumgebungen werden in der Regel unterschiedlich konfiguriert und weisen deutliche Unterschiede bei den Anforderungen auf. Was in der Entwicklung funktioniert, muss in der Produktion nicht unbedingt akzeptabel sein. Beispiel: In einer Entwicklungsumgebung ist eine ausführliche Protokollierung von Fehlern für Debuggingzwecke sinnvoll. Dieselbe Vorgehensweise kann in einer Produktionsumgebung jedoch zu einem Sicherheitsproblem führen. In einer Entwicklungsumgebung müssen Sie sich keine Gedanken zu Themen wie Skalierbarkeit, Zuverlässigkeit und Leistung machen, während dies in einer Produktionsumgebung kritische Faktoren sind. +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} + In diesem Beitrag werden einige der Best Practices in Bezug auf das Thema Sicherheit für Express-Anwendungen behandelt, die in der Produktionsumgebung bereitgestellt werden. +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - Über [hsts](https://github.com/helmetjs/hsts) werden `Strict-Transport-Security`-Header festgelegt, über die sichere (HTTP over SSL/TLS) Verbindungen zum Server durchgesetzt werden. + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - "Helmet" ist eine Ansammlung von neun kleineren Middlewarefunktionen, über die sicherheitsrelevante HTTP-Header festgelegt werden. + - [Reduce fingerprinting](#reduce-fingerprinting) + - Über [xssFilter](https://github.com/helmetjs/x-xss-protection) werden `X-XSS-Protection`-Header festgelegt, um XSS-Filter (Cross-site Scripting) in den meisten aktuellen Web-Browsern zu aktivieren. + - Über [noCache](https://github.com/helmetjs/nocache) werden `Cache-Control`- und Pragma-Header festgelegt, um clientseitiges Caching zu deaktivieren. + - Über [ieNoOpen](https://github.com/helmetjs/ienoopen) werden `X-Download-Options`-Header für IE8+ festgelegt. + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) + - [Avoid other known vulnerabilities](#avoid-other-known-vulnerabilities) + - [Additional considerations](#additional-considerations) + ## Verwenden Sie keine veralteten oder anfälligen Versionen von Express Express 2.x und 3.x werden nicht mehr gepflegt. Sicherheits- und Leistungsprobleme in diesen Versionen werden nicht mehr behoben. Verwenden Sie diese Versionen nicht! Wenn Sie noch nicht auf Version 4 umgestellt haben, befolgen Sie die Anweisungen im [Migrationshandbuch](/{{ page.lang }}/guide/migrating-4.html). @@ -25,57 +51,121 @@ Stellen Sie außerdem sicher, dass Sie keine anfälligen Express-Versionen verwe Wenn über Ihre Anwendung vertrauliche Daten bearbeitet oder übertragen werden, sollten Sie [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) verwenden, um die Verbindung und die Daten zu schützen. Diese Technologie verschlüsselt Daten, bevor sie vom Client zum Server gesendet werden. Dadurch lassen sich einige gängige (und einfache) Hackerattacken vermeiden. Auch wenn Ajax- und POST-Anforderungen nicht sofort offensichtlich und in Browsern "versteckt" zu sein scheinen, ist deren Netzverkehr anfällig für das [Ausspionieren von Paketen](https://en.wikipedia.org/wiki/Packet_analyzer) und [Man-in-the-Middle-Attacken](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -Möglicherweise sind Sie mit SSL-Verschlüsselung (Secure Socket Layer) bereits vertraut. [TLS ist einfach der nächste Entwicklungsschritt bei SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). In anderen Worten: Wenn Sie bisher SSL verwendet haben, sollten Sie ein Upgrade auf TLS in Erwägung ziehen. Generell empfehlen wir für TLS den Nginx-Server. Eine gute Referenz zum Konfigurieren von TLS auf Nginx (und anderen Servern) ist [Empfohlene Serverkonfigurationen (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). +Möglicherweise sind Sie mit SSL-Verschlüsselung (Secure Socket Layer) bereits vertraut. [TLS ist einfach der nächste Entwicklungsschritt bei SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx). In anderen Worten: Wenn Sie bisher SSL verwendet haben, sollten Sie ein Upgrade auf TLS in Erwägung ziehen. Generell empfehlen wir für TLS den Nginx-Server. Eine gute Referenz zum Konfigurieren von TLS auf Nginx (und anderen Servern) ist [Empfohlene Serverkonfigurationen (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). Ein handliches Tool zum Abrufen eines kostenloses TLS-Zertifikats ist außerdem [Let's Encrypt](https://letsencrypt.org/about/), eine kostenlose, automatisierte und offene Zertifizierungsstelle der [Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/). +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## "Helmet" verwenden [Helmet](https://www.npmjs.com/package/helmet) kann beim Schutz Ihrer Anwendung gegen einige gängige Schwachstellen hilfreiche Dienste leisten, indem die HTTP-Header entsprechend konfiguriert werden. -"Helmet" ist eine Ansammlung von neun kleineren Middlewarefunktionen, über die sicherheitsrelevante HTTP-Header festgelegt werden. +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* Über [csp](https://github.com/helmetjs/csp) wird der `Content-Security-Policy`-Header festgelegt, um Cross-Site Scripting-Attacken und anderen standortübergreifenden Injektionen vorzubeugen. -* Über [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) wird der `X-Powered-By`-Header entfernt. -* Über [hsts](https://github.com/helmetjs/hsts) werden `Strict-Transport-Security`-Header festgelegt, über die sichere (HTTP over SSL/TLS) Verbindungen zum Server durchgesetzt werden. -* Über [ieNoOpen](https://github.com/helmetjs/ienoopen) werden `X-Download-Options`-Header für IE8+ festgelegt. -* Über [noCache](https://github.com/helmetjs/nocache) werden `Cache-Control`- und Pragma-Header festgelegt, um clientseitiges Caching zu deaktivieren. -* Über [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) werden `X-Content-Type-Options`-Header festgelegt, um bei Browsern MIME-Sniffing von Antworten weg vom deklarierten Inhaltstyp (declared content-type) vorzubeugen. -* Über [frameguard](https://github.com/helmetjs/frameguard) wird der `X-Frame-Options`-Header festgelegt, um [Clickjacking](https://www.owasp.org/index.php/Clickjacking)-Schutz zu gewährleisten. -* Über [xssFilter](https://github.com/helmetjs/x-xss-protection) werden `X-XSS-Protection`-Header festgelegt, um XSS-Filter (Cross-site Scripting) in den meisten aktuellen Web-Browsern zu aktivieren. +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. Installieren Sie "Helmet" wie alle anderen Module: -
-
-$ npm install --save helmet
-
-
+```bash +$ npm install helmet +``` So verwenden Sie "Helmet" in Ihrem Code: -
-
-...
-var helmet = require('helmet');
-app.use(helmet());
-...
-
-
+```js +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... +``` -### Deaktivieren Sie mindestens den X-Powered-By-Header +## Reduce fingerprinting -Wenn Sie "Helmet" nicht verwenden wollen, sollten Sie mindestens den `X-Powered-By`-Header deaktivieren. Angreifer können diesen Header (der standardmäßig aktiviert ist) zum Erkennen von Anwendungen mit Express verwenden und dann gezielte Attacken in die Wege leiten. +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. Ein bewährtes Verfahren ist also, diesen Header mit der Methode `app.disable()` zu deaktivieren: -
-
-app.disable('x-powered-by');
-
-
+```js +app.disable('x-powered-by') +``` + +{% capture powered-advisory %} + +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. + +{% endcapture %} + +{% include admonitions/note.html content=powered-advisory %} + +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): -Wenn Sie `helmet.js` verwenden, kümmert sich das Tool darum. +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## Cookies sicher verwenden @@ -83,8 +173,8 @@ Um sicherzustellen, dass Cookies Ihre Anwendung nicht für Angriffsmöglichkeite Es gibt zwei wesentliche Middleware-Cookie-Sitzungsmodule: -* [express-session](https://www.npmjs.com/package/express-session), das in Express 3.x integrierte `express.session`-Middleware ersetzt. -* [cookie-session](https://www.npmjs.com/package/cookie-session), das in Express 3.x integrierte `express.cookieSession`-Middleware ersetzt. +- [express-session](https://www.npmjs.com/package/express-session), das in Express 3.x integrierte `express.session`-Middleware ersetzt. +- [cookie-session](https://www.npmjs.com/package/cookie-session), das in Express 3.x integrierte `express.cookieSession`-Middleware ersetzt. Der Hauptunterschied zwischen diesen beiden Modulen liegt darin, wie die Cookie-Sitzungsdaten gespeichert werden. Die [express-session](https://www.npmjs.com/package/express-session)-Middleware speichert Sitzungsdaten auf dem Server. Sie speichert nur die Sitzungs-ID im Cookie und nicht die Sitzungsdaten. Standardmäßig wird dabei der speicherinterne Speicher verwendet. Eine Verwendung der Middleware in der Produktionsumgebung ist nicht vorgesehen. In der Produktionsumgebung müssen Sie einen skalierbaren "Session-Store" einrichten. Siehe hierzu die Liste der [kompatiblen Session-Stores](https://github.com/expressjs/session#compatible-session-stores). @@ -94,67 +184,98 @@ Im Gegensatz dazu implementiert die [cookie-session](https://www.npmjs.com/packa Die Verwendung des standardmäßigen Namens des Sitzungscookies kann Ihre Anwendung anfällig für Attacken machen. Das mögliche Sicherheitsproblem ist vergleichbar mit `X-Powered-By`: ein potenzieller Angreifer kann diesen Header verwenden, um einen elektronischen Fingerabdruck des Servers zu erstellen und Attacken entsprechend zu platzieren. -Dieses Problem lässt sich vermeiden, wenn Sie allgemeine Cookienamen verwenden; z. B. durch Verwendung der [express-session](https://www.npmjs.com/package/express-session)-Middleware: +Über [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) werden `X-Content-Type-Options`-Header festgelegt, um bei Browsern MIME-Sniffing von Antworten weg vom deklarierten Inhaltstyp (declared content-type) vorzubeugen. -
-
-var session = require('express-session');
+```js
+const session = require('express-session')
 app.set('trust proxy', 1) // trust first proxy
-app.use( session({
-   secret : 's3Cur3',
-   name : 'sessionId',
-  })
-);
-
-
+app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) +``` ### Cookie-Sicherheitsoptionen festlegen Legen Sie die folgenden Cookieoptionen fest, um die Sicherheit zu erhöhen: -* `secure` - Stellt sicher, dass der Browser das Cookie nur über HTTPS sendet. -* `httpOnly` - Stellt sicher, dass das Cookie nur über HTTP(S) und nicht über das Client-JavaScript gesendet wird und dadurch Schutz gegen Cross-Site Scripting-Attacken besteht. -* `domain` - Gibt die Domäne des Cookies an, die für den Vergleich mit der Domäne des Servers verwendet wird, in der die URL angefordert wird. Stimmen diese beiden überein, müssen Sie das Pfadattribut überprüfen. -* `path` - Gibt den Pfad des Cookies an, der für den Vergleich mit dem Anforderungspfad verwendet wird. Wenn dieser Pfad und die Domäne übereinstimmen, können Sie das Cookie in der Anforderung senden. -* `expires` - Wird verwendet, um das Ablaufdatum für persistente Cookies festzulegen. +- `secure` - Stellt sicher, dass der Browser das Cookie nur über HTTPS sendet. +- `httpOnly` - Stellt sicher, dass das Cookie nur über HTTP(S) und nicht über das Client-JavaScript gesendet wird und dadurch Schutz gegen Cross-Site Scripting-Attacken besteht. +- `domain` - Gibt die Domäne des Cookies an, die für den Vergleich mit der Domäne des Servers verwendet wird, in der die URL angefordert wird. Stimmen diese beiden überein, müssen Sie das Pfadattribut überprüfen. +- `path` - Gibt den Pfad des Cookies an, der für den Vergleich mit dem Anforderungspfad verwendet wird. Wenn dieser Pfad und die Domäne übereinstimmen, können Sie das Cookie in der Anforderung senden. +- `expires` - Wird verwendet, um das Ablaufdatum für persistente Cookies festzulegen. Dies ist ein Beispiel zur Verwendung der [cookie-session](https://www.npmjs.com/package/cookie-session)-Middleware: -
-
-var session = require('cookie-session');
-var express = require('express');
-var app = express();
+```js
+const session = require('cookie-session')
+const express = require('express')
+const app = express()
 
-var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
+const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
 app.use(session({
   name: 'session',
   keys: ['key1', 'key2'],
-  cookie: { secure: true,
-            httpOnly: true,
-            domain: 'example.com',
-            path: 'foo/bar',
-            expires: expiryDate
-          }
-  })
-);
-
-
+ cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) +``` -## Weitere Überlegungen +## Prevent brute-force attacks against authorization + +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +1. The number of consecutive failed attempts by the same user name and IP address. +2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) + +## Ensure your dependencies are secure + +Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. -Dies sind einige weitere Empfehlungen aus der hervorragenden [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). In diesem Blogbeitrag finden Sie alle Details zu diesen Empfehlungen: +Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. -* Implementieren Sie Rate-Limiting, um Brute-Force-Attacken gegen Authentifizierungen zu verhindern. Hierfür können Sie beispielsweise das [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) verwenden, um eine Rate-Limiting-Richtlinie durchzusetzen. Alternativ können Sie eine Middleware wie [express-limiter](https://www.npmjs.com/package/express-limiter) verwenden. Hierzu müssen Sie jedoch Ihren Code etwas modifizieren. -* Verwenden Sie die [csurf](https://www.npmjs.com/package/csurf)-Middleware, um CSRF-Attacken (Cross-Site Request Forgery) vorzubeugen. -* Filtern und bereinigen Sie immer Benutzereingaben, um sich gegen XS-Angriffe (Cross-Site Scripting) und Befehlsinjektionsattacken zu schützen. -* Implementieren Sie Verteidungsmaßnahmen gegen SQL-Injection-Attacken, indem sie parametrisierte Abfragen oder vorbereitete Anweisungen einsetzen. -* Nutzen Sie das Open-Source-Tool [sqlmap](http://sqlmap.org/), um SQL-Injection-Schwachstellen in Ihrer Anwendung zu erkennen. -* Verwenden Sie die Tools [nmap](https://nmap.org/) und [sslyze](https://github.com/nabla-c0d3/sslyze), um die Konfiguration Ihrer SSL-Verschlüsselungen, -Schlüssel und Neuvereinbarungen sowie die Gültigkeit Ihres Zertifikats zu testen. -* Verwenden Sie [safe-regex](https://www.npmjs.com/package/safe-regex), um sicherzustellen, dass Ihre regulären Ausdrücke nicht für [Denial-of-Service-Attacken](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) anfällig sind. +```bash +$ npm audit +``` -## Vermeiden Sie andere Schwachstellen +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: + +```bash +$ npm install -g snyk +$ cd your-app +``` + +Use this command to test your application for vulnerabilities: + +```bash +$ snyk test +``` + +### Vermeiden Sie andere Schwachstellen Achten Sie auf [Node Security Project](https://npmjs.com/advisories)-Empfehlungen, die Express oder andere Module, die Ihre Anwendung nutzt, beeinträchtigen können. Im Allgemeinen ist Node Security Project aber eine exzellente Ressource mit Wissen und Tools zur Sicherheit von Node. -Letztendlich können Express-Anwendungen – wie viele andere Webanwendungen auch – anfällig für eine Vielzahl webbasierter Attacken sein. Machen Sie sich deshalb mit bekannten [webspezifischen Schwachstellen](https://www.owasp.org/index.php/Top_10_2013-Top_10) vertraut und treffen Sie die geeigneten Vorkehrungen, um diese zu vermeiden. +Letztendlich können Express-Anwendungen – wie viele andere Webanwendungen auch – anfällig für eine Vielzahl webbasierter Attacken sein. Machen Sie sich deshalb mit bekannten [webspezifischen Schwachstellen](https://www.owasp.org/www-project-top-ten/) vertraut und treffen Sie die geeigneten Vorkehrungen, um diese zu vermeiden. + +## Weitere Überlegungen + +Dies sind einige weitere Empfehlungen aus der hervorragenden [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). In diesem Blogbeitrag finden Sie alle Details zu diesen Empfehlungen: + +- Filtern und bereinigen Sie immer Benutzereingaben, um sich gegen XS-Angriffe (Cross-Site Scripting) und Befehlsinjektionsattacken zu schützen. +- Implementieren Sie Verteidungsmaßnahmen gegen SQL-Injection-Attacken, indem sie parametrisierte Abfragen oder vorbereitete Anweisungen einsetzen. +- Nutzen Sie das Open-Source-Tool [sqlmap](http://sqlmap.org/), um SQL-Injection-Schwachstellen in Ihrer Anwendung zu erkennen. +- Verwenden Sie die Tools [nmap](https://nmap.org/) und [sslyze](https://github.com/nabla-c0d3/sslyze), um die Konfiguration Ihrer SSL-Verschlüsselungen, -Schlüssel und Neuvereinbarungen sowie die Gültigkeit Ihres Zertifikats zu testen. +- Verwenden Sie [safe-regex](https://www.npmjs.com/package/safe-regex), um sicherzustellen, dass Ihre regulären Ausdrücke nicht für [Denial-of-Service-Attacken](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) anfällig sind. + +[helmet]: \ No newline at end of file diff --git a/de/advanced/developing-template-engines.md b/de/advanced/developing-template-engines.md old mode 100755 new mode 100644 index 3e79176f7e..5832050244 --- a/de/advanced/developing-template-engines.md +++ b/de/advanced/developing-template-engines.md @@ -1,8 +1,9 @@ --- layout: page title: Template-Engines für Express entwickeln +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: de +redirect_from: " " --- # Template-Engines für Express entwickeln @@ -11,37 +12,35 @@ Verwenden Sie die Methode `app.engine(ext, callback)`, um Ihre eigene Template-E Der folgende Code ist ein Beispiel für die Implementierung einer sehr einfachen Template-Engine für die Ausgabe von `.ntl`-Dateien. -
-
-var fs = require('fs'); // this engine requires the fs module
-app.engine('ntl', function (filePath, options, callback) { // define the template engine
-  fs.readFile(filePath, function (err, content) {
-    if (err) return callback(new Error(err));
+```js
+const fs = require('fs') // this engine requires the fs module
+app.engine('ntl', (filePath, options, callback) => { // define the template engine
+  fs.readFile(filePath, (err, content) => {
+    if (err) return callback(err)
     // this is an extremely simple template engine
-    var rendered = content.toString().replace('#title#', ''+ options.title +'')
-    .replace('#message#', '

'+ options.message +'

'); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
-
+ const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

${options.message}

`) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine +``` Ihre Anwendung ist jetzt in der Lage, `.ntl`-Dateien auszugeben. Erstellen Sie im Verzeichnis `views` eine Datei namens `index.ntl` mit dem folgenden Inhalt. -
-
+```pug
 #title#
 #message#
-
-
+``` + Erstellen Sie dann in Ihrer Anwendung die folgende Route. -
-
-app.get('/', function (req, res) {
-  res.render('index', { title: 'Hey', message: 'Hello there!'});
-});
-
-
-Wenn Sie eine Anforderung zur Homepage einleiten, wird `index.ntl` im HTML-Format ausgegeben. + +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` + +Wenn Sie eine Anforderung zur Homepage einleiten, wird `index.ntl` im HTML-Format ausgegeben. \ No newline at end of file diff --git a/de/advanced/healthcheck-graceful-shutdown.md b/de/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..c1da62bfca --- /dev/null +++ b/de/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/de/advanced/pm.md b/de/advanced/pm.md deleted file mode 100755 index c59e40eb87..0000000000 --- a/de/advanced/pm.md +++ /dev/null @@ -1,282 +0,0 @@ ---- -layout: page -title: Prozessmanager für Express-Anwendungen -menu: advanced -lang: de ---- - -# Prozessmanager für Express-Anwendungen - -Wenn Sie Express-Anwendungen für Produktionsumgebungen ausführen, ist der Einsatz eines *Prozessmanagers* hilfreich, um folgende Aufgaben (Tasks) auszuführen: - -- Automatischer Neustart der Anwendung nach einem Absturz -- Einblicke in die Laufzeitleistung und die Ressourcennutzung -- Dynamische Änderung der Einstellungen zur Verbesserung des Leistungsverhaltens -- Steuerung des Clustering - -Ein Prozessmanager ist vergleichbar mit einem Anwendungsserver: er ist ein "Container" für Anwendungen, der die Bereitstellung erleichtert, eine hohe Verfügbarkeit sicherstellt und die Verwaltung der Anwendung zur Laufzeit ermöglicht. - -Die gängigsten Prozessmanager für Express- und andere Node.js-Anwendungen sind: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -Der Einsatz eines dieser drei Tools kann sehr hilfreich sein. StrongLoop Process Manager ist jedoch das einzige Tool, dass eine umfassende Laufzeit- und Bereitstellungslösung bietet, die den gesamten Node.js-Anwendungslebenszyklus abdeckt. Für jeden Schritt vor und nach der Produktion steht über eine einheitliche Schnittstelle ein Tool zur Verfügung. - -Nachfolgend finden Sie einen Kurzbeschreibung zu jedem dieser Tools. -Einen ausführlichen Vergleich der Tools finden Sie unter [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) ist ein Prozessmanager für Node.js-Anwendungen in Produktionsumgebungen. StrongLoop PM verfügt über integrierte Funktionen für Lastverteilung, Überwachung und Bereitstellung auf mehreren Hosts sowie eine grafische Konsole. Mit StrongLoop PM lassen sich die folgenden Aufgaben (Tasks) ausführen: - -- Erstellen, Packen und Bereitstellen Ihrer Node.js-Anwendung auf einem lokalen oder fernen System -- Anzeige von CPU-Profilen und Heapspeichermomentaufnahmen (Heap-Snapshots) zur Optimierung der Leistung und Diagnose von Speicherlecks -- Herstellen der dauerhaften Betriebsbereitschaft von Prozessen und Clustern -- Anzeige von Leistungsmessdaten für Ihre Anwendung -- Einfache Verwaltung von Bereitstellungen auf mehreren Hosts inkl. Nginx-Integration -- Vereinheitlichung mehrerer StrongLoop PMs auf einer über Arc verwalteten verteilten Microservices-Laufzeitumgebung - -StrongLoop PM kann über ein leistungsfähiges Befehlszeilen-Schnittstellentool namens `slc` oder das grafisch orientierte Tool Arc genutzt werden. Arc ist ein Open-Source-Tool, das von StrongLoop kompetent unterstützt wird. - -Weitere Informationen siehe [http://strong-pm.io/](http://strong-pm.io/). - -Vollständige Dokumentation - -- [Node-Anwendungen im Betrieb (in der StrongLoop-Dokumentation)](http://docs.strongloop.com/display/SLC) -- [StrongLoop Process Manager verwenden](http://docs.strongloop.com/display/SLC/Using+Process+Manager) - -### Installation -
-
-$ [sudo] npm install -g strongloop
-
-
- -### Grundlegende Verwendung -
-
-$ cd my-app
-$ slc start
-
-
- -Anzeigen des Status von Process Manager und allen bereitgestellten Anwendungen: - -
-
-$ slc ctl
-Service ID: 1
-Service Name: my-app
-Environment variables:
-  No environment variables defined
-Instances:
-    Version  Agent version  Cluster size
-     4.1.13      1.5.14           4
-Processes:
-        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
-    1.1.57692  57692   0
-    1.1.57693  57693   1     0.0.0.0:3001
-    1.1.57694  57694   2     0.0.0.0:3001
-    1.1.57695  57695   3     0.0.0.0:3001
-    1.1.57696  57696   4     0.0.0.0:3001
-
-
- -Auflisten aller verwalteten Anwendungen (Services): - -
-
-$ slc ctl ls
-Id          Name         Scale
- 1          my-app       1
-
-
- -Stoppen einer Anwendung: - -
-
-$ slc ctl stop my-app
-
-
- -Neustart einer Anwendung: - -
-
-$ slc ctl restart my-app
-
-
- -Sie können auch einen "Soft Restart" durchführen, damit die Verarbeitungsprozesse eine Karenzzeit zum Schließen bestehender Verbindungen erhalten. Dann kann die aktuelle Anwendung neu gestartet werden: - -
-
-$ slc ctl soft-restart my-app
-
-
- -Entfernen einer Anwendung aus dem Verwaltungsprozess: - -
-
-$ slc ctl remove my-app
-
-
- -## PM2 - -PM2 ist ein Prozessmanager für Node.js-Anwendungen in Produktionsumgebungen, der über eine integrierte Lastausgleichsfunktion verfügt. Mit PM2 lässt sich die dauerhafte Betriebsbereitschaft von Anwendungen sicherstellen. So können die Anwendungen ohne Ausfallzeiten erneut geladen werden, wodurch die Ausführung allgemeiner Systemverwaltungsaufgaben erleichtert wird. Über PM2 können auch Protokollierung, Überwachung und Clustering von Anwendungen vorgenommen werden. - -Weitere Informationen siehe [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Installation - -
-
-$ [sudo] npm install pm2 -g
-
-
- -### Grundlegende Verwendung - -Wenn Sie eine Anwendung mit dem Befehl `pm2` starten, müssen Sie den Pfad zur Anwendung angeben. Wenn Sie eine Anwendung jedoch stoppen, neu starten oder löschen, können Sie auch nur den Namen oder die ID der Anwendung angeben. - -
-
-$ pm2 start npm --name my-app -- start
-[PM2] restartProcessId process id 0
-┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
-│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
-├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
-│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
-└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
- Use the `pm2 show ` command to get more details about an app.
-
-
- -Wenn Sie eine Anwendung mit dem Befehl `pm2` starten, wird die Anwendung sofort in den Hintergrund gestellt. Sie können diese im Hintergrund laufende Anwendung über die Befehlszeile mit verschiedenen `pm2`-Befehlen steuern. - -nach dem Starten einer Anwendung mit dem Befehl `pm2` wird diese in der PM2-Prozessliste mit einer ID registriert. Sie können also Anwendungen mit demselben Namen aus verschiedenen Verzeichnissen auf dem System über deren ID verwalten. - -Beachten Sie Folgendes: Wenn mehrere Anwendungen mit demselben Namen ausgeführt werden, gelten die `pm2`-Befehle für alle Anwendungen. Verwenden Sie daher für das Verwalten einzelner Anwendungen IDs anstelle von Namen. - -Erstellen einer Liste aller aktiven Prozesse: - -
-
-$ pm2 list
-
-
- -Stoppen einer Anwendung: - -
-
-$ pm2 stop 0
-
-
- -Neustart einer Anwendung: - -
-
-$ pm2 restart 0
-
-
- -Anzeige detaillierter Informationen zu einer Anwendung: - -
-
-$ pm2 show 0
-
-
- -Entfernen einer Anwendung aus dem PM2-Register: - -
-
-$ pm2 delete 0
-
-
- - -## Forever - -Forever ist ein einfaches Befehlszeilen-Schnittstellentool, mit dem sichergestellt wird, dass ein Script kontinuierlich ausgeführt wird. Die einfache Benutzerschnittstelle von Forever eignet sich ideal für einfachere Bereitstellungen von Node.js-Anwendungen und Scripts. - -Weitere Informationen siehe [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Installation - -
-
-$ [sudo] npm install forever -g
-
-
- -### Grundlegende Verwendung - -Verwenden Sie zum Starten eines Scripts den Befehl `forever start` und geben Sie den Pfad zum Script an: - -
-
-$ forever start script.js
-
-
- -Dieser Befehl führt das Script im Dämonmodus (im Hintergrund) aus. - -Wenn Sie das Script so ausführen wollen, dass es an das Terminal angehängt wird, müssen Sie `start` weglassen: - -
-
-$ forever script.js
-
-
- -Es ist sinnvoll, Ausgaben des Forever-Tools und des Scripts mit den Protokollierungsoptionen `-l`, `-o` und `-e` zu protokollieren (wie in diesem Beispiel gezeigt): - -
-
-$ forever start -l forever.log -o out.log -e err.log script.js
-
-
- -Anzeigen der Liste mit Scripts, die über Forever gestartet wurden: - -
-
-$ forever list
-
-
- -Stoppen eines Scripts, das über Forever gestartet wurde. Verwenden Sie hierzu den Befehl `forever stop` und geben Sie den Prozessindex an (der über den Befehl `forever list` erstellt wird). - -
-
-$ forever stop 1
-
-
- -Geben Sie alternativ den Pfad zur Datei an: - -
-
-$ forever stop script.js
-
-
- -Stoppen aller Scripts, die über Forever gestartet wurden: - -
-
-$ forever stopall
-
-
- -Forever verfügt über eine Vielzahl von Optionen sowie eine programmgesteuerte API. diff --git a/de/advanced/security-updates.md b/de/advanced/security-updates.md old mode 100755 new mode 100644 index d63be11648..e882a9af54 --- a/de/advanced/security-updates.md +++ b/de/advanced/security-updates.md @@ -1,44 +1,87 @@ --- layout: page title: Express-Sicherheitsupdates +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: de +redirect_from: " " --- # Sicherheitsupdates
-Schwachstellen bei Node.js wirken sich direkt auf Express aus. Daher sollten Sie [ein Auge auf Schwachstellen bei Node.js haben](http://blog.nodejs.org/vulnerability/) und sicherstellen, dass Sie die aktuelle stabile Version von Node.js haben. +Schwachstellen bei Node.js wirken sich direkt auf Express aus. Daher sollten Sie [ein Auge auf Schwachstellen bei Node.js haben](https://nodejs.org +/en/blog/vulnerability/) und sicherstellen, dass Sie die aktuelle stabile Version von Node.js haben.
Die folgende Liste enthält die Express-Schwachstellen, die im angegebenen Versionsupdate behoben wurden. +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} + ## 4.x - * 4.11.1 - * Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben. - * 4.10.7 - * Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben. - * 4.8.8 - * Schwachstellen durch Directory-Traversal-Technik in `express.static` ([Empfehlung](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)) behoben. - * 4.8.4 - * Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten. - * 4.8.0 - * Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt. - * Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet. +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. + - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. +- 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +- 4.15.2 + - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben. +- 4.10.7 + - Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben. +- 4.8.8 + - Schwachstellen durch Directory-Traversal-Technik in `express.static` ([Empfehlung](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)) behoben. +- 4.8.4 + - Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten. +- 4.8.0 + - Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt. + - Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet. ## 3.x - * 3.19.1 - * Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben. - * 3.19.0 - * Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben. - * 3.16.10 - * Schwachstellen durch Directory-Traversal-Technik in `express.static` behoben. - * 3.16.6 - * Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten. - * 3.16.0 - * Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt. - * Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet. - * 3.3.0 - * Die Antwort 404 bei einem nicht unterstützten Überschreibungsversuch war anfällig gegen Cross-Site Scripting-Attacken. +
+ **Express 3.x WIRD NICHT MEHR GEWARTET** + +Bekannte und unbekannte Probleme bei Sicherheit und Leistung in 3.x wurden seit dem letzten Update (1. August 2015) noch nicht behoben. Es wird dringend empfohlen, die aktuelle Version von Express zu verwenden. + +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). + +
+ +- 3.19.1 + - Offenlegungsgefahr beim Rootpfad in `express.static`, `res.sendfile` und `res.sendFile` behoben. +- 3.19.0 + - Offene Umadressierungsschwachstelle in `express.static` ([Empfehlung](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) behoben. +- 3.16.10 + - Schwachstellen durch Directory-Traversal-Technik in `express.static` behoben. +- 3.16.6 + - Node.js 0.10 kann in bestimmten Situationen Lecks bei `fd` aufweisen, die sich auf `express.static` und `res.sendfile` auswirken. Böswillige Anforderungen können zu Lecks bei `fd` führen und letztendlich `EMFILE`-Fehler nach sich ziehen und bewirken, dass Server nicht antworten. +- 3.16.0 + - Sparse-Arrays mit extrem hohen Indizes in der Abfragezeichenfolge können bewirken, dass für die Prozessausführung nicht genügend Arbeitsspeicher zur Verfügung steht und es zu einem Serverabsturz kommt. + - Extrem verschachtelte Abfragezeichenfolgenobjekte können bewirken, dass der Prozess blockiert und der Server dadurch vorübergehend nicht antwortet. +- 3.3.0 + - Die Antwort 404 bei einem nicht unterstützten Überschreibungsversuch war anfällig gegen Cross-Site Scripting-Attacken. \ No newline at end of file diff --git a/de/api.md b/de/api.md old mode 100755 new mode 100644 index fc5a006732..815162cbec --- a/de/api.md +++ b/de/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - API-Referenz -lang: de +layout: api +version: 5x +title: Express 5.x - API-Referenz +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api +redirect_from: " " --- -
- -

4.x-API

- - - {% include api/en/4x/express.md %} +
+

5.x API

+ {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
diff --git a/de/changelog/index.md b/de/changelog/index.md new file mode 100644 index 0000000000..2456265b18 --- /dev/null +++ b/de/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
+ +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
    +
  • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
    +
  • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
    +
  • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
    +
  • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
  • + +
  • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
  • + +
  • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
  • + +
  • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
  • + +
  • + Starting with this version, Express supports Node.js 18.x. +
  • + +
  • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
  • + +
  • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
  • + +
  • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
  • + +
  • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
  • + +
  • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
  • + +
  • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
    +
  • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
    +
  • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
  • + +
  • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
  • + +
  • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
  • + +
  • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
  • + +
  • + Starting with this version, Express supports Node.js 14.x. +
  • + +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
    +
  • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
    +
  • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
  • + +
  • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
  • + +
  • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
  • + +
  • + Starting with this version, Express supports Node.js 10.x and 12.x. +
  • + +
  • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
  • + +
  • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
    +
  • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
    +
  • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
  • + +
  • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
  • + +
  • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
    +
  • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
    +
  • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
    +
  • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
  • + +
  • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
  • + +
  • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
  • + +
  • + Starting with this version, Express supports Node.js 8.x. +
  • + +
  • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
  • + +
  • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
  • + +
  • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
  • + +
  • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
  • + +
  • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
    +
  • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
  • + +
  • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
  • + +
  • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
    +
  • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
    +
  • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
  • + +
  • + Fix error when `res.set` cannot add charset to `Content-Type`. +
  • + +
  • + Fix missing `` in HTML document. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
    +
  • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
    +
  • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
    +
  • + Starting with this version, Express supports Node.js 7.x. +
  • + +
  • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
  • + +
  • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
  • + +
  • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
    +
  • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
    +
  • + Starting with this version, Express supports Node.js 6.x. +
  • + +
  • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
  • + +
  • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
  • + +
  • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
  • + +
  • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
  • + +
  • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
  • + +
  • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
  • + +
  • + IP address resolution with proxies has been greatly improved. +
  • + +
  • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
  • +
+ +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
diff --git a/de/guide/behind-proxies.md b/de/guide/behind-proxies.md old mode 100755 new mode 100644 index 581aaca165..6dab4f9521 --- a/de/guide/behind-proxies.md +++ b/de/guide/behind-proxies.md @@ -1,73 +1,88 @@ --- layout: page title: Express hinter Proxys +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: de +redirect_from: " " --- # Express hinter Proxys -Bei der Ausführung einer Express-Anwendung hinter einem Proxy legen Sie die Anwendungsvariable `trust proxy` (mithilfe von [app.set()](/{{ page.lang }}/4x/api.html#app.set)) auf einen der in der folgenden Tabelle enthaltenen Werte fest: +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
-Auch wenn die Anwendungsausführung nicht fehlschlägt, wenn die Anwendungsvariable `trust proxy` nicht festgelegt wurde, wird die IP-Adresse des Proxys nicht ordnungsgemäß als Client-IP-Adresse eingetragen, es sei denn, `trust proxy` wurde konfiguriert. +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
+Bei der Ausführung einer Express-Anwendung hinter einem Proxy legen Sie die Anwendungsvariable `trust proxy` (mithilfe von [app.set()](/{{ page.lang }}/4x/api.html#app.set)) auf einen der in der folgenden Tabelle enthaltenen Werte fest: + - - + - +
TypWert
Boolesch -Wenn `true` angegeben wird, wird die IP-Adresse des Clients als der äußerst rechte Eintrag im Header `X-Forwarded-*` interpretiert. +Wenn `true` angegeben wird, wird die IP-Adresse des Clients als der äußerst rechte Eintrag im Header `X-Forwarded-*` interpretiert. + Wenn `false` angegeben wird, wird die Anwendung als direkte Verbindung zum Internet gesehen. Die IP-Adresse des Clients wird dann von `req.connection.remoteAddress` abgeleitet. Dies ist die Standardeinstellung. + +
+When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
IP-AdressenIP addresses -Eine einzelne IP-Adresse, ein Teilnetz oder ein Array von IP-Adressen und Teilnetzen, denen vertraut werden kann. Die folgende Liste zeigt die vorkonfigurierten Teilnetznamen: -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`. +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: + +- loopback - `127.0.0.1/8`, `::1/128` +- linklocal - `169.254.0.0/16`, `fe80::/10` +- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` Sie können IP-Adressen wie folgt festlegen: -
-app.set('trust proxy', 'loopback') // specify a single subnet
+```js
+app.set('trust proxy', 'loopback') // specify a single subnet
 app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
 app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
-app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
-
+app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` + +Sobald die Werte angegeben wurden, werden die betreffenden IP-Adressen und Teilnetze aus dem Adressfeststellungsprozess ausgeschlossen. Die nicht vertrauenswürdige IP-Adresse, die am nächsten zum Anwendungsserver liegt, wird als IP-Adresse des Clients festgelegt. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. -Sobald die Werte angegeben wurden, werden die betreffenden IP-Adressen und Teilnetze aus dem Adressfeststellungsprozess ausgeschlossen. Die nicht vertrauenswürdige IP-Adresse, die am nächsten zum Anwendungsserver liegt, wird als IP-Adresse des Clients festgelegt.
Zahl -Dem `n`-ten Hop vom Proxy-Server soll als Client vertraut werden. +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. + +
+When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
FunktionFunction -Individuell angepasste, vertrauenswürdige Implementierung. Dies sollten Sie nur verwenden, wenn Sie genau wissen, was Sie tun.
-app.set('trust proxy', function (ip) {
-  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
-  else return false;
-});
-
+Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
-Die Festlegung eines anderen `trust proxy`-Werts als `false` resultiert in drei wichtigen Änderungen: +Enabling `trust proxy` will have the following impact:
    -
  • Der Wert für [req.hostname](/{{ page.lang }}/api.html#req.hostname) wird vom Wert abgeleitet, der im Header `X-Forwarded-Host` festgelegt wurde. Dieser Wert kann vom Client oder Proxy festgelegt werden. -
  • +
  • Der Wert für [req.hostname](/{{ page.lang }}/api.html#req.hostname) wird vom Wert abgeleitet, der im Header `X-Forwarded-Host` festgelegt wurde. Dieser Wert kann vom Client oder Proxy festgelegt werden.
  • `X-Forwarded-Proto` kann vom Reverse Proxy festgelegt werden, um der Anwendung mitzuteilen, ob es sich um `https` oder `http` oder sogar um einen ungültigen Namen handelt. Dieser Wert wird durch [req.protocol](/{{ page.lang }}/api.html#req.protocol) abgebildet.
  • Als Werte für [req.ip](/{{ page.lang }}/api.html#req.ip) und [req.ips](/{{ page.lang }}/api.html#req.ips) wird die Liste der Adressen aus `X-Forwarded-For` herangezogen. diff --git a/de/guide/database-integration.md b/de/guide/database-integration.md old mode 100755 new mode 100644 index 1a43023cc4..3b20abc348 --- a/de/guide/database-integration.md +++ b/de/guide/database-integration.md @@ -1,225 +1,266 @@ --- layout: page title: Datenbankintegration in Express +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: de +redirect_from: " " --- # Datenbankintegration Die Herstellung einer Verbindung zwischen Datenbanken und Express-Anwendungen erfolgt einfach durch Laden eines geeigneten Node.js-Treibers für die Datenbank in Ihre Anwendung. In diesem Dokument wird in Kurzform beschrieben, wie einige der gängigsten Node.js-Module für Datenbanksysteme Ihrer Express-Anwendung hinzugefügt und verwendet werden: -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongo) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgres) +- [Redis](#redis) +- +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
    Diese Datenbanktreiber sind neben zahlreichen anderen Treibern verfügbar. Weitere Optionen finden Sie auf der [npm](https://www.npmjs.com/)-Site.
    - - ## Cassandra **Modul**: [cassandra-driver](https://github.com/datastax/nodejs-driver) **Installation** -
    -
    +### Installation
    +
    +```bash
     $ npm install cassandra-driver
    -
    -
    +``` -**Beispiel** +### Beispiel -
    -
    -var cassandra = require('cassandra-driver');
    -var client = new cassandra.Client({ contactPoints: ['localhost']});
    +```js
    +const cassandra = require('cassandra-driver')
    +const client = new cassandra.Client({ contactPoints: ['localhost'] })
    +
    +client.execute('select key from system.local', (err, result) => {
    +  if (err) throw err
    +  console.log(result.rows[0])
    +})
    +```
     
    -client.execute('select key from system.local', function(err, result) {
    -  if (err) throw err;
    -  console.log(result.rows[0]);
    -});
    -
    -
    +## Couchbase - +**Module**: [couchnode](https://github.com/couchbase/couchnode) + +### Installation + +```bash +$ npm install couchbase +``` + +### Beispiel + +```js +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') + +// add a document to a bucket +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) + +// get all documents with shoe size 13 +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) +``` ## CouchDB **Modul**: [nano](https://github.com/dscape/nano) **Installation** -
    -
    +### Installation
    +
    +```bash
     $ npm install nano
    -
    -
    +``` -**Beispiel** +### Beispiel -
    -
    -var nano = require('nano')('http://localhost:5984');
    -nano.db.create('books');
    -var books = nano.db.use('books');
    +```js
    +const nano = require('nano')('http://localhost:5984')
    +nano.db.create('books')
    +const books = nano.db.use('books')
     
    -//Insert a book document in the books database
    -books.insert({name: 'The Art of war'}, null, function(err, body) {
    -  if (!err){
    -    console.log(body);
    +// Insert a book document in the books database
    +books.insert({ name: 'The Art of war' }, null, (err, body) => {
    +  if (err) {
    +    console.log(err)
    +  } else {
    +    console.log(body)
       }
    -});
    +})
     
    -//Get a list of all books
    -books.list(function(err, body){
    -  console.log(body.rows);
    -});
    -
    -
    - - +// Get a list of all books +books.list((err, body) => { + if (err) { + console.log(err) + } else { + console.log(body.rows) + } +}) +``` ## LevelDB **Modul**: [levelup](https://github.com/rvagg/node-levelup) **Installation** -
    -
    -$ npm install level levelup leveldown
    -
    -
    +### Installation -**Beispiel** +```bash +$ npm install level levelup leveldown +``` -
    -
    -var levelup = require('levelup');
    -var db = levelup('./mydb');
    +### Beispiel
     
    -db.put('name', 'LevelUP', function (err) {
    +```js
    +const levelup = require('levelup')
    +const db = levelup('./mydb')
     
    -  if (err) return console.log('Ooops!', err);
    -  db.get('name', function (err, value) {
    -    if (err) return console.log('Ooops!', err);
    -    console.log('name=' + value);
    -  });
    +db.put('name', 'LevelUP', (err) => {
    +  if (err) return console.log('Ooops!', err)
     
    -});
    -
    -
    + db.get('name', (err, value) => { + if (err) return console.log('Ooops!', err) - + console.log(`name=${value}`) + }) +}) +``` ## MySQL **Modul**: [mysql](https://github.com/felixge/node-mysql/) **Installation** -
    -
    +### Installation
    +
    +```bash
     $ npm install mysql
    -
    -
    +``` -**Beispiel** +### Beispiel -
    -
    -var mysql      = require('mysql');
    -var connection = mysql.createConnection({
    -  host     : 'localhost',
    -  user     : 'dbuser',
    -  password : 's3kreee7'
    -});
    +```js
    +const mysql = require('mysql')
    +const connection = mysql.createConnection({
    +  host: 'localhost',
    +  user: 'dbuser',
    +  password: 's3kreee7',
    +  database: 'my_db'
    +})
     
    -connection.connect();
    +connection.connect()
     
    -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
    -  if (err) throw err;
    -  console.log('The solution is: ', rows[0].solution);
    -});
    +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
    +  if (err) throw err
     
    -connection.end();
    -
    -
    + console.log('The solution is: ', rows[0].solution) +}) - +connection.end() +``` ## MongoDB **Modul**: [mongodb](https://github.com/mongodb/node-mongodb-native) **Installation** -
    -
    +### Installation
    +
    +```bash
     $ npm install mongodb
    -
    -
    +``` -**Beispiel** +### Example (v2.\*) -
    -
    -var MongoClient = require('mongodb').MongoClient;
    +```js
    +const MongoClient = require('mongodb').MongoClient
     
    -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
    -  if (err) {
    -    throw err;
    -  }
    -  db.collection('mammals').find().toArray(function(err, result) {
    -    if (err) {
    -      throw err;
    -    }
    -    console.log(result);
    -  });
    -});
    -
    -
    +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { + if (err) throw err -Wenn Sie nach einem Objektmodelltreiber für MongoDB suchen, schauen Sie unter [Mongoose](https://github.com/LearnBoost/mongoose) nach. + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +### Example (v3.\*) - +```js +const MongoClient = require('mongodb').MongoClient + +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { + if (err) throw err + + const db = client.db('animals') + + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +Wenn Sie nach einem Objektmodelltreiber für MongoDB suchen, schauen Sie unter [Mongoose](https://github.com/LearnBoost/mongoose) nach. ## Neo4j -**Modul**: [apoc](https://github.com/hacksparrow/apoc) -**Installation** +**Module**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver) -
    -
    -$ npm install apoc
    -
    -
    +### Installation -**Beispiel** +```bash +$ npm install neo4j-driver +``` -
    -
    -var apoc = require('apoc');
    +### Beispiel
     
    -apoc.query('match (n) return n').exec().then(
    -  function (response) {
    -    console.log(response);
    -  },
    -  function (fail) {
    -    console.log(fail);
    -  }
    -);
    -
    -
    +```js +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) - +const session = driver.session() + +session.readTransaction((tx) => { + return tx.run('MATCH (n) RETURN count(n) AS count') + .then((res) => { + console.log(res.records[0].get('count')) + }) + .catch((error) => { + console.log(error) + }) +}) +``` ## Oracle @@ -229,7 +270,7 @@ apoc.query('match (n) return n').exec().then( Anmerkung: [Siehe Installations-Voraussetzungen](https://github.com/oracle/node-oracledb#-installation). -```sh +```bash $ npm install oracledb ``` @@ -267,137 +308,182 @@ async function getEmployee (empId) { getEmployee(101) ``` - - ## PostgreSQL **Modul**: [pg-promise](https://github.com/vitaly-t/pg-promise) **Installation** -
    -
    -$ npm install pg-promise
    -
    -
    - -**Beispiel** +### Installation -
    -
    -var pgp = require("pg-promise")(/*options*/);
    -var db = pgp("postgres://username:password@host:port/database");
    +```bash
    +$ npm install pg-promise
    +```
     
    -db.one("SELECT $1 AS value", 123)
    -    .then(function (data) {
    -        console.log("DATA:", data.value);
    -    })
    -    .catch(function (error) {
    -        console.log("ERROR:", error);
    -    });
    -
    -
    +### Beispiel - +```js +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') + +db.one('SELECT $1 AS value', 123) + .then((data) => { + console.log('DATA:', data.value) + }) + .catch((error) => { + console.log('ERROR:', error) + }) +``` ## Redis **Modul**: [redis](https://github.com/mranney/node_redis) **Installation** -
    -
    +### Installation
    +
    +```bash
     $ npm install redis
    -
    -
    +``` + +### Beispiel -**Beispiel** +```js +const redis = require('redis') +const client = redis.createClient() + +client.on('error', (err) => { + console.log(`Error ${err}`) +}) -
    -
    -var client = require('redis').createClient();
    +client.set('string key', 'string val', redis.print)
    +client.hset('hash key', 'hashtest 1', 'some value', redis.print)
    +client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
     
    -client.on('error', function (err) {
    -  console.log('Error ' + err);
    -});
    +client.hkeys('hash key', (err, replies) => {
    +  console.log(`${replies.length} replies:`)
     
    -client.set('string key', 'string val', redis.print);
    -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
    -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
    +  replies.forEach((reply, i) => {
    +    console.log(`    ${i}: ${reply}`)
    +  })
    +
    +  client.quit()
    +})
    +```
     
    -client.hkeys('hash key', function (err, replies) {
    +## SQL Server
     
    -  console.log(replies.length + ' replies:');
    -  replies.forEach(function (reply, i) {
    -    console.log('    ' + i + ': ' + reply);
    -  });
    +**Module**: [tedious](https://github.com/tediousjs/tedious)
     
    -  client.quit();
    +### Installation
     
    -});
    -
    -
    +```bash +$ npm install tedious +``` - +### Beispiel + +```js +const Connection = require('tedious').Connection +const Request = require('tedious').Request + +const config = { + server: 'localhost', + authentication: { + type: 'default', + options: { + userName: 'your_username', // update me + password: 'your_password' // update me + } + } +} + +const connection = new Connection(config) + +connection.on('connect', (err) => { + if (err) { + console.log(err) + } else { + executeStatement() + } +}) + +function executeStatement () { + request = new Request("select 123, 'hello world'", (err, rowCount) => { + if (err) { + console.log(err) + } else { + console.log(`${rowCount} rows`) + } + connection.close() + }) + + request.on('row', (columns) => { + columns.forEach((column) => { + if (column.value === null) { + console.log('NULL') + } else { + console.log(column.value) + } + }) + }) + + connection.execSql(request) +} +``` ## SQLite **Modul**: [sqlite3](https://github.com/mapbox/node-sqlite3) **Installation** -
    -
    -$ npm install sqlite3
    -
    -
    +### Installation -**Beispiel** +```bash +$ npm install sqlite3 +``` -
    -
    -var sqlite3 = require('sqlite3').verbose();
    -var db = new sqlite3.Database(':memory:');
    +### Beispiel
     
    -db.serialize(function() {
    +```js
    +const sqlite3 = require('sqlite3').verbose()
    +const db = new sqlite3.Database(':memory:')
     
    -  db.run('CREATE TABLE lorem (info TEXT)');
    -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
    +db.serialize(() => {
    +  db.run('CREATE TABLE lorem (info TEXT)')
    +  const stmt = db.prepare('INSERT INTO lorem VALUES (?)')
     
    -  for (var i = 0; i < 10; i++) {
    -    stmt.run('Ipsum ' + i);
    +  for (let i = 0; i < 10; i++) {
    +    stmt.run(`Ipsum ${i}`)
       }
     
    -  stmt.finalize();
    +  stmt.finalize()
     
    -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
    -    console.log(row.id + ': ' + row.info);
    -  });
    -});
    +  db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
    +    console.log(`${row.id}: ${row.info}`)
    +  })
    +})
     
    -db.close();
    -
    -
    - - +db.close() +``` ## ElasticSearch **Modul**: [elasticsearch](https://github.com/elastic/elasticsearch-js) **Installation** -
    -
    +### Installation
    +
    +```bash
     $ npm install elasticsearch
    -
    -
    +``` -**Beispiel** +### Beispiel -
    -
    -var elasticsearch = require('elasticsearch');
    -var client = elasticsearch.Client({
    +```js
    +const elasticsearch = require('elasticsearch')
    +const client = elasticsearch.Client({
       host: 'localhost:9200'
    -});
    +})
     
     client.search({
       index: 'books',
    @@ -410,10 +496,9 @@ client.search({
           }
         }
       }
    -}).then(function(response) {
    -  var hits = response.hits.hits;
    -}, function(error) {
    -  console.trace(error.message);
    -});
    -
    -
    +}).then((response) => { + const hits = response.hits.hits +}, (error) => { + console.trace(error.message) +}) +``` diff --git a/de/guide/debugging.md b/de/guide/debugging.md old mode 100755 new mode 100644 index d88cfad7ab..0661aaf8b3 --- a/de/guide/debugging.md +++ b/de/guide/debugging.md @@ -1,39 +1,28 @@ --- layout: page title: Debugging bei Express +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: de +redirect_from: " " --- # Debugging bei Express -Express verwendet das Modul [debug](https://www.npmjs.com/package/debug) intern, um Informationen zu Weiterleitungsübereinstimmungen, verwendete Middlewarefunktionen, Anwendungsmodi und den Verlauf des Anforderung/Antwort-Zyklus zu protokollieren. - -
    -`debug` ist praktisch eine erweiterte Version von `console.log`. Im Gegensatz zu `console.log` müssen jedoch -keine `debug`-Protokolle im Produktionscode auskommentiert werden. Die Protokollierung wird standardmäßig inaktiviert und kann über die Umgebungsvariable `DEBUG` bedingt aktiviert werden. -
    - Wenn Sie alle in Express verwendeten internen Protokolle anzeigen wollen, legen Sie beim Starten Ihrer Anwendung die Umgebungsvariable `DEBUG` auf `express:*` fest. -
    -
    +```bash
     $ DEBUG=express:* node index.js
    -
    -
    +``` Verwenden Sie unter Windows den entsprechenden Befehl. -
    -
    -> set DEBUG=express:* & node index.js
    -
    -
    +```bash +> $env:DEBUG = "express:*"; node index.js +``` Die Ausführung dieses Befehls für die durch [express generator](/{{ page.lang }}/starter/generator.html) generierte Standardanwendung resultiert in folgender Ausgabe: -
    -
    +```bash
     $ DEBUG=express:* node ./bin/www
       express:router:route new / +0ms
       express:router:layer new / +1ms
    @@ -69,19 +58,17 @@ $ DEBUG=express:* node ./bin/www
       express:router:layer new / +1ms
       express:router use /users router +0ms
       express:router:layer new /users +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -
    -
    +``` Bei einer Anforderung an die Anwendung sind die Protokolle im Express-Code angegeben: -
    -
    +```bash
       express:router dispatching GET / +4h
       express:router query  : / +2ms
       express:router expressInit  : / +0ms
    @@ -97,29 +84,46 @@ Bei einer Anforderung an die Anwendung sind die Protokolle im Express-Code angeg
       express:view lookup "index.pug" +338ms
       express:view stat "/projects/example/views/index.pug" +0ms
       express:view render "/projects/example/views/index.pug" +1ms
    -
    -
    +``` Wenn Sie nur die Protokolle von der Routerimplementierung sehen wollen, legen Sie den Wert für `DEBUG` auf `express:router` fest. Gleichermaßen gilt: Wenn Sie nur die Protokolle von der Anwendungsimplementierung sehen wollen, legen Sie den Wert für `DEBUG` auf `express:application` fest, usw. ## Von `express` generierte Anwendungen -Eine über den Befehl `express` generierte Anwendung verwendet ebenfalls das Modul `debug`. Der Debug-Namespace wird auf den Namen der Anwendung erweitert. +An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application. Beispiel: Wenn Sie die Anwendung mit `$ express sample-app` generiert haben, können Sie die Debuganweisungen mit dem folgenden Befehl aktivieren: -
    -
    +```bash
     $ DEBUG=sample-app:* node ./bin/www
    -
    -
    +``` Sie können mehrere Debug-Namespaces in einer durch Kommas getrennten Namensliste angeben: -
    -
    +```bash
     $ DEBUG=http,mail,express:* node index.js
    -
    -
    +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -Weitere Informationen zu `debug` finden Sie unter [debug](https://www.npmjs.com/package/debug). +{% include admonitions/note.html content=debug-text %} diff --git a/de/guide/error-handling.md b/de/guide/error-handling.md old mode 100755 new mode 100644 index 186081978f..1ffb0f9738 --- a/de/guide/error-handling.md +++ b/de/guide/error-handling.md @@ -1,119 +1,143 @@ --- layout: page title: Fehlerbehandlung in Express +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: de +redirect_from: " " --- # Fehlerbehandlung -Middlewarefunktionen für die Fehlerbehandlung werden in derselben Weise definiert wie andere Middlewarefunktionen, nur, dass Fehlerbehandlungsfunktionen vier anstatt drei Argumente aufweisen: -`(err, req, res, next)`. Beispiel: +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    - -Middleware für die Fehlerbehandlung wird ganz zuletzt nach allen anderen `app.use()`- und Weiterleitungsaufrufen definiert. Beispiel: - -
    -
    -var bodyParser = require('body-parser');
    -var methodOverride = require('method-override');
    -
    -app.use(bodyParser());
    -app.use(methodOverride());
    -app.use(function(err, req, res, next) {
    -  // logic
    -});
    -
    -
    +## Catching Errors -Antworten von der Middlewarefunktion können das von Ihnen gewünschte Format aufweisen wie beispielsweise eine Fehlerseite im HTML-Format, eine einfache Nachricht oder eine JSON-Zeichenfolge. +It's important to ensure that Express catches all errors that occur while +running route handlers and middleware. -Für organisatorische Zwecke (und Frameworks der höheren Ebene) können Sie mehrere Middlewarefunktionen für die Fehlerbehandlung definieren, wie Sie dies bei regulären Middlewarefunktionen auch tun würden. Wenn Sie beispielsweise eine Fehlerbehandlungsroutine (Error-Handler) für Anforderungen über `XHR` und andere Anforderungen definieren wollen, können Sie die folgenden Befehle verwenden: +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. Beispiel: -
    -
    -var bodyParser = require('body-parser');
    -var methodOverride = require('method-override');
    +```js
    +app.get('/', (req, res) => {
    +  throw new Error('BROKEN') // Express will catch this on its own.
    +})
    +```
     
    -app.use(bodyParser());
    -app.use(methodOverride());
    -app.use(logErrors);
    -app.use(clientErrorHandler);
    -app.use(errorHandler);
    -
    -
    +Middlewarefunktionen für die Fehlerbehandlung werden in derselben Weise definiert wie andere Middlewarefunktionen, nur, dass Fehlerbehandlungsfunktionen vier anstatt drei Argumente aufweisen: +`(err, req, res, next)`. Beispiel: -In diesem Beispiel kann die generische `logErrors`-Funktion Anforderungs- und Fehlerinformationen in `stderr` schreiben: +```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) + } + }) +}) +``` -
    -
    -function logErrors(err, req, res, next) {
    -  console.error(err.stack);
    -  next(err);
    -}
    -
    -
    +Middleware für die Fehlerbehandlung wird ganz zuletzt nach allen anderen `app.use()`- und Weiterleitungsaufrufen definiert. +Beispiel: -In diesem Beispiel wird `clientErrorHandler` wie folgt definiert. In diesem Fall wird der Fehler explizit an den nächsten Error-Handler übergeben: +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` -
    -
    -function clientErrorHandler(err, req, res, next) {
    -  if (req.xhr) {
    -    res.status(500).send({ error: 'Something failed!' });
    -  } else {
    -    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. -Die `errorHandler`-Funktion "catch-all" kann wie folgt implementiert werden: +Wenn Sie Übergaben an die Funktion `next()` vornehmen (außer die Zeichenfolge `'route'`), sieht Express die aktuelle Anforderung als Fehler an und überspringt alle verbleibenden fehlerfreien Behandlungsroutinen und Middlewarefunktionen. -
    -
    -function errorHandler(err, req, res, next) {
    -  res.status(500);
    -  res.render('error', { error: err });
    -}
    -
    -
    +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: -Wenn Sie Übergaben an die Funktion `next()` vornehmen (außer die Zeichenfolge `'route'`), sieht Express die aktuelle Anforderung als Fehler an und überspringt alle verbleibenden fehlerfreien Behandlungsroutinen und Middlewarefunktionen. Wenn Sie den Fehler bearbeiten wollen, müssen Sie (wie im nächsten Abschnitt beschrieben) eine Fehlerbehandlungsweiterleitung erstellen. +```js +app.get('/', [ + function (req, res, next) { + fs.writeFile('/inaccessible-path', 'data', next) + }, + function (req, res) { + res.send('OK') + } +]) +``` -Bei einem Routenhandler mit mehreren Callback-Funktionen können Sie den Parameter `route` verwenden, um den nächsten Routenhandler zu überspringen. Beispiel: +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. -
    -
    -app.get('/a_route_behind_paywall',
    -  function checkIfPaidSubscriber(req, res, next) {
    -    if(!req.user.hasPaid) {
    +Bei einem Routenhandler mit mehreren Callback-Funktionen können Sie den Parameter `route` verwenden, um den nächsten Routenhandler zu überspringen. Beispiel:
     
    -      // continue handling this request
    -      next('route');
    +```js
    +app.get('/', (req, res, next) => {
    +  setTimeout(() => {
    +    try {
    +      throw new Error('BROKEN')
    +    } catch (err) {
    +      next(err)
         }
    -  }, function getPaidContent(req, res, next) {
    -    PaidContent.find(function(err, doc) {
    -      if(err) return next(err);
    -      res.json(doc);
    -    });
    -  });
    -
    -
    + }, 100) +}) +``` -In diesem Beispiel wird der Handler `getPaidContent` übersprungen. Alle verbleibenden Handler in `app` für `/a_route_behind_paywall` werden jedoch weiter ausgeführt. +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. -
    -Aufrufe zu `next()` und `next(err)` geben an, dass der aktuelle Handler abgeschlossen ist und welchen Status er aufweist. Durch `next(err)` werden alle verbleibenden Handler in der Kette übersprungen. Ausgenommen hiervor sind die Handler, die konfiguriert sind, um Fehler wie oben beschrieben zu behandeln. -
    +Use promises to avoid the overhead of the `try...catch` block or when using functions +that return promises. Beispiel: + +```js +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { + throw new Error('BROKEN') + }).catch(next) // Errors will be passed to Express. +}) +``` + +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. + +You could also use a chain of handlers to rely on synchronous error +catching, by reducing the asynchronous code to something trivial. Beispiel: + +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +The above example has a couple of trivial statements from 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 +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. + +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. ## Die Standardfehlerbehandlungsroutine (Default Error Handler) @@ -125,18 +149,135 @@ Wenn Sie einen Fehler an `next()` übergeben und diesen nicht mit einem Error-Ha Legen Sie die Umgebungsvariable `NODE_ENV` auf `production` fest, um die Anwendung im Produktionsmodus auszuführen.
+When an error is written, the following information is added to the +response: + +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. + Wenn `next()` mit einem Fehler aufgerufen wird, nachdem Sie mit dem Schreiben der Antwort begonnen haben (z. B., wenn Sie beim Streamen der Antwort zum Client einen Fehler feststellen), schließt die Standardfehlerbehandlungsroutine in Express die Verbindung, und die Anforderung schlägt fehl. Wenn Sie also einen angepassten Error-Handler hinzufügen, empfiehlt es sich, eine Delegierung zur Standardfehlerbehandlungsroutine in Express vorzunehmen, wenn die Header bereits an den Client gesendet wurden: -
-
-function errorHandler(err, req, res, next) {
+```js
+function errorHandler (err, req, res, next) {
   if (res.headersSent) {
-    return next(err);
+    return next(err)
   }
-  res.status(500);
-  res.render('error', { error: err });
+  res.status(500)
+  res.render('error', { error: err })
 }
-
-
+``` + +Note that the default error handler can get triggered if you call `next()` with an error +in your code more than once, even if custom error handling middleware is in place. + +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html). + +## Writing error handlers + +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)`. Beispiel: + +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` + +You define error-handling middleware last, after other `app.use()` and routes calls; for example: + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use((err, req, res, next) => { + // logic +}) +``` + +Antworten von der Middlewarefunktion können das von Ihnen gewünschte Format aufweisen wie beispielsweise eine Fehlerseite im HTML-Format, eine einfache Nachricht oder eine JSON-Zeichenfolge. + +Für organisatorische Zwecke (und Frameworks der höheren Ebene) können Sie mehrere Middlewarefunktionen für die Fehlerbehandlung definieren, wie Sie dies bei regulären Middlewarefunktionen auch tun würden. Wenn Sie beispielsweise eine Fehlerbehandlungsroutine (Error-Handler) für Anforderungen über `XHR` und andere Anforderungen definieren wollen, können Sie die folgenden Befehle verwenden: + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use(logErrors) +app.use(clientErrorHandler) +app.use(errorHandler) +``` + +In diesem Beispiel kann die generische `logErrors`-Funktion Anforderungs- und Fehlerinformationen in `stderr` schreiben: + +```js +function logErrors (err, req, res, next) { + console.error(err.stack) + next(err) +} +``` + +In diesem Beispiel wird `clientErrorHandler` wie folgt definiert. In diesem Fall wird der Fehler explizit an den nächsten Error-Handler übergeben: + +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. + +```js +function clientErrorHandler (err, req, res, next) { + if (req.xhr) { + res.status(500).send({ error: 'Something failed!' }) + } else { + next(err) + } +} +``` + +Die `errorHandler`-Funktion "catch-all" kann wie folgt implementiert werden: + +```js +function errorHandler (err, req, res, next) { + res.status(500) + res.render('error', { error: err }) +} +``` + +If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. Beispiel: + +```js +app.get('/a_route_behind_paywall', + (req, res, next) => { + if (!req.user.hasPaid) { + // continue handling this request + next('route') + } else { + next() + } + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` + +In diesem Beispiel wird der Handler `getPaidContent` übersprungen. Alle verbleibenden Handler in `app` für `/a_route_behind_paywall` werden jedoch weiter ausgeführt. + +
+Aufrufe zu `next()` und `next(err)` geben an, dass der aktuelle Handler abgeschlossen ist und welchen Status er aufweist. Durch `next(err)` werden alle verbleibenden Handler in der Kette übersprungen. Ausgenommen hiervor sind die Handler, die konfiguriert sind, um Fehler wie oben beschrieben zu behandeln. +
diff --git a/de/guide/migrating-4.md b/de/guide/migrating-4.md old mode 100755 new mode 100644 index 53a5049801..ddfe05f09a --- a/de/guide/migrating-4.md +++ b/de/guide/migrating-4.md @@ -1,8 +1,9 @@ --- layout: page title: Migration auf Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: de +redirect_from: " " --- # Wechsel zu Express 4 @@ -24,15 +25,16 @@ In diesem Beitrag werden folgende Themen behandelt: In Express 4 wurden einige signifikante Änderungen vorgenommen: Siehe hierzu auch: -* [Neue Features/Funktionen in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migration von 3.x auf 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [Neue Features/Funktionen in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [Migration von 3.x auf 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

Änderungen am Express-Core- und Middlewaresystem

@@ -48,7 +50,7 @@ Ohne integrierte Middleware müssen Sie explizit alle Middlewarefunktionen hinzu In der folgenden Tabelle sind Express 3-Middlewarefunktionen und deren Entsprechungen in Express 4 aufgelistet. - + @@ -80,7 +82,7 @@ In der folgenden Tabelle sind Express 3-Middlewarefunktionen und deren Entsprech -
Express 3Express 4
Express 3Express 4
express.bodyParser body-parser + multer
serve-index
express.static serve-static
+ Hier finden Sie die [komplette Liste](https://github.com/senchalabs/connect#middleware) der Express 4-Middleware. @@ -88,27 +90,28 @@ In den meisten Fällen können Sie einfach nur die Middleware der alten Version

app.use akzeptiert Parameter.

-In Version 4 können Sie über einen Variablenparameter den Pfad definieren, in den Middlewarefunktionen geladen werden. Dann können Sie den Wert des Parameters aus dem Routenhandler laden. Beispiel: +In Version 4 können Sie über einen Variablenparameter den Pfad definieren, in den Middlewarefunktionen geladen werden. Dann können Sie den Wert des Parameters aus dem Routenhandler laden. +Beispiel: + +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` -
-
-app.use('/book/:id', function(req, res, next) {
-  console.log('ID:', req.params.id);
-  next();
-});
-
-

Das Routingsystem

Anwendungen laden nun implizit Routing-Middleware. Sie müssen sich also keine Gedanken mehr über die Reihenfolge machen, in der die Middleware in Bezug auf die `router`-Middleware geladen wird. -Die Art und Weise, wie Weiterleitungen (Routen) definiert werden, bleibt unverändert. Das Routingsystem verfügt jedoch über zwei neue Funktionen, die beim Organisieren Ihrer Weiterleitungen helfen: +Das Routingsystem verfügt jedoch über zwei neue Funktionen, die beim Organisieren Ihrer Weiterleitungen helfen: {: .doclist } -* Die neue Methode `app.route()` zum Erstellen verkettbarer Routenhandler für einen Weiterleitungspfad -* Die neue Klasse `express.Router` zum Erstellen modular einbindbarer Routenhandler + +- Die neue Methode `app.route()` zum Erstellen verkettbarer Routenhandler für einen Weiterleitungspfad +- Die neue Klasse `express.Router` zum Erstellen modular einbindbarer Routenhandler

Die Methode app.route()

@@ -116,20 +119,18 @@ Die neue Methode `app.route()` hilft beim Erstellen verkettbarer Routenhandler f Dies ist ein Beispiel für verkettete Routenhandler, die mit der Funktion `app.route()` definiert werden. -
-
+```js
 app.route('/book')
-  .get(function(req, res) {
-    res.send('Get a random book');
+  .get((req, res) => {
+    res.send('Get a random book')
   })
-  .post(function(req, res) {
-    res.send('Add a book');
+  .post((req, res) => {
+    res.send('Add a book')
   })
-  .put(function(req, res) {
-    res.send('Update the book');
-  });
-
-
+ .put((req, res) => { + res.send('Update the book') + }) +```

Die Klasse express.Router

@@ -139,38 +140,36 @@ Im folgenden Beispiel wird ein Router als Modul erstellt, Middleware in das Modu Beispiel: Erstellen Sie eine Routerdatei namens `birds.js` mit dem folgenden Inhalt im Anwendungsverzeichnis: -
-
-var express = require('express');
-var router = express.Router();
+```js
+var express = require('express')
+var router = express.Router()
 
 // middleware specific to this router
-router.use(function timeLog(req, res, next) {
-  console.log('Time: ', Date.now());
-  next();
-});
+router.use((req, res, next) => {
+  console.log('Time: ', Date.now())
+  next()
+})
 // define the home page route
-router.get('/', function(req, res) {
-  res.send('Birds home page');
-});
+router.get('/', (req, res) => {
+  res.send('Birds home page')
+})
 // define the about route
-router.get('/about', function(req, res) {
-  res.send('About birds');
-});
+router.get('/about', (req, res) => {
+  res.send('About birds')
+})
 
-module.exports = router;
-
-
+module.exports = router +``` Laden Sie dann das Routermodul in die Anwendung: -
-
-var birds = require('./birds');
-...
-app.use('/birds', birds);
-
-
+```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` Die Anwendung kann nun Anforderungen an die Pfade `/birds` und `/birds/about` bearbeiten und ruft die Middleware `timeLog` auf, die speziell für diese Weiterleitung bestimmt ist. @@ -180,7 +179,7 @@ Weitere Änderungen In der folgenden Tabelle sind andere kleinere, aber trotzdem wichtige Änderungen in Express 4 aufgeführt: - + @@ -203,7 +202,7 @@ Das Modul `http` wird nicht mehr benötigt, es sei denn, Sie müssen direkt mit `app.configure()` @@ -286,11 +285,12 @@ Entfernt. Die Funktionalität ist nun auf die Einstellung des Basis-Cookiewerts begrenzt. Verwenden Sie `res.cookie()`, um weitere Funktionalität zu erhalten. -
Objekt Beschreibung
-Die Funktion `app.configure()` wurde entfernt. Verwenden Sie die Funktion `process.env.NODE_ENV` oder `app.get('env')`, um die Umgebung zu erkennen und die Anwendung entsprechend zu konfigurieren. +Die Funktion `app.configure()` wurde entfernt. Verwenden Sie die Funktion `process.env.NODE_ENV` oder `app.get('env')`, um die Umgebung zu erkennen und die Anwendung entsprechend zu konfigurieren.
+

Beispiel für eine Anwendungsmigration

-Dies ist ein Beispiel für die Migration einer Express 3-Anwendung auf Express 4. Die dabei interessanten Dateien sind `app.js` und `package.json`. +Dies ist ein Beispiel für die Migration einer Express 3-Anwendung auf Express 4. +Die dabei interessanten Dateien sind `app.js` und `package.json`.

Anwendung der Version 3 @@ -300,48 +300,45 @@ Anwendung der Version 3 Es wird eine Express v.3-Anwendung mit der folgenden Datei `app.js` angenommen: -
-
-var express = require('express');
-var routes = require('./routes');
-var user = require('./routes/user');
-var http = require('http');
-var path = require('path');
+```js
+var express = require('express')
+var routes = require('./routes')
+var user = require('./routes/user')
+var http = require('http')
+var path = require('path')
 
-var app = express();
+var app = express()
 
 // all environments
-app.set('port', process.env.PORT || 3000);
-app.set('views', path.join(__dirname, 'views'));
-app.set('view engine', 'pug');
-app.use(express.favicon());
-app.use(express.logger('dev'));
-app.use(express.methodOverride());
-app.use(express.session({ secret: 'your secret here' }));
-app.use(express.bodyParser());
-app.use(app.router);
-app.use(express.static(path.join(__dirname, 'public')));
+app.set('port', process.env.PORT || 3000)
+app.set('views', path.join(__dirname, 'views'))
+app.set('view engine', 'pug')
+app.use(express.favicon())
+app.use(express.logger('dev'))
+app.use(express.methodOverride())
+app.use(express.session({ secret: 'your secret here' }))
+app.use(express.bodyParser())
+app.use(app.router)
+app.use(express.static(path.join(__dirname, 'public')))
 
 // development only
-if ('development' == app.get('env')) {
-  app.use(express.errorHandler());
+if (app.get('env') === 'development') {
+  app.use(express.errorHandler())
 }
 
-app.get('/', routes.index);
-app.get('/users', user.list);
+app.get('/', routes.index)
+app.get('/users', user.list)
 
-http.createServer(app).listen(app.get('port'), function(){
-  console.log('Express server listening on port ' + app.get('port'));
-});
-
-
+http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

package.json

Die zugehörige `package.json`-Datei der Version 3 sieht in etwa wie folgt aus: -
-
+```json
 {
   "name": "application-name",
   "version": "0.0.1",
@@ -354,8 +351,7 @@ Die zugehörige `package.json`-Datei der Version 3 sieht in etwa wie folgt aus:
     "pug": "*"
   }
 }
-
-
+```

Prozess @@ -363,20 +359,19 @@ Prozess Beginnen Sie den Migrationsprozess mit der Installation der erforderlichen Middleware für die Express 4-Anwendung und der Aktualisierung von Express und Pug auf die aktuellen Versionen. Verwenden Sie hierzu den folgenden Befehl: -
-
+```bash
 $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
-
-
+``` Nehmen Sie an `app.js` die folgenden Änderungen vor: 1. Die integrierten Express-Middlewarefunktionen `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` und - `express.errorHandler` sind im Objekt `express` nicht mehr verfügbar. Sie müssen deren Alternativen manuell installieren und in die Anwendung laden. + `express.logger`, `express.methodOverride`, + `express.session`, `express.bodyParser` und + `express.errorHandler` sind im Objekt `express` nicht mehr verfügbar. Sie müssen deren Alternativen manuell installieren und in die Anwendung laden. -2. Sie müssen die Funktion `app.router` nicht mehr laden. Sie ist kein gültiges Express 4-Anwendungsobjekt. Entfernen Sie also den Code `app.use(app.router);`. +2. Sie müssen die Funktion `app.router` nicht mehr laden. + Sie ist kein gültiges Express 4-Anwendungsobjekt. Entfernen Sie also den Code `app.use(app.router);`. 3. Stellen Sie sicher, dass die Middlewarefunktionen in der richtigen Reihenfolge geladen werden – laden Sie `errorHandler` nach dem Laden der Anwendungsweiterleitungen. @@ -386,8 +381,7 @@ Nehmen Sie an `app.js` die folgenden Änderungen vor: Durch Ausführung des Befehls `npm` wird `package.json` wie folgt aktualisiert: -
-
+```json
 {
   "name": "application-name",
   "version": "0.0.1",
@@ -400,87 +394,84 @@ Durch Ausführung des Befehls `npm` wird `package.json` wie folgt aktualisiert:
     "errorhandler": "^1.1.1",
     "express": "^4.8.0",
     "express-session": "^1.7.2",
-    "pug": "^2.0.0-beta6",
+    "pug": "^2.0.0",
     "method-override": "^2.1.2",
     "morgan": "^1.2.2",
     "multer": "^0.1.3",
     "serve-favicon": "^2.0.1"
   }
 }
-
-
+```

app.js

Entfernen Sie dann ungültigen Code, laden Sie die erforderliche Middleware und nehmen Sie andere Änderungen nach Bedarf vor. Die Datei `app.js` sieht dann wie folgt aus: -
-
-var http = require('http');
-var express = require('express');
-var routes = require('./routes');
-var user = require('./routes/user');
-var path = require('path');
+```js
+var http = require('http')
+var express = require('express')
+var routes = require('./routes')
+var user = require('./routes/user')
+var path = require('path')
 
-var favicon = require('serve-favicon');
-var logger = require('morgan');
-var methodOverride = require('method-override');
-var session = require('express-session');
-var bodyParser = require('body-parser');
-var multer = require('multer');
-var errorHandler = require('errorhandler');
+var favicon = require('serve-favicon')
+var logger = require('morgan')
+var methodOverride = require('method-override')
+var session = require('express-session')
+var bodyParser = require('body-parser')
+var multer = require('multer')
+var errorHandler = require('errorhandler')
 
-var app = express();
+var app = express()
 
 // all environments
-app.set('port', process.env.PORT || 3000);
-app.set('views', path.join(__dirname, 'views'));
-app.set('view engine', 'pug');
-app.use(favicon(__dirname + '/public/favicon.ico'));
-app.use(logger('dev'));
-app.use(methodOverride());
-app.use(session({ resave: true,
-                  saveUninitialized: true,
-                  secret: 'uwotm8' }));
-app.use(bodyParser.json());
-app.use(bodyParser.urlencoded({ extended: true }));
-app.use(multer());
-app.use(express.static(path.join(__dirname, 'public')));
-
-app.get('/', routes.index);
-app.get('/users', user.list);
+app.set('port', process.env.PORT || 3000)
+app.set('views', path.join(__dirname, 'views'))
+app.set('view engine', 'pug')
+app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
+app.use(logger('dev'))
+app.use(methodOverride())
+app.use(session({
+  resave: true,
+  saveUninitialized: true,
+  secret: 'uwotm8'
+}))
+app.use(bodyParser.json())
+app.use(bodyParser.urlencoded({ extended: true }))
+app.use(multer())
+app.use(express.static(path.join(__dirname, 'public')))
+
+app.get('/', routes.index)
+app.get('/users', user.list)
 
 // error handling middleware should be loaded after the loading the routes
-if ('development' == app.get('env')) {
-  app.use(errorHandler());
+if (app.get('env') === 'development') {
+  app.use(errorHandler())
 }
 
-var server = http.createServer(app);
-server.listen(app.get('port'), function(){
-  console.log('Express server listening on port ' + app.get('port'));
-});
-
-
- -
-Wenn Sie nicht direkt mit dem Modul `http` arbeiten müssen (socket.io/SPDY/HTTPS), ist das Laden des Moduls nicht erforderlich. Die Anwendung kann dann einfach wie folgt gestartet werden: -
-app.listen(app.get('port'), function(){
-  console.log('Express server listening on port ' + app.get('port'));
-});
-
-
+var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` + +
Wenn Sie nicht direkt mit dem Modul `http` arbeiten müssen (socket.io/SPDY/HTTPS), ist das Laden des Moduls nicht erforderlich. Die Anwendung kann dann einfach wie folgt gestartet werden: + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +

Anwendung ausführen

Der Migrationsprozess ist abgeschlossen und die Anwendung ist nun eine Express 4-Anwendung. Zum Bestätigen starten Sie die Anwendung mit dem folgenden Befehl: -
-
+```bash
 $ node .
-
-
+``` Laden Sie [http://localhost:3000](http://localhost:3000) und sehen Sie, wie die Homepage von Express 4 wiedergegeben wird. @@ -492,23 +483,20 @@ Das Befehlszeilentool zum Generieren einer Express-Anwendung ist nach wie vor `e Wenn der Express 3 App Generator bereits auf Ihrem System installiert ist, müssen Sie diesen deinstallieren: -
-
+```bash
 $ npm uninstall -g express
-
-
+``` + Abhängig davon, wie Ihre Datei- und Verzeichnissberechtigungen konfiguriert sind, müssen Sie diesen Befehl möglicherweise mit `sudo` ausführen. + Installieren Sie nun den neuen Generator: -
-
+```bash
 $ npm install -g express-generator
-
-
+``` Abhängig davon, wie Ihre Datei- und Verzeichnissberechtigungen konfiguriert sind, müssen Sie diesen Befehl möglicherweise mit `sudo` ausführen. - Nun wird der Befehl `express` auf Ihrem System auf den Express 4 App Generator aktualisiert.

Änderungen am App Generator

@@ -516,19 +504,18 @@ Nun wird der Befehl `express` auf Ihrem System auf den Express 4 App Generator a Befehlsoptionen und -nutzung bleiben größtenteils unverändert. Es gelten jedoch folgende Ausnahmen: {: .doclist } -* Option `--sessions` wurde entfernt. -* Option `--jshtml` wurde entfernt. -* Option `--hogan` wurde hinzugefügt, um [Hogan.js](http://twitter.github.io/hogan.js/) zu unterstützen. + +- Option `--sessions` wurde entfernt. +- Option `--jshtml` wurde entfernt. +- Option `--hogan` wurde hinzugefügt, um [Hogan.js](http://twitter.github.io/hogan.js/) zu unterstützen.

Beispiel

Führen Sie den folgenden Befehl aus, um eine Express 4-Anwendung zu erstellen: -
-
+```bash
 $ express app4
-
-
+``` Wenn Sie sich den Inhalt der Datei `app4/app.js` ansehen, werden Sie feststellen, dass alle Middlewarefunktionen (außer `express.static`), die für die Anwendung erforderlich sind, als unabhängige Module geladen werden und die Middleware `router` nicht mehr explizit in die Anwendung geladen wird. @@ -536,11 +523,9 @@ Sie werden auch feststellen, dass die Datei `app.js` nun ein Node.js-Modul ist Starten Sie nach der Installation der Abhängigkeiten die Anwendung mit dem folgenden Befehl: -
-
+```bash
 $ npm start
-
-
+``` Wenn Sie sich das npm-Startscript in der Datei `package.json` näher ansehen, werden Sie feststellen, dass der eigentliche Befehl, der die Anwendung startet, `node ./bin/www` heißt. Dieser Befehl lautete in Express 3 `node app.js`. @@ -550,23 +535,19 @@ Weder das Verzeichnis `bin` noch die erweiterungslose Datei `www` ist für das E Um das Verzeichnis `www` zu löschen und alles im "Express 3-Stil" zu belassen, löschen Sie die Zeile mit dem Eintrag `module.exports = app;` am Ende der Datei `app.js`. Fügen Sie dann stattdessen den folgenden Code an derselben Position ein: -
-
-app.set('port', process.env.PORT || 3000);
+```js
+app.set('port', process.env.PORT || 3000)
 
-var server = app.listen(app.get('port'), function() {
-  debug('Express server listening on port ' + server.address().port);
-});
-
-
+var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` Stellen Sie sicher, dass Sie das Modul `debug` am Anfang der Datei `app.js` laden. Verwenden Sie dazu den folgenden Code: -
-
-var debug = require('debug')('app4');
-
-
+```js +var debug = require('debug')('app4') +``` Ändern Sie als Nächstes `"start": "node ./bin/www"` in der Datei `package.json` in `"start": "node app.js"`. diff --git a/de/guide/migrating-5.md b/de/guide/migrating-5.md old mode 100755 new mode 100644 index 837fdea897..af9d495fd5 --- a/de/guide/migrating-5.md +++ b/de/guide/migrating-5.md @@ -1,31 +1,44 @@ --- layout: page title: Migration auf Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: de +redirect_from: " " --- # Wechsel zu Express 5

Überblick

-Express 5.0 befindet sich noch in der Alpha-Release-Phase. Hier finden Sie jedoch bereits eine Vorschau zu den Änderungen in diesem Release und zur Migration Ihrer Express 4-Anwendung auf Express 5. +Express 5.0 befindet sich noch in der Beta-Release-Phase. Hier finden Sie jedoch bereits eine Vorschau zu den Änderungen in diesem Release und zur Migration Ihrer Express 4-Anwendung auf Express 5. -Express 5 unterscheidet sich nicht allzu sehr von Express 4: Die Änderungen an der API sind nicht so signifikant wie von 3.0 zu 4.0. Auch wenn die Basis-API unverändert bleibt, wird es doch einige grundlegende Veränderungen geben. In anderen Worten: Ein vorhandenes Express 4-Programm funktioniert möglicherweise nicht mehr, wenn Sie es für Express 5 aktualisieren. +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -Zum Installieren der aktuellen Alpha-Version und zur Vorschau von Express 5 geben Sie den folgenden Befehl im Stammverzeichnis Ihrer Anwendung ein: - -
-
-$ npm install express@5.0.0-alpha.2 --save
-
-
+```sh +npm install "express@5" +``` Sie können Ihre automatisierten Tests ausführen, um zu sehen, was fehlschlägt, und Probleme gemäß den folgenden Updates beheben. Nachdem Sie alle Testfehler behoben haben, führen Sie Ihre Anwendung aus, um zu sehen, welche Fehler noch auftreten. Sie werden sofort feststellen, ob die Anwendung Methoden oder Eigenschaften verwendet, die nicht unterstützt werden. -

Änderungen in Express 5

+## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: + +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). -Nachfolgend finden Sie eine Liste mit Änderungen (Stand: Alpha-2-Release), die sich auf Sie als Express-Benutzer auswirken werden. Siehe hierzu auch die [Pull-Anforderung](https://github.com/expressjs/express/pull/2237) mit einer Liste aller geplanten Features und Funktionen. +

Änderungen in Express 5

**Entfernte Methoden und Eigenschaften** @@ -37,95 +50,497 @@ Nachfolgend finden Sie eine Liste mit Änderungen (Stand: Alpha-2-Release), die
  • req.param(name)
  • res.json(obj, status)
  • res.jsonp(obj, status)
  • +
  • res.redirect('back') and res.location('back')
  • +
  • res.redirect(url, status)
  • res.send(body, status)
  • res.send(status)
  • res.sendfile()
  • +
  • router.param(fn)
  • +
  • express.static.mime
  • +
  • express:router debug logs
  • -**Geändert** +**Verbesserungen** -**Verbesserungen** +**Geändert** -

    Entfernte Methoden und Eigenschaften

    +## Entfernte Methoden und Eigenschaften Wenn Sie eine dieser Methoden oder Eigenschaften in Ihrer Anwendung verwenden, stürzt die Anwendung ab. Sie müssen also Ihre Anwendung ändern, wenn Sie auf Version 5 umgestellt haben. -

    app.del()

    +

    app.del()

    Express 5 unterstützt die Funktion `app.del()` nicht mehr. Wenn Sie diese Funktion verwenden, wird ein Fehler ausgelöst. Für die Registrierung von HTTP DELETE-Weiterleitungen verwenden Sie stattdessen die Funktion `app.delete()`. -Anfänglich wurde `del` statt `delete` verwendet, weil `delete` in JavaScript ein reserviertes Schlüsselwort ist. Ab ECMAScript 6 jedoch können `delete` und andere reservierte Schlüsselwörter legal als Eigenschaftsnamen verwendet werden. Lesen hier auch die Diskussion, die zur Einstellung der Unterstützung der Funktion `app.del` geführt hat. +Anfänglich wurde `del` statt `delete` verwendet, weil `delete` in JavaScript ein reserviertes Schlüsselwort ist. Ab ECMAScript 6 jedoch können `delete` und andere reservierte Schlüsselwörter legal als Eigenschaftsnamen verwendet werden. + +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` + +{% endcapture %} -

    app.param(fn)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} -Die Signatur `app.param(fn)` wurde für die Änderung der Verhaltensweise der Funktion `app.param(name, fn)` verwendet. Seit v4.11.0 wurde sie nicht mehr verwendet. In Express 5 wird sie überhaupt nicht mehr unterstützt. +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) -

    Pluralisierte Methodennamen

    +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

    app.param(fn)

    + +Die Signatur `app.param(fn)` wurde für die Änderung der Verhaltensweise der Funktion `app.param(name, fn)` verwendet. Seit v4.11.0 wurde sie nicht mehr verwendet. In Express 5 wird sie überhaupt nicht mehr unterstützt. + +

    Pluralisierte Methodennamen

    Die folgenden Methodennamen wurden pluralisiert. In Express 4 wurde bei Verwendung der alten Methoden eine Warnung zur Einstellung der Unterstützung ausgegeben. Express 5 unterstützt diese Methoden nicht mehr. +`req.acceptsLanguage()` wird durch `req.acceptsLanguages()` ersetzt. + `req.acceptsCharset()` wird durch `req.acceptsCharsets()` ersetzt. `req.acceptsEncoding()` wird durch `req.acceptsEncodings()` ersetzt. -`req.acceptsLanguage()` wird durch `req.acceptsLanguages()` ersetzt. +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} -

    Führender Doppelpunkt (:) im Namen für app.param(name, fn)

    +{% include admonitions/note.html content=codemod-pluralized-methods %} + +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    Führender Doppelpunkt (:) im Namen für app.param(name, fn)

    Ein führendes Doppelpunktzeichen (:) im Namen für die Funktion `app.param(name, fn)` ist ein Überbleibsel aus Express 3. Aus Gründen der Abwärtskompatibilität wurde dieser Name in Express 4 mit einem Hinweis zu veralteten Versionen weiter unterstützt. In Express 5 wird dieser Name stillschwiegend ignoriert und der Namensparameter ohne einen vorangestellten Doppelpunkt verwendet. Dies dürfte keine Auswirkungen auf Ihren Code haben, wenn Sie die Express 4-Dokumentation zu [app.param](/{{ page.lang }}/4x/api.html#app.param) befolgen, da dort der führende Doppelpunkt nicht erwähnt wird. -

    req.param(name)

    +

    req.param(name)

    Dieses potenziell verwirrende und durchaus riskante Verfahren des Abrufens von Formulardaten wurde entfernt. Sie müssen nun ganz speziell nach dem übergebenen Parameternamen im Objekt `req.params`, `req.body` oder `req.query` suchen. -

    res.json(obj, status)

    +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    Express 5 unterstützt die Signatur `res.json(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.json()`-Methoden wie dieser verketten: `res.status(status).json(obj)`. -

    res.jsonp(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    Express 5 unterstützt die Signatur `res.jsonp(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.jsonp()`-Methoden wie dieser verketten: `res.status(status).jsonp(obj)`. -

    res.send(body, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    Express 5 unterstützt die Signatur `res.send(obj, status)` nicht mehr. Stattdessen müssen Sie den Status festlegen und diesen dann mit `res.send()`-Methoden wie dieser verketten: `res.status(status).send(obj)`. -

    res.send(status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    + +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    + +Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) + +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` + +

    res.send(status)

    + +Express 5 unterstützt die Signatur res.send(status), nicht mehr, wobei _`status`_ für eine Zahl steht. Verwenden Sie stattdessen die Funktion `res.sendStatus(statusCode)`, mit der der Statuscode für den HTTP-Antwort-Header festgelegt und die Textversion des Codes gesendet wird: "Not Found" (Nicht gefunden), "Internal Server Error" (Interner Serverfehler) usw. +Wenn Sie eine Zahl senden und hierfür die Funktion `res.send()` verwenden müssen, müssen Sie die Zahl in Anführungszeichen setzen, um diese in eine Zeichenfolge zu konvertieren. Dadurch interpretiert Express diese Zahl nicht als Versuch, die nicht mehr unterstützte alte Signatur zu verwenden. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} -Express 5 unterstützt die Signatur res.send(status), nicht mehr, wobei *`status`* für eine Zahl steht. Verwenden Sie stattdessen die Funktion `res.sendStatus(statusCode)`, mit der der Statuscode für den HTTP-Antwort-Header festgelegt und die Textversion des Codes gesendet wird: "Not Found" (Nicht gefunden), "Internal Server Error" (Interner Serverfehler) usw. Wenn Sie eine Zahl senden und hierfür die Funktion `res.send()` verwenden müssen, müssen Sie die Zahl in Anführungszeichen setzen, um diese in eine Zeichenfolge zu konvertieren. Dadurch interpretiert Express diese Zahl nicht als Versuch, die nicht mehr unterstützte alte Signatur zu verwenden. +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) -

    res.sendfile()

    +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

    res.sendfile()

    Die Funktion `res.sendfile()` wurde durch eine Version in Camel-Schreibweise von `res.sendFile()` in Express 5 ersetzt. -

    Geändert

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. Seit v4.11.0 wurde sie nicht mehr verwendet. In Express 5 wird sie überhaupt nicht mehr unterstützt. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## Geändert + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. Beispiel: -

    app.router

    +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +Beispiel: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    Das Objekt `app.router`, das in Express 4 entfernt wurde, ist in Express 5 wieder verfügbar. In der neuen Version fungiert dieses Objekt nur als Referenz zum Express-Basisrouter – im Gegensatz zu Express 3, wo die Anwendung dieses Objekt explizit laden musste. -

    req.host

    +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    In Express 4 übergab die Funktion `req.host` nicht ordnungsgemäß eine eventuell vorhandene Portnummer. In Express 5 wird die Portnummer beibehalten. -

    req.query

    +

    req.query

    + +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -In Express 4.7 und ab Express 5 kann die Abfrageparser-Option `false` akzeptieren, um das Parsing von Abfragezeichenfolgen zu deaktivieren, wenn Sie Ihre eigene Funktion für die Parsinglogik bei Abfragezeichenfolgen verwenden wollen. +

    res.clearCookie

    -

    Verbesserungen

    +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. -

    res.render()

    +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## Verbesserungen + +

    res.render()

    Diese Methode erzwingt nun asynchrones Verhalten für alle View-Engines, sodass durch View-Engines mit synchroner Implementierung verursachte Fehler vermieden werden, durch die die empfohlene Schnittstelle nicht verwendet werden konnte. + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/de/guide/overriding-express-api.md b/de/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/de/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/de/guide/routing.md b/de/guide/routing.md old mode 100755 new mode 100644 index 42c4a90989..29fdb6431c --- a/de/guide/routing.md +++ b/de/guide/routing.md @@ -1,27 +1,38 @@ --- layout: page title: Weiterleitung in Express +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: de +redirect_from: " " --- # Weiterleitung (Routing) -Der Begriff *Weiterleitung* (Routing) bezieht sich auf die Definition von Anwendungsendpunkten (URIs) und deren Antworten auf Clientanforderungen. Eine Einführung in dieses Routing siehe [Basisrouting](/{{ page.lang }}/starter/basic-routing.html). +Der Begriff _Weiterleitung_ (Routing) bezieht sich auf die Definition von Anwendungsendpunkten (URIs) und deren Antworten auf Clientanforderungen. +Eine Einführung in dieses Routing siehe [Basisrouting](/{{ page.lang }}/starter/basic-routing.html). + +You define routing using methods of the Express `app` object that correspond to HTTP methods; +for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). + +These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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 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 +to the next callback. Der folgende Code ist ein Beispiel für ein sehr einfaches Basisrouting. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
     // respond with "hello world" when a GET request is made to the homepage
    -app.get('/', function(req, res) {
    -  res.send('hello world');
    -});
    -
    -
    +app.get('/', (req, res) => { + res.send('hello world') +}) +```

    Weiterleitungsmethoden

    @@ -29,150 +40,205 @@ Eine Weiterleitungsmethode wird von einer HTTP-Methode abgeleitet und an eine In Der folgende Code ist ein Beispiel für Weiterleitungen, die für die Methoden GET und POST zum Stamm (Root) der Anwendung definiert werden. -
    -
    +```js
     // GET method route
    -app.get('/', function (req, res) {
    -  res.send('GET request to the homepage');
    -});
    +app.get('/', (req, res) => {
    +  res.send('GET request to the homepage')
    +})
     
     // POST method route
    -app.post('/', function (req, res) {
    -  res.send('POST request to the homepage');
    -});
    -
    -
    - -Express unterstützt die folgenden Weiterleitungsmethoden, die den HTTP-Methoden entsprechen: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search` und `connect`. +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` -
    -Verwenden Sie zum Weiterleiten von Methoden, die zu den JavaScript-Variablennamen führen, die Notation "Eckige Klammer". Beispiel: `app['m-search']('/', function ...` -
    - -Es gibt eine spezielle Weiterleitungsmethode, `app.all()`, die nicht von einer HTTP-Methode abgeleitet wird. Diese Methode wird zum Laden von Middlewarefunktionen bei einem Pfad für alle Anforderungsmethoden verwendet. +Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). -Im folgenden Beispiel wird der Handler für Anforderungen zur Weiterleitung "/secret" ausgeführt, um herauszufinden, ob Sie GET-, POST-, PUT-, DELETE- oder andere HTTP-Anforderungsmethoden verwenden, die im [HTTP-Modul](https://nodejs.org/api/http.html#http_http_methods) unterstützt werden. +Es gibt eine spezielle Weiterleitungsmethode, `app.all()`, die nicht von einer HTTP-Methode abgeleitet wird. Diese Methode wird zum Laden von Middlewarefunktionen bei einem Pfad für alle Anforderungsmethoden verwendet. Im folgenden Beispiel wird der Handler für Anforderungen zur Weiterleitung "/secret" ausgeführt, um herauszufinden, ob Sie GET-, POST-, PUT-, DELETE- oder andere HTTP-Anforderungsmethoden verwenden, die im [HTTP-Modul](https://nodejs.org/api/http.html#http_http_methods) unterstützt werden. -
    -
    -app.all('/secret', function (req, res, next) {
    -  console.log('Accessing the secret section ...');
    -  next(); // pass control to the next handler
    -});
    -
    -
    +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +```

    Weiterleitungspfade

    Über Weiterleitungspfade werden in Kombination mit einer Anforderungsmethode die Endpunkte definiert, bei denen Anforderungen erfolgen können. Weiterleitungspfade können Zeichenfolgen, Zeichenfolgemuster oder reguläre Ausdrücke sein. -
    -Express verwendet für den Abgleich der Weiterleitungspfade [path-to-regexp](https://www.npmjs.com/package/path-to-regexp). In der Dokumentation zu "path-to-regexp" finden Sie alle Möglichkeiten zum Definieren von Weiterleitungspfaden. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) ist ein handliches Tool zum Testen von Express-Basisweiterleitungen, auch wenn dieses Tool keine Musterabgleiche unterstützt. -
    +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
    -Abfragezeichenfolgen sind nicht Teil des Weiterleitungspfads. -
    +{% include admonitions/caution.html content=caution-character %} -Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgen. +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} + +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) ist ein handliches Tool zum Testen von Express-Basisweiterleitungen, auch wenn dieses Tool keine Musterabgleiche unterstützt. + +{% endcapture %} + +{% include admonitions/note.html content=note-path-to-regexp %} + +{% capture query-string-note %} + +Query strings are not part of the route path. + +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### Route paths based on strings Dieser Weiterleitungspfad gleicht Weiterleitungsanforderungen zum Stammverzeichnis (`/`) ab. -
    -
    -app.get('/', function (req, res) {
    -  res.send('root');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` Dieser Weiterleitungspfad gleicht Anforderungen mit `/about` ab. -
    -
    -app.get('/about', function (req, res) {
    -  res.send('about');
    -});
    -
    -
    +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` Dieser Weiterleitungspfad gleicht Anforderungen mit `/random.text` ab. -
    -
    -app.get('/random.text', function (req, res) {
    -  res.send('random.text');
    -});
    -
    -
    +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` -Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgemustern. +### Route paths based on string patterns + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} + +{% include admonitions/caution.html content=caution-string-patterns %} Dieser Weiterleitungspfad gleicht `acd` und `abcd` ab. -
    -
    -app.get('/ab?cd', function(req, res) {
    -  res.send('ab?cd');
    -});
    -
    -
    - -Dieser Weiterleitungspfad gleicht `abcd`, `abbcd`, `abbbcd` usw. ab. - -
    -
    -app.get('/ab+cd', function(req, res) {
    -  res.send('ab+cd');
    -});
    -
    -
    - -Dieser Weiterleitungspfad gleicht `abcd`, `abxcd`, `abRABDOMcd`, `ab123cd` usw. ab. - -
    -
    -app.get('/ab*cd', function(req, res) {
    -  res.send('ab*cd');
    -});
    -
    -
    +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` + +Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgemustern. + +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` + +Dies sind einige Beispiele für Weiterleitungspfade auf Basis von Zeichenfolgen. + +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` Dieser Weiterleitungspfad gleicht `/abe` und `/abcde` ab. -
    -
    -app.get('/ab(cd)?e', function(req, res) {
    - res.send('ab(cd)?e');
    -});
    -
    -
    +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` + +### Route paths based on regular expressions -
    -Die Zeichen ?, +, * und () sind Subsets ihrer Entsprechungen in regulären Ausdrücken. Der Bindestrich (-) und der Punkt (.) werden von zeichenfolgebasierten Pfaden förmlich interpretiert. +Dieser Weiterleitungspfad gleicht alle Weiterleitungsnamen ab, die den Buchstaben "a" enthalten. + +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` + +Dieser Weiterleitungspfad gleicht `butterfly` und `dragonfly`, jedoch nicht `butterflyman`, `dragonfly man` usw. + +```js +app.get(/.*fly$/, (req, res) => { + res.send('/.*fly$/') +}) +``` + +

    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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
    +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
    -Beispiele für Weiterleitungspfade auf Basis regulärer Ausdrücke: +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. -Dieser Weiterleitungspfad gleicht alle Weiterleitungsnamen ab, die den Buchstaben "a" enthalten. +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` + +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` + +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} -
    -
    -app.get(/a/, function(req, res) {
    -  res.send('/a/');
    -});
    -
    -
    +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): -Dieser Weiterleitungspfad gleicht `butterfly` und `dragonfly`, jedoch nicht `butterflyman`, `dragonfly man` usw. ab. +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` -
    -
    -app.get(/.*fly$/, function(req, res) {
    -  res.send('/.*fly$/');
    -});
    -
    -
    +{% capture escape-advisory %} + +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %}

    Routenhandler (Weiterleitungsroutinen)

    @@ -182,108 +248,99 @@ Routenhandler können eine Funktion und/oder ein Funktionsarray sein, wie in den Eine einzelne Callback-Funktion kann eine Weiterleitung verarbeiten. Beispiel: -
    -
    -app.get('/example/a', function (req, res) {
    -  res.send('Hello from A!');
    -});
    -
    -
    +```js +app.get('/example/a', (req, res) => { + res.send('Hello from A!') +}) +``` Mehrere Callback-Funktionen können eine Weiterleitung verarbeiten (achten Sie darauf, dass Sie das Objekt `next` angeben). Beispiel: -
    -
    -app.get('/example/b', function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from B!');
    -});
    -
    -
    +```js +app.get('/example/b', (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from B!') +}) +``` Ein Array von Callback-Funktionen kann eine Weiterleitung verarbeiten. Beispiel: -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -var cb2 = function (req, res) {
    -  res.send('Hello from C!');
    +const cb2 = function (req, res) {
    +  res.send('Hello from C!')
     }
     
    -app.get('/example/c', [cb0, cb1, cb2]);
    -
    -
    +app.get('/example/c', [cb0, cb1, cb2]) +``` Eine Kombination aus unabhängigen Funktionen und Funktionsarrays kann eine Weiterleitung verarbeiten. Beispiel: -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/d', [cb0, cb1], function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from D!');
    -});
    -
    -
    +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +```

    Antwortmethoden

    Über die Methoden für das Antwortobjekt (`res`) in der folgenden Tabelle kann eine Antwort an den Client gesendet und der Anforderung/Antwort-Zyklus beendet werden. Wenn keine dieser Methoden über einen Routenhandler aufgerufen wird, bleibt die Clientanforderung im Status "blockiert". -| Methode | Beschreibung -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Gibt eine Eingabeaufforderung zum Herunterladen einer Datei aus. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Beendet den Prozess "Antwort". -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Sendet eine JSON-Antwort. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Sendet eine JSON-Antwort mit JSONP-Unterstützung. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Leitet eine Anforderung um. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Gibt eine Anzeigevorlage aus. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Sendet eine Antwort mit unterschiedlichen Typen. -| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | Sendet eine Datei als Oktett-Stream. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Legt den Antwortstatuscode fest und sendet dessen Zeichenfolgedarstellung als Antworthauptteil. +| Methode | Beschreibung | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Gibt eine Eingabeaufforderung zum Herunterladen einer Datei aus. | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | End the response process. | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Sendet eine JSON-Antwort. | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Sendet eine JSON-Antwort mit JSONP-Unterstützung. | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Leitet eine Anforderung um. | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Render a view template. | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Sendet eine Antwort mit unterschiedlichen Typen. | +| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | Sendet eine Datei als Oktett-Stream. | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Legt den Antwortstatuscode fest und sendet dessen Zeichenfolgedarstellung als Antworthauptteil. |

    app.route()

    -Sie können mithilfe von `app.route()` verkettbare Routenhandler für einen Weiterleitungspfad erstellen. Da der Pfad an einer einzelnen Position angegeben wird, ist das Erstellen modularer Weiterleitungen hilfreich, da Redundanzen und Schreibfehler reduziert werden. Weitere Informationen zu Weiterleitungen finden Sie in der Dokumentation zu [Router()](/{{ page.lang }}/4x/api.html#router). +Sie können mithilfe von `app.route()` verkettbare Routenhandler für einen Weiterleitungspfad erstellen. +Da der Pfad an einer einzelnen Position angegeben wird, ist das Erstellen modularer Weiterleitungen hilfreich, da Redundanzen und Schreibfehler reduziert werden. Weitere Informationen zu Weiterleitungen finden Sie in der Dokumentation zu [Router()](/{{ page.lang }}/4x/api.html#router). Dies ist ein Beispiel für verkettete Routenhandler, die mit der Funktion `app.route()` definiert werden. -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    + .put((req, res) => { + res.send('Update the book') + }) +```

    express.Router

    @@ -293,37 +350,43 @@ Im folgenden Beispiel wird ein Router als Modul erstellt, eine Middlewarefunktio Erstellen Sie eine Routerdatei namens `birds.js` mit dem folgenden Inhalt im Anwendungsverzeichnis: -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const router = express.Router()
     
     // middleware that is specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +const timeLog = (req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +}
    +router.use(timeLog)
    +
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` Laden Sie dann das Routermodul in die Anwendung: -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +const birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` Die Anwendung kann nun Anforderungen an die Pfade `/birds` und `/birds/about` bearbeiten und ruft die Middlewarefunktion `timeLog` auf, die speziell für diese Weiterleitung bestimmt ist. + +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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/de/guide/using-middleware.md b/de/guide/using-middleware.md old mode 100755 new mode 100644 index a1eddb6b0a..0d1baea51c --- a/de/guide/using-middleware.md +++ b/de/guide/using-middleware.md @@ -1,183 +1,229 @@ --- layout: page title: Express-Middleware verwenden +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: de +redirect_from: " " --- # Middleware verwenden Express ist ein Weiterleitungs- und Middleware-Web-Framework, das selbst nur minimale Funktionalität aufweist: Eine Express-Anwendung besteht im Wesentlichen aus einer Reihe von Middlewarefunktionsaufrufen. -*Middlewarefunktionen* sind Funktionen, die Zugriff auf das [Anforderungsobjekt](/{{ page.lang }}/4x/api.html#req) (`req`), das [Antwortobjekt](/{{ page.lang }}/4x/api.html#res) (`res`) und die nächste Middlewarefunktion im Anforderung/Antwort-Zyklus der Anwendung haben. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet. +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the next middleware function in the application's request-response cycle. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet. Über Middlewarefunktionen lassen sich die folgenden Tasks ausführen: -* Ausführen von Code -* Vornehmen von Änderungen an der Anforderung und an Antwortobjekten -* Beenden des Anforderung/Antwort-Zyklus -* Aufrufen der nächsten Middlewarefunktion im Stack +- Ausführen von Code +- Vornehmen von Änderungen an der Anforderung und an Antwortobjekten +- End the request-response cycle. +- Aufrufen der nächsten Middlewarefunktion im Stack Wenn über die aktuelle Middlewarefunktion der Anforderung/Antwort-Zyklus nicht beendet werden kann, muss `next()` aufgerufen werden, um die Steuerung an die nächste Middlewarefunktion zu übergeben. Andernfalls geht die Anforderung in den Status "Blockiert" über. Eine Express-Anwendung kann die folgenden Middlewaretypen verwenden: - - [Middleware auf Anwendungsebene](#middleware.application) - - [Middleware auf Routerebene](#middleware.router) - - [Middleware für die Fehlerbehandlung](#middleware.error-handling) - - [Integrierte Middleware](#middleware.built-in) - - [Middleware anderer Anbieter](#middleware.third-party) +- [Middleware auf Anwendungsebene](#middleware.application) +- [Middleware auf Routerebene](#middleware.router) +- [Middleware für die Fehlerbehandlung](#middleware.error-handling) +- [Integrierte Middleware](#middleware.built-in) +- [Middleware anderer Anbieter](#middleware.third-party) -Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mountpfad laden. Sie können auch eine Reihe von Middlewarefunktionen zusammen laden. Dadurch wird ein Sub-Stack des Middlewaresystems am Mountpunkt erstellt. +Sie können Middleware auf Anwendungsebene und Routerebene mit einem optionalen Mountpfad laden. +Sie können auch eine Reihe von Middlewarefunktionen zusammen laden. Dadurch wird ein Sub-Stack des Middlewaresystems am Mountpunkt erstellt.

    Middleware auf Anwendungsebene

    -Binden Sie Middleware auf Anwendungsebene zu einer Instanz des [Anwendungsobjekts](/{{ page.lang }}/4x/api.html#app), indem Sie die Funktionen `app.use()` und `app.METHOD()` verwenden. `METHOD` ist dabei die HTTP-Methode der Anforderung, die die Middlewarefunktion in Kleinschreibung verarbeitet (wie GET, PU oder POST). +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. Dieses Beispiel zeigt eine Middlewarefunktion ohne Mountpfad. Die Funktion wird immer dann ausgeführt, wenn die Anwendung eine Anforderung erhält. -
    -
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    -
    -
    +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` Dieses Beispiel zeigt eine Middlewarefunktion mit dem Mountpfad `/user/:id`. Die Funktion wird für jede Art von HTTP-Anforderung auf dem Pfad `/user/:id` ausgeführt. -
    -
    -app.use('/user/:id', function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Dieses Beispiel zeigt eine Weiterleitung und deren Handlerfunktion (Middlewaresystem). Die Funktion verarbeitet GET-Anforderungen zum Pfad `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  res.send('USER');
    -});
    -
    -
    - -Dies ist ein Beispiel zum Laden einer Reihe von Middlewarefunktionen an einem Mountpunkt mit einem Mountpfad. Das Beispiel veranschaulicht einen Middleware-Stack, über den Anforderungsinformationen zu einer HTTP-Anforderung zum Pfad `/user/:id` ausgegeben werden. - -
    -
    -app.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.get('/user/:id', (req, res, next) => { + res.send('USER') +}) +``` + +Dies ist ein Beispiel zum Laden einer Reihe von Middlewarefunktionen an einem Mountpunkt mit einem Mountpfad. +Das Beispiel veranschaulicht einen Middleware-Stack, über den Anforderungsinformationen zu einer HTTP-Anforderung zum Pfad `/user/:id` ausgegeben werden. + +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Mit einem Routenhandler können Sie mehrere Weiterleitungen für einen Pfad definieren. Im folgenden Beispiel werden zwei Weiterleitungen für GET-Anforderungen zum Pfad `/user/:id` definiert. Die zweite Weiterleitung verursacht zwar keine Probleme, wird jedoch nie aufgerufen, da durch die erste Weiterleitung der Anforderung/Antwort-Zyklus beendet wird. Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -}, function (req, res, next) {
    -  res.send('User Info');
    -});
    +```js
    +app.get('/user/:id', (req, res, next) => {
    +  console.log('ID:', req.params.id)
    +  next()
    +}, (req, res, next) => {
    +  res.send('User Info')
    +})
     
     // handler for the /user/:id path, which prints the user ID
    -app.get('/user/:id', function (req, res, next) {
    -  res.end(req.params.id);
    -});
    -
    -
    +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) +}) +``` -Wenn Sie den Rest der Middlewarefunktionen eines Weiterleitungs-Middleware-Stack überspringen wollen, rufen Sie `next('route')` auf, um die Steuerung an die nächste Weiterleitung zu übergeben. **HINWEIS**: `next('route')` funktioniert nur in Middlewarefunktionen, die über die Funktionen `app.METHOD()` oder `router.METHOD()` geladen wurden. +Wenn Sie den Rest der Middlewarefunktionen eines Weiterleitungs-Middleware-Stack überspringen wollen, rufen Sie `next('route')` auf, um die Steuerung an die nächste Weiterleitung zu übergeben. + +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden. -
    -
    -app.get('/user/:id', function (req, res, next) {
    +```js
    +app.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next route
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass the control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    -  // render a regular page
    -  res.render('regular');
    -});
    +  else next()
    +}, (req, res, next) => {
    +  // send a regular response
    +  res.send('regular')
    +})
     
    -// handler for the /user/:id path, which renders a special page
    -app.get('/user/:id', function (req, res, next) {
    -  res.render('special');
    -});
    -
    -
    +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +Dies ist ein Beispiel zur Verwendung der Middlewarefunktion `express.static` mit einem ausführlich dargestellten Optionsobjekt: + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

    Middleware auf Routerebene

    Middleware auf Routerebene funktioniert in der gleichen Weise wie Middleware auf Anwendungsebene, mit dem einzigen Unterschied, dass sie an eine Instanz von `express.Router()` gebunden ist. -
    -
    -var router = express.Router();
    -
    -
    +```js +const router = express.Router() +``` + Laden Sie Middleware auf Routerebene über die Funktionen `router.use()` und `router.METHOD()`. + Der folgende Beispielcode repliziert das Middlewaresystem, das oben für die Middleware auf Anwendungsebene gezeigt wird, durch Verwendung von Middleware auf Routerebene. -
    -
    -var app = express();
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const app = express()
    +const router = express.Router()
     
     // a middleware function with no mount path. This code is executed for every request to the router
    -router.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time:', Date.now())
    +  next()
    +})
     
     // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    -router.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    +router.use('/user/:id', (req, res, next) => {
    +  console.log('Request URL:', req.originalUrl)
    +  next()
    +}, (req, res, next) => {
    +  console.log('Request Type:', req.method)
    +  next()
    +})
     
     // a middleware sub-stack that handles GET requests to the /user/:id path
    -router.get('/user/:id', function (req, res, next) {
    +router.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next router
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    +  else next()
    +}, (req, res, next) => {
       // render a regular page
    -  res.render('regular');
    -});
    +  res.render('regular')
    +})
     
     // handler for the /user/:id path, which renders a special page
    -router.get('/user/:id', function (req, res, next) {
    -  console.log(req.params.id);
    -  res.render('special');
    -});
    +router.get('/user/:id', (req, res, next) => {
    +  console.log(req.params.id)
    +  res.render('special')
    +})
     
     // mount the router on the app
    -app.use('/', router);
    -
    -
    +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. + +Dieses Beispiel zeigt einen Middleware-Sub-Stack, über den GET-Anforderungen zum Pfad `/user/:id` verarbeitet werden. + +```js +const express = require('express') +const app = express() +const router = express.Router() + +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) + +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) + +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +```

    Middleware für die Fehlerbehandlung

    @@ -187,14 +233,12 @@ Middleware für die Fehlerbehandlung benötigt immer *vier* Argumente. Sie müss Middlewarefunktionen für die Fehlerbehandlung werden in derselben Weise definiert wie andere Middlewarefunktionen, außer dass Fehlerbehandlungsfunktionen speziell bei Signaturen vier anstatt drei Argumente aufweisen `(err, req, res, next)`: -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Details zu Middleware für die Fehlerbehandlung siehe [Fehlerbehandlung](/{{ page.lang }}/guide/error-handling.html). @@ -202,56 +246,11 @@ Details zu Middleware für die Fehlerbehandlung siehe [Fehlerbehandlung](/{{ pag Seit Version 4.x bestehen bei Express keine Abhängigkeiten zu [Connect](https://github.com/senchalabs/connect) mehr. Mit Ausnahme von `express.static` befinden sich nun alle Middlewarefunktionen, die bisher in Express enthalten waren, in separaten Modulen. Sehen Sie sich hierzu auch die [Liste der Middlewarefunktionen](https://github.com/senchalabs/connect#middleware) an. -

    express.static(root, [options])

    - -Die einzige integrierte Middlewarefunktion in Express ist `express.static`. Diese Funktion basiert auf [serve-static](https://github.com/expressjs/serve-static) und ist zuständig für die statischen Assets einer Express-Anwendung. - -Das Argument `root` gibt das Stammverzeichnis an, von dem aus statische Assets bedient werden. - -Das optionale Objekt `options` kann folgende Eigenschaften aufweisen: - -| Eigenschaft | Beschreibung | Typ | Standard | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | Option für Dateien mit Punkterweiterung (dotfiles). Mögliche Werte sind "allow", "deny" und "ignore" | Zeichenfolge | "ignore" | -| `etag` | Aktiviert oder inaktiviert die etag-Generierung. | Boolesch | `true` | -| `extensions` | Legt Dateierweiterungs-Fallbacks fest. | Bereich | `[]` | -| `index` | Sendet die verzeichnissspezifische indexierte Datei. Bei `false` wird die Verzeichnisindexierung inaktiviert. | Gemischt | "index.html" | - `lastModified` | Legt den Header `Last-Modified` auf das Datum der letzten Änderung der Datei im Betriebssystem fest. Mögliche Werte sind`true` und `false`. | Boolesch | `true` | -| `maxAge` | Legt die Eigenschaft "max-age" des Headers "Cache-Control" in Millisekunden oder als Zeichenfolge im [ms-Format](https://www.npmjs.org/package/ms) fest. | Zahl | 0 | -| `redirect` | Umleitung zu einem abschließenden "/", wenn der Pfadname ein Verzeichnis ist. | Boolesch | `true` | -| `setHeaders` | Funktion zum Festlegen von HTTP-Headern für die Datei. | Funktion | | - -Dies ist ein Beispiel zur Verwendung der Middlewarefunktion `express.static` mit einem ausführlich dargestellten Optionsobjekt: - -
    -
    -var options = {
    -  dotfiles: 'ignore',
    -  etag: false,
    -  extensions: ['htm', 'html'],
    -  index: false,
    -  maxAge: '1d',
    -  redirect: false,
    -  setHeaders: function (res, path, stat) {
    -    res.set('x-timestamp', Date.now());
    -  }
    -}
    -
    -app.use(express.static('public', options));
    -
    -
    - -Es sind mehrere statische Verzeichnisse pro Anwendung möglich: - -
    -
    -app.use(express.static('public'));
    -app.use(express.static('uploads'));
    -app.use(express.static('files'));
    -
    -
    +Die einzige integrierte Middlewarefunktion in Express ist `express.static`. -Details zur Funktion `serve-static` und deren Optionen finden Sie in der Dokumentation zu [serve-static](https://github.com/expressjs/serve-static). +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**

    Middleware anderer Anbieter

    @@ -261,21 +260,17 @@ Installieren Sie das Modul Node.js für die erforderliche Funktionalität. Laden Das folgende Beispiel veranschaulicht das Installieren und Laden der Middlewarefunktion `cookie-parser` für das Cookie-Parsing. -
    -
    +```bash
     $ npm install cookie-parser
    -
    -
    +``` -
    -
    -var express = require('express');
    -var app = express();
    -var cookieParser = require('cookie-parser');
    +```js
    +const express = require('express')
    +const app = express()
    +const cookieParser = require('cookie-parser')
     
     // load the cookie-parsing middleware
    -app.use(cookieParser());
    -
    -
    +app.use(cookieParser()) +``` Eine nicht vollständige Liste zu den Middlewarefunktionen anderer Anbieter, die im Allgemeinen mit Express verwendet werden, finden Sie unter [Middleware anderer Anbieter](../resources/middleware.html). diff --git a/de/guide/using-template-engines.md b/de/guide/using-template-engines.md old mode 100755 new mode 100644 index 5850860b81..abce1f7ffd --- a/de/guide/using-template-engines.md +++ b/de/guide/using-template-engines.md @@ -1,59 +1,61 @@ --- layout: page title: Template-Engines in Express verwenden +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: de +redirect_from: " " --- # Template-Engines in Express verwenden -Bevor über Express Vorlagendateien ausgegeben werden können, müssen die folgenden Anwendungseinstellungen festgelegt werden: +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +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. -* `views`, das Verzeichnis, in dem sich die Vorlagendateien befinden. Beispiel: `app.set('views', './views')` -* `view engine`, die zu verwendende Template-Engine. Beispiel: `app.set('view engine', 'pug')` +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. + +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: + +- `views`, das Verzeichnis, in dem sich die Vorlagendateien befinden. Beispiel: `app.set('views', './views')` + This defaults to the `views` directory in the application root directory. +- `view engine`, die zu verwendende Template-Engine. Beispiel: `app.set('view engine', 'pug')` Installieren Sie dann das entsprechende npm-Paket für die Template-Engine: -
    -
    +```bash
     $ npm install pug --save
    -
    -
    +``` + +
    Express-konforme Template-Engines wie Pug exportieren eine Funktion namens `__express(filePath, options, callback)`, die über die Funktion `res.render()` aufgerufen wird, um den Vorlagencode ausgeben zu können. + +Einige Template-Engines folgen dieser Konvention nicht. Die Bibliothek [Consolidate.js](https://www.npmjs.org/package/consolidate) folgt dieser Konvention, indem alle gängigen Node.js-Template-Engines zugeordnet werden. Daher ist eine reibungslose Funktion in Express gewährleistet. -
    -Express-konforme Template-Engines wie Pug exportieren eine Funktion namens `__express(filePath, options, callback)`, die über die Funktion `res.render()` aufgerufen wird, um den Vorlagencode ausgeben zu können. Einige Template-Engines folgen dieser Konvention nicht. Die Bibliothek [Consolidate.js](https://www.npmjs.org/package/consolidate) folgt dieser Konvention, indem alle gängigen Node.js-Template-Engines zugeordnet werden. Daher ist eine reibungslose Funktion in Express gewährleistet.
    Nach der Festlegung der View-Engine muss die Engine nicht angegeben oder das Template-Engine-Modul nicht in Ihre Anwendung geladen werden. Express lädt das Modul intern (wie unten für das obige Beispiel gezeigt). -
    -
    -app.set('view engine', 'pug');
    -
    -
    +```js +app.set('view engine', 'pug') +``` Erstellen Sie eine Pug-Vorlagendatei namens `index.pug` im Verzeichnis `views` mit dem folgenden Inhalt: -
    -
    +```pug
     html
       head
         title= title
       body
         h1= message
    -
    -
    +``` Dann erstellen Sie eine Weiterleitung, um die Datei `index.pug` auszugeben. Wenn die Eigenschaft `view engine` nicht festgelegt wurde, müssen Sie die Erweiterung der Datei `view` angeben. Andernfalls müssen Sie diese Erweiterung nicht angeben. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` Wenn Sie eine Anforderung zur Homepage ausführen, wird die Datei `index.pug` im HTML-Format ausgegeben. -Weitere Informationen zur Funktionsweise von Template-Engines in Express siehe ["Template-Engines für Express entwickeln"](/{{ page.lang }}/advanced/developing-template-engines.html). +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/de/guide/writing-middleware.md b/de/guide/writing-middleware.md old mode 100755 new mode 100644 index 283fbeaac8..c4d5653244 --- a/de/guide/writing-middleware.md +++ b/de/guide/writing-middleware.md @@ -1,33 +1,35 @@ --- layout: page title: Middleware für die Verwendung in Express-Anwendungen schreiben +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: de +redirect_from: " " --- # Middleware für die Verwendung in Express-Anwendungen schreiben

    Überblick

    -*Middlewarefunktionen* sind Funktionen, die Zugriff auf das [Anforderungsobjekt](/{{ page.lang }}/4x/api.html#req) (`req`), das [Antwortobjekt](/{{ page.lang }}/4x/api.html#res) (`res`) und die nächste Middlewarefunktion im Anforderung/Antwort-Zyklus der Anwendung haben. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet. +_Middlewarefunktionen_ sind Funktionen, die Zugriff auf das [Anforderungsobjekt](/{{ page.lang }}/4x/api.html#req) (`req`), das [Antwortobjekt](/{{ page.lang }}/4x/api.html#res) (`res`) und die nächste Middlewarefunktion im Anforderung/Antwort-Zyklus der Anwendung haben. Die nächste Middlewarefunktion wird im Allgemeinen durch die Variable `next` bezeichnet. Über Middlewarefunktionen lassen sich die folgenden Tasks ausführen: -* Ausführen von Code -* Vornehmen von Änderungen an der Anforderung und an Antwortobjekten -* Beenden des Anforderung/Antwort-Zyklus -* Aufrufen der nächsten Middleware im Stack +- Ausführen von Code +- Vornehmen von Änderungen an der Anforderung und an Antwortobjekten +- End the request-response cycle. +- Aufrufen der nächsten Middleware im Stack Wenn über die aktuelle Middlewarefunktion der Anforderung/Antwort-Zyklus nicht beendet werden kann, muss `next()` aufgerufen werden, um die Steuerung an die nächste Middlewarefunktion zu übergeben. Andernfalls geht die Anforderung in den Status "Blockiert" über. Das folgende Beispiel zeigt die Elemente eines Middlewarefunktionsaufrufs: - - @@ -67,7 +68,7 @@ When using this setting, it is important to ensure there are not multiple, diffe Custom trust implementation. ```js -app.set('trust proxy', function (ip) { +app.set('trust proxy', (ip) => { if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs else return false }) diff --git a/en/guide/database-integration.md b/en/guide/database-integration.md index abe289fe13..5f0956f65c 100644 --- a/en/guide/database-integration.md +++ b/en/guide/database-integration.md @@ -1,10 +1,11 @@ --- layout: page title: Express database integration +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: en redirect_from: "/guide/database-integration.html" --- + # Database integration Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app: @@ -24,7 +25,7 @@ Adding the capability to connect databases to Express apps is just a matter of l * [Elasticsearch](#elasticsearch)
    -These database drivers are among many that are available. For other options, +These database drivers are among many that are available. For other options, search on the [npm](https://www.npmjs.com/) site.
    @@ -34,17 +35,17 @@ search on the [npm](https://www.npmjs.com/) site. ### Installation -```sh +```bash $ npm install cassandra-driver ``` ### Example ```js -var cassandra = require('cassandra-driver') -var client = new cassandra.Client({ contactPoints: ['localhost'] }) +const cassandra = require('cassandra-driver') +const client = new cassandra.Client({ contactPoints: ['localhost'] }) -client.execute('select key from system.local', function (err, result) { +client.execute('select key from system.local', (err, result) => { if (err) throw err console.log(result.rows[0]) }) @@ -56,18 +57,18 @@ client.execute('select key from system.local', function (err, result) { ### Installation -```sh +```bash $ npm install couchbase ``` ### Example ```js -var couchbase = require('couchbase') -var bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') // add a document to a bucket -bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, result) { +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { if (err) { console.log(err) } else { @@ -76,9 +77,9 @@ bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, res }) // get all documents with shoe size 13 -var n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' -var query = N1qlQuery.fromString(n1ql) -bucket.query(query, [13], function (err, result) { +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { if (err) { console.log(err) } else { @@ -93,19 +94,19 @@ bucket.query(query, [13], function (err, result) { ### Installation -```sh +```bash $ npm install nano ``` ### Example ```js -var nano = require('nano')('http://localhost:5984') +const nano = require('nano')('http://localhost:5984') nano.db.create('books') -var books = nano.db.use('books') +const books = nano.db.use('books') // Insert a book document in the books database -books.insert({ name: 'The Art of war' }, null, function (err, body) { +books.insert({ name: 'The Art of war' }, null, (err, body) => { if (err) { console.log(err) } else { @@ -114,7 +115,7 @@ books.insert({ name: 'The Art of war' }, null, function (err, body) { }) // Get a list of all books -books.list(function (err, body) { +books.list((err, body) => { if (err) { console.log(err) } else { @@ -129,23 +130,23 @@ books.list(function (err, body) { ### Installation -```sh +```bash $ npm install level levelup leveldown ``` ### Example ```js -var levelup = require('levelup') -var db = levelup('./mydb') +const levelup = require('levelup') +const db = levelup('./mydb') -db.put('name', 'LevelUP', function (err) { +db.put('name', 'LevelUP', (err) => { if (err) return console.log('Ooops!', err) - db.get('name', function (err, value) { + db.get('name', (err, value) => { if (err) return console.log('Ooops!', err) - console.log('name=' + value) + console.log(`name=${value}`) }) }) ``` @@ -156,15 +157,15 @@ db.put('name', 'LevelUP', function (err) { ### Installation -```sh +```bash $ npm install mysql ``` ### Example ```js -var mysql = require('mysql') -var connection = mysql.createConnection({ +const mysql = require('mysql') +const connection = mysql.createConnection({ host: 'localhost', user: 'dbuser', password: 's3kreee7', @@ -173,7 +174,7 @@ var connection = mysql.createConnection({ connection.connect() -connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) { +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => { if (err) throw err console.log('The solution is: ', rows[0].solution) @@ -188,19 +189,19 @@ connection.end() ### Installation -```sh +```bash $ npm install mongodb ``` ### Example (v2.*) ```js -var MongoClient = require('mongodb').MongoClient +const MongoClient = require('mongodb').MongoClient -MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { if (err) throw err - db.collection('mammals').find().toArray(function (err, result) { + db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) @@ -211,14 +212,14 @@ MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { ### Example (v3.*) ```js -var MongoClient = require('mongodb').MongoClient +const MongoClient = require('mongodb').MongoClient -MongoClient.connect('mongodb://localhost:27017/animals', function (err, client) { +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { if (err) throw err - var db = client.db('animals') + const db = client.db('animals') - db.collection('mammals').find().toArray(function (err, result) { + db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) @@ -235,24 +236,24 @@ If you want an object model driver for MongoDB, look at [Mongoose](https://githu ### Installation -```sh +```bash $ npm install neo4j-driver ``` ### Example ```js -var neo4j = require('neo4j-driver') -var driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) -var session = driver.session() +const session = driver.session() -session.readTransaction(function (tx) { +session.readTransaction((tx) => { return tx.run('MATCH (n) RETURN count(n) AS count') - .then(function (res) { + .then((res) => { console.log(res.records[0].get('count')) }) - .catch(function (error) { + .catch((error) => { console.log(error) }) }) @@ -266,7 +267,7 @@ session.readTransaction(function (tx) { NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). -```sh +```bash $ npm install oracledb ``` @@ -310,21 +311,21 @@ getEmployee(101) ### Installation -```sh +```bash $ npm install pg-promise ``` ### Example ```js -var pgp = require('pg-promise')(/* options */) -var db = pgp('postgres://username:password@host:port/database') +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') db.one('SELECT $1 AS value', 123) - .then(function (data) { + .then((data) => { console.log('DATA:', data.value) }) - .catch(function (error) { + .catch((error) => { console.log('ERROR:', error) }) ``` @@ -335,29 +336,29 @@ db.one('SELECT $1 AS value', 123) ### Installation -```sh +```bash $ npm install redis ``` ### Example ```js -var redis = require('redis') -var client = redis.createClient() +const redis = require('redis') +const client = redis.createClient() -client.on('error', function (err) { - console.log('Error ' + err) +client.on('error', (err) => { + console.log(`Error ${err}`) }) client.set('string key', 'string val', redis.print) client.hset('hash key', 'hashtest 1', 'some value', redis.print) client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print) -client.hkeys('hash key', function (err, replies) { - console.log(replies.length + ' replies:') +client.hkeys('hash key', (err, replies) => { + console.log(`${replies.length} replies:`) - replies.forEach(function (reply, i) { - console.log(' ' + i + ': ' + reply) + replies.forEach((reply, i) => { + console.log(` ${i}: ${reply}`) }) client.quit() @@ -370,17 +371,17 @@ client.hkeys('hash key', function (err, replies) { ### Installation -```sh +```bash $ npm install tedious ``` ### Example ```js -var Connection = require('tedious').Connection -var Request = require('tedious').Request +const Connection = require('tedious').Connection +const Request = require('tedious').Request -var config = { +const config = { server: 'localhost', authentication: { type: 'default', @@ -391,9 +392,9 @@ var config = { } } -var connection = new Connection(config) +const connection = new Connection(config) -connection.on('connect', function (err) { +connection.on('connect', (err) => { if (err) { console.log(err) } else { @@ -402,17 +403,17 @@ connection.on('connect', function (err) { }) function executeStatement () { - request = new Request("select 123, 'hello world'", function (err, rowCount) { + request = new Request("select 123, 'hello world'", (err, rowCount) => { if (err) { console.log(err) } else { - console.log(rowCount + ' rows') + console.log(`${rowCount} rows`) } connection.close() }) - request.on('row', function (columns) { - columns.forEach(function (column) { + request.on('row', (columns) => { + columns.forEach((column) => { if (column.value === null) { console.log('NULL') } else { @@ -431,28 +432,28 @@ function executeStatement () { ### Installation -```sh +```bash $ npm install sqlite3 ``` ### Example ```js -var sqlite3 = require('sqlite3').verbose() -var db = new sqlite3.Database(':memory:') +const sqlite3 = require('sqlite3').verbose() +const db = new sqlite3.Database(':memory:') -db.serialize(function () { +db.serialize(() => { db.run('CREATE TABLE lorem (info TEXT)') - var stmt = db.prepare('INSERT INTO lorem VALUES (?)') + const stmt = db.prepare('INSERT INTO lorem VALUES (?)') - for (var i = 0; i < 10; i++) { - stmt.run('Ipsum ' + i) + for (let i = 0; i < 10; i++) { + stmt.run(`Ipsum ${i}`) } stmt.finalize() - db.each('SELECT rowid AS id, info FROM lorem', function (err, row) { - console.log(row.id + ': ' + row.info) + db.each('SELECT rowid AS id, info FROM lorem', (err, row) => { + console.log(`${row.id}: ${row.info}`) }) }) @@ -465,15 +466,15 @@ db.close() ### Installation -```sh +```bash $ npm install elasticsearch ``` ### Example ```js -var elasticsearch = require('elasticsearch') -var client = elasticsearch.Client({ +const elasticsearch = require('elasticsearch') +const client = elasticsearch.Client({ host: 'localhost:9200' }) @@ -488,9 +489,9 @@ client.search({ } } } -}).then(function (response) { - var hits = response.hits.hits -}, function (error) { +}).then((response) => { + const hits = response.hits.hits +}, (error) => { console.trace(error.message) }) ``` diff --git a/en/guide/debugging.md b/en/guide/debugging.md index 3da5c70233..4f2f04e396 100755 --- a/en/guide/debugging.md +++ b/en/guide/debugging.md @@ -1,37 +1,29 @@ --- layout: page title: Debugging Express +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: en redirect_from: "/guide/debugging.html" --- -# Debugging Express - -Express uses the [debug](https://www.npmjs.com/package/debug) module -internally to log information about route matches, middleware functions that are in use, application mode, -and the flow of the request-response cycle. -
    -`debug` is like an augmented version of `console.log`, but unlike `console.log`, you don't have to -comment out `debug` logs in production code. Logging is turned off by default and can be conditionally turned on by using the `DEBUG` environment variable. -
    +# Debugging Express To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*` when launching your app. -```sh +```bash $ DEBUG=express:* node index.js ``` On Windows, use the corresponding command. -```sh -> set DEBUG=express:* & node index.js +```bash +> $env:DEBUG = "express:*"; node index.js ``` Running this command on the default app generated by the [express generator](/{{ page.lang }}/starter/generator.html) prints the following output: -```sh +```bash $ DEBUG=express:* node ./bin/www express:router:route new / +0ms express:router:layer new / +1ms @@ -77,7 +69,7 @@ $ DEBUG=express:* node ./bin/www When a request is then made to the app, you will see the logs specified in the Express code: -```sh +```bash express:router dispatching GET / +4h express:router query : / +2ms express:router expressInit : / +0ms @@ -95,21 +87,21 @@ When a request is then made to the app, you will see the logs specified in the E express:view render "/projects/example/views/index.pug" +1ms ``` -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. +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` -An application generated by the `express` command also uses the `debug` module and its debug namespace is scoped to the name of the application. +An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application. For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: -```sh +```bash $ DEBUG=sample-app:* node ./bin/www ``` You can specify more than one debug namespace by assigning a comma-separated list of names: -```sh +```bash $ DEBUG=http,mail,express:* node index.js ``` @@ -125,12 +117,14 @@ When running through Node.js, you can set a few environment variables that will | `DEBUG_FD` | File descriptor to write debug output to. | | `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | -__Note:__ The environment variables beginning with `DEBUG_` end up being +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being converted into an Options object that gets used with `%o`/`%O` formatters. See the Node.js documentation for [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) for the complete list. -## Resources +{% endcapture %} -For more information about `debug`, see the [debug](https://www.npmjs.com/package/debug). +{% include admonitions/note.html content=debug-text %} diff --git a/en/guide/error-handling.md b/en/guide/error-handling.md index e8e34b2d80..493dafe8eb 100755 --- a/en/guide/error-handling.md +++ b/en/guide/error-handling.md @@ -1,10 +1,11 @@ --- layout: page title: Express error handling +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: en redirect_from: "/guide/error-handling.html" --- + # Error Handling _Error Handling_ refers to how Express catches and processes errors that @@ -21,7 +22,7 @@ require no extra work. If synchronous code throws an error, then Express will catch and process it. For example: ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { throw new Error('BROKEN') // Express will catch this on its own. }) ``` @@ -31,8 +32,8 @@ and middleware, you must pass them to the `next()` function, where Express will catch and process them. For example: ```js -app.get('/', function (req, res, next) { - fs.readFile('/file-does-not-exist', function (err, data) { +app.get('/', (req, res, next) => { + fs.readFile('/file-does-not-exist', (err, data) => { if (err) { next(err) // Pass errors to Express. } else { @@ -47,8 +48,8 @@ will call `next(value)` automatically when they reject or throw an error. For example: ```js -app.get('/user/:id', async function (req, res, next) { - var user = await getUserById(req.params.id) +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) res.send(user) }) ``` @@ -75,16 +76,16 @@ app.get('/', [ ]) ``` -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 +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: ```js -app.get('/', function (req, res, next) { - setTimeout(function () { +app.get('/', (req, res, next) => { + setTimeout(() => { try { throw new Error('BROKEN') } catch (err) { @@ -103,8 +104,8 @@ Use promises to avoid the overhead of the `try...catch` block or when using func that return promises. For example: ```js -app.get('/', function (req, res, next) { - Promise.resolve().then(function () { +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { throw new Error('BROKEN') }).catch(next) // Errors will be passed to Express. }) @@ -121,7 +122,7 @@ catching, by reducing the asynchronous code to something trivial. For example: ```js app.get('/', [ function (req, res, next) { - fs.readFile('/maybe-valid-file', 'utf-8', function (err, data) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { res.locals.data = data next(err) }) @@ -136,9 +137,9 @@ app.get('/', [ The above example has a couple of trivial statements from 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 +in the chain. Then, the example above tries to process the data. If this fails, then the 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 +the `readFile` callback, then the application might exit and the Express error handlers would not run. Whichever method you use, if you want Express error handlers to be called in and the @@ -169,7 +170,7 @@ response: If you call `next()` with an error after you have started writing the response (for example, if you encounter an error while streaming the -response to the client) the Express default error handler closes the +response to the client), the Express default error handler closes the connection and fails the request. So when you add a custom error handler, you must delegate to @@ -189,6 +190,8 @@ function errorHandler (err, req, res, next) { Note that the default error handler can get triggered if you call `next()` with an error in your code more than once, even if custom error handling middleware is in place. +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html). + ## Writing error handlers Define error-handling middleware functions in the same way as other middleware functions, @@ -196,7 +199,7 @@ except error-handling functions have four arguments instead of three: `(err, req, res, next)`. For example: ```js -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) @@ -205,15 +208,15 @@ app.use(function (err, req, res, next) { You define error-handling middleware last, after other `app.use()` and routes calls; for example: ```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') +const bodyParser = require('body-parser') +const methodOverride = require('method-override') app.use(bodyParser.urlencoded({ extended: true })) app.use(bodyParser.json()) app.use(methodOverride()) -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { // logic }) ``` @@ -226,8 +229,8 @@ regular middleware functions. For example, to define an error-handler for requests made by using `XHR` and those without: ```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') +const bodyParser = require('body-parser') +const methodOverride = require('method-override') app.use(bodyParser.urlencoded({ extended: true @@ -251,7 +254,7 @@ function logErrors (err, req, res, next) { 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 _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. ```js function clientErrorHandler (err, req, res, next) { @@ -272,19 +275,19 @@ function errorHandler (err, req, res, next) { } ``` -If you have a route handler with multiple callback functions you can use the `route` parameter to skip to the next route handler. For example: +If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. For example: ```js app.get('/a_route_behind_paywall', - function checkIfPaidSubscriber (req, res, next) { + (req, res, next) => { if (!req.user.hasPaid) { // continue handling this request next('route') } else { next() } - }, function getPaidContent (req, res, next) { - PaidContent.find(function (err, doc) { + }, (req, res, next) => { + PaidContent.find((err, doc) => { if (err) return next(err) res.json(doc) }) diff --git a/en/guide/migrating-4.md b/en/guide/migrating-4.md index 805a2b901d..32776440f8 100755 --- a/en/guide/migrating-4.md +++ b/en/guide/migrating-4.md @@ -1,10 +1,11 @@ --- layout: page title: Migrating to Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: en redirect_from: "/guide/migrating-4.html" --- + # Moving to Express 4

    Overview

    @@ -100,7 +101,7 @@ In version 4 you can use a variable parameter to define the path where middlewar For example: ```js -app.use('/book/:id', function (req, res, next) { +app.use('/book/:id', (req, res, next) => { console.log('ID:', req.params.id) next() }) @@ -130,13 +131,13 @@ Here is an example of chained route handlers that are defined by using the `app. ```js app.route('/book') - .get(function (req, res) { + .get((req, res) => { res.send('Get a random book') }) - .post(function (req, res) { + .post((req, res) => { res.send('Add a book') }) - .put(function (req, res) { + .put((req, res) => { res.send('Update the book') }) ``` @@ -159,16 +160,16 @@ var express = require('express') var router = express.Router() // middleware specific to this router -router.use(function timeLog (req, res, next) { +router.use((req, res, next) => { console.log('Time: ', Date.now()) next() }) // define the home page route -router.get('/', function (req, res) { +router.get('/', (req, res) => { res.send('Birds home page') }) // define the about route -router.get('/about', function (req, res) { +router.get('/about', (req, res) => { res.send('About birds') }) @@ -350,7 +351,7 @@ if (app.get('env') === 'development') { app.get('/', routes.index) app.get('/users', user.list) -http.createServer(app).listen(app.get('port'), function () { +http.createServer(app).listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ``` @@ -383,7 +384,7 @@ Begin the migration process by installing the required middleware for the Express 4 app and updating Express and Pug to their respective latest version with the following command: -```sh +```bash $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save ``` @@ -393,7 +394,7 @@ Make the following changes to `app.js`: `express.logger`, `express.methodOverride`, `express.session`, `express.bodyParser` and `express.errorHandler` are no longer available on the - `express` object. You must install their alternatives + `express` object. You must install their alternatives manually and load them in the app. 2. You no longer need to load the `app.router` function. @@ -478,7 +479,7 @@ if (app.get('env') === 'development') { } var server = http.createServer(app) -server.listen(app.get('port'), function () { +server.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ``` @@ -487,7 +488,7 @@ server.listen(app.get('port'), function () { Unless you need to work directly with the `http` module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way: ```js -app.listen(app.get('port'), function () { +app.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ``` @@ -498,7 +499,7 @@ app.listen(app.get('port'), function () { The migration process is complete, and the app is now an Express 4 app. To confirm, start the app by using the following command: -```sh +```bash $ node . ``` @@ -517,7 +518,7 @@ The command-line tool to generate an Express app is still If you already have the Express 3 app generator installed on your system, you must uninstall it: -```sh +```bash $ npm uninstall -g express ``` Depending on how your file and directory privileges are configured, @@ -525,7 +526,7 @@ you might need to run this command with `sudo`. Now install the new generator: -```sh +```bash $ npm install -g express-generator ``` @@ -548,7 +549,7 @@ Command options and use largely remain the same, with the following exceptions: Execute the following command to create an Express 4 app: -```sh +```bash $ express app4 ``` @@ -561,11 +562,11 @@ You will also notice that the `app.js` file is now a Node.js module, in contrast After installing the dependencies, start the app by using the following command: -```sh +```bash $ npm start ``` -If you look at the npm start script in the `package.json` file, +If you look at the `npm start` script in the `package.json` file, you will notice that the actual command that starts the app is `node ./bin/www`, which used to be `node app.js` in Express 3. @@ -588,7 +589,7 @@ delete the line that says `module.exports = app;` at the end of the ```js app.set('port', process.env.PORT || 3000) -var server = app.listen(app.get('port'), function () { +var server = app.listen(app.get('port'), () => { debug('Express server listening on port ' + server.address().port) }) ``` @@ -602,6 +603,6 @@ var debug = require('debug')('app4') Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`. You have now moved the functionality of `./bin/www` back to -`app.js`. This change is not recommended, but the exercise helps you +`app.js`. This change is not recommended, but the exercise helps you to understand how the `./bin/www` file works, and why the `app.js` file no longer starts on its own. diff --git a/en/guide/migrating-5.md b/en/guide/migrating-5.md index 8af7c30356..99a5b8fb9f 100755 --- a/en/guide/migrating-5.md +++ b/en/guide/migrating-5.md @@ -1,30 +1,44 @@ --- layout: page title: Migrating to Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: en redirect_from: "/guide/migrating-5.html" --- + # Moving to Express 5

    Overview

    -Express 5.0 is still in the alpha release stage, but here is a preview of the changes that will be in the release and how to migrate your Express 4 app to Express 5. - -Express 5 is not very different from Express 4: The changes to the API are not as significant as from 3.0 to 4.0. Although the basic API remains the same, there are still breaking changes; in other words an existing Express 4 program might not work if you update it to use Express 5. +Express 5 is not very different from Express 4; although it maintains the same basic API, there are still changes that break compatibility with the previous version. Therefore, an application built with Express 4 might not work if you update it to use Express 5. -To install the latest alpha and to preview Express 5, enter the following command in your application root directory: +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: ```sh -$ npm install express@>=5.0.0-alpha.8 --save +npm install "express@5" ``` You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported. -

    Changes in Express 5

    +## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: -Here is the list of changes (as of the alpha 2 release ) that will affect you as a user of Express. -See the [pull request](https://github.com/expressjs/express/pull/2237) for a list of all the planned features. +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). + +

    Changes in Express 5

    **Removed methods and properties** @@ -36,42 +50,80 @@ See the [pull request](https://github.com/expressjs/express/pull/2237) for a lis
  • req.param(name)
  • res.json(obj, status)
  • res.jsonp(obj, status)
  • +
  • res.redirect('back') and res.location('back')
  • +
  • res.redirect(url, status)
  • res.send(body, status)
  • res.send(status)
  • res.sendfile()
  • +
  • router.param(fn)
  • +
  • express.static.mime
  • +
  • express:router debug logs
  • **Changed** + **Improvements** -

    Removed methods and properties

    +## Removed methods and properties If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5. -

    app.del()

    +

    app.del()

    + +Express 5 no longer supports the `app.del()` function. If you use this function, an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. -Express 5 no longer supports the `app.del()` function. If you use this function an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. +Initially, `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. -Initially `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` +{% endcapture %} -

    app.param(fn)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) + +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

    app.param(fn)

    The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. -

    Pluralized method names

    +

    Pluralized method names

    -The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: +The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: `req.acceptsCharset()` is replaced by `req.acceptsCharsets()`. @@ -79,53 +131,411 @@ The following method names have been pluralized. In Express 4, using the old met `req.acceptsLanguage()` is replaced by `req.acceptsLanguages()`. -

    Leading colon (:) in the name for app.param(name, fn)

    +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` +{% endcapture %} + +{% include admonitions/note.html content=codemod-pluralized-methods %} + +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    Leading colon (:) in the name for app.param(name, fn)

    A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon. This should not affect your code if you follow the Express 4 documentation of [app.param](/{{ page.lang }}/4x/api.html#app.param), as it makes no mention of the leading colon. -

    req.param(name)

    +

    req.param(name)

    This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object. -

    res.json(obj, status)

    +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`. -

    res.jsonp(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`. -

    res.send(body, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    + +Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + + +

    res.redirect('back') and res.location('back')

    + +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. -

    res.send(status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) + +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` + +

    res.send(status)

    -Express 5 no longer supports the signature res.send(status), where _`status`_ is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. +Express 5 no longer supports the signature `res.send(status)`, where `status` is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature. -

    res.sendfile()

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) + +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

    res.sendfile()

    The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5. -

    Changed

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## Changed + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. For example: +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` +should be changed to: +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    -

    app.router

    +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +For example: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    The `app.router` object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. -

    req.host

    +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    -In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5 the port number is maintained. +In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5, the port number is maintained. -

    req.query

    +

    req.query

    -In Express 4.7 and Express 5 onwards, the query parser option can accept `false` to disable query string parsing when you want to use your own function for query string parsing logic. +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -

    Improvements

    +

    res.clearCookie

    -

    res.render()

    +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. + +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## Improvements + +

    res.render()

    This method now enforces asynchronous behavior for all view engines, avoiding bugs caused by view engines that had a synchronous implementation and that violated the recommended interface. + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/en/guide/overriding-express-api.md b/en/guide/overriding-express-api.md index bf2a912540..032e3dd625 100644 --- a/en/guide/overriding-express-api.md +++ b/en/guide/overriding-express-api.md @@ -1,16 +1,15 @@ --- layout: page title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. menu: guide -lang: en --- -
    # Overriding the Express API 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: -1. The global protoypes at `express.request` and `express.response`. +1. The global prototypes at `express.request` and `express.response`. 2. App-specific prototypes at `app.request` and `app.response`. Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. @@ -55,7 +54,19 @@ The following code rewrites how the value of `req.ip` is to be derived. Now, it Object.defineProperty(app.request, 'ip', { configurable: true, enumerable: true, - get: function () { return this.get('Client-IP') } + get () { return this.get('Client-IP') } }) ``` -
    + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/en/guide/routing.md b/en/guide/routing.md index 5587e7a853..8ff238884a 100755 --- a/en/guide/routing.md +++ b/en/guide/routing.md @@ -1,8 +1,8 @@ --- layout: page title: Express routing +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: en redirect_from: "/guide/routing.html" --- @@ -12,11 +12,11 @@ _Routing_ refers to how an application's endpoints (URIs) respond to client requ For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/basic-routing.html). You define routing using methods of the Express `app` object that correspond to HTTP methods; -for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, -see [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/4x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/4x/api.html#app.use) to +for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). -These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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. +These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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 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 @@ -25,11 +25,11 @@ to the next callback. The following code is an example of a very basic route. ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() // respond with "hello world" when a GET request is made to the homepage -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('hello world') }) ``` @@ -38,27 +38,27 @@ app.get('/', function (req, res) { A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class. -The following code is an example of routes that are defined for the GET and the POST methods to the root of the app. +The following code is an example of routes that are defined for the `GET` and the `POST` methods to the root of the app. ```js // GET method route -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('GET request to the homepage') }) // POST method route -app.post('/', function (req, res) { +app.post('/', (req, res) => { res.send('POST request to the homepage') }) ``` Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. -For a full list, see [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). -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, 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`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). ```js -app.all('/secret', function (req, res, next) { +app.all('/secret', (req, res, next) => { console.log('Accessing the secret section ...') next() // pass control to the next handler }) @@ -68,24 +68,37 @@ app.all('/secret', function (req, res, next) { 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. -The characters `?`, `+`, `*`, and `()` are subsets of their regular expression counterparts. The hyphen (`-`) and the dot (`.`) are interpreted literally by string-based paths. +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -If you need to use the dollar character (`$`) in a path string, enclose it escaped within `([` and `])`. For example, the path string for requests at "`/data/$book`", would be "`/data/([\$])book`". +{% include admonitions/caution.html content=caution-character %} -
    - Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) is a handy tool for testing basic Express routes, although it does not support pattern matching. -
    +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} + +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [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. + +{% endcapture %} + +{% include admonitions/note.html content=note-path-to-regexp %} + +{% capture query-string-note %} -
    Query strings are not part of the route path. -
    -Here are some examples of route paths based on strings. +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### Route paths based on strings This route path will match requests to the root route, `/`. ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('root') }) ``` @@ -93,7 +106,7 @@ app.get('/', function (req, res) { This route path will match requests to `/about`. ```js -app.get('/about', function (req, res) { +app.get('/about', (req, res) => { res.send('about') }) ``` @@ -101,17 +114,21 @@ app.get('/about', function (req, res) { This route path will match requests to `/random.text`. ```js -app.get('/random.text', function (req, res) { +app.get('/random.text', (req, res) => { res.send('random.text') }) ``` -Here are some examples of route paths based on string patterns. +### Route paths based on string patterns + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} + +{% include admonitions/caution.html content=caution-string-patterns %} This route path will match `acd` and `abcd`. ```js -app.get('/ab?cd', function (req, res) { +app.get('/ab?cd', (req, res) => { res.send('ab?cd') }) ``` @@ -119,7 +136,7 @@ app.get('/ab?cd', function (req, res) { This route path will match `abcd`, `abbcd`, `abbbcd`, and so on. ```js -app.get('/ab+cd', function (req, res) { +app.get('/ab+cd', (req, res) => { res.send('ab+cd') }) ``` @@ -127,7 +144,7 @@ app.get('/ab+cd', function (req, res) { This route path will match `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, and so on. ```js -app.get('/ab*cd', function (req, res) { +app.get('/ab*cd', (req, res) => { res.send('ab*cd') }) ``` @@ -135,17 +152,17 @@ app.get('/ab*cd', function (req, res) { This route path will match `/abe` and `/abcde`. ```js -app.get('/ab(cd)?e', function (req, res) { +app.get('/ab(cd)?e', (req, res) => { res.send('ab(cd)?e') }) ``` -Examples of route paths based on regular expressions: +### Route paths based on regular expressions This route path will match anything with an "a" in it. ```js -app.get(/a/, function (req, res) { +app.get(/a/, (req, res) => { res.send('/a/') }) ``` @@ -153,12 +170,12 @@ app.get(/a/, function (req, res) { This route path will match `butterfly` and `dragonfly`, but not `butterflyman`, `dragonflyman`, and so on. ```js -app.get(/.*fly$/, function (req, res) { +app.get(/.*fly$/, (req, res) => { res.send('/.*fly$/') }) ``` -

    Route parameters

    +

    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. @@ -171,7 +188,7 @@ req.params: { "userId": "34", "bookId": "8989" } To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. ```js -app.get('/users/:userId/books/:bookId', function (req, res) { +app.get('/users/:userId/books/:bookId', (req, res) => { res.send(req.params) }) ``` @@ -194,6 +211,11 @@ Request URL: http://localhost:3000/plantae/Prunus.persica req.params: { "genus": "Prunus", "species": "persica" } ``` +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): ``` @@ -202,13 +224,22 @@ Request URL: http://localhost:3000/user/42 req.params: {"userId": "42"} ``` -
    -Because the regular expression is usually part of a literal string, be sure to escape any \ characters with an additional backslash, for example \\d+. -
    +{% capture escape-advisory %} -
    -In Express 4.x, the * character in regular expressions is not interpreted in the usual way. As a workaround, use {0,} instead of *. This will likely be fixed in Express 5. -
    +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %}

    Route handlers

    @@ -216,10 +247,10 @@ You can provide multiple callback functions that behave like [middleware](/{{ pa 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: +A single callback function can handle a route. For example: ```js -app.get('/example/a', function (req, res) { +app.get('/example/a', (req, res) => { res.send('Hello from A!') }) ``` @@ -227,51 +258,51 @@ app.get('/example/a', function (req, res) { More than one callback function can handle a route (make sure you specify the `next` object). For example: ```js -app.get('/example/b', function (req, res, next) { +app.get('/example/b', (req, res, next) => { console.log('the response will be sent by the next function ...') next() -}, function (req, res) { +}, (req, res) => { res.send('Hello from B!') }) ``` -An array of callback functions can handle a route. For example: +An array of callback functions can handle a route. For example: ```js -var cb0 = function (req, res, next) { +const cb0 = function (req, res, next) { console.log('CB0') next() } -var cb1 = function (req, res, next) { +const cb1 = function (req, res, next) { console.log('CB1') next() } -var cb2 = function (req, res) { +const cb2 = function (req, res) { res.send('Hello from C!') } app.get('/example/c', [cb0, cb1, cb2]) ``` -A combination of independent functions and arrays of functions can handle a route. For example: +A combination of independent functions and arrays of functions can handle a route. For example: ```js -var cb0 = function (req, res, next) { +const cb0 = function (req, res, next) { console.log('CB0') next() } -var cb1 = function (req, res, next) { +const cb1 = function (req, res, next) { console.log('CB1') next() } -app.get('/example/d', [cb0, cb1], function (req, res, next) { +app.get('/example/d', [cb0, cb1], (req, res, next) => { console.log('the response will be sent by the next function ...') next() -}, function (req, res) { +}, (req, res) => { res.send('Hello from D!') }) ``` @@ -280,34 +311,34 @@ app.get('/example/d', [cb0, cb1], function (req, res, next) { 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. -| Method | Description -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Prompt a file to be downloaded. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | End the response process. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Send a JSON response. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Send a JSON response with JSONP support. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirect a request. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Render a view template. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Send a response of various types. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Send a file as an octet stream. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. +| Method | Description | +| --------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/5x/api.html#res.download) | Prompt a file to be downloaded. | +| [res.end()](/{{ page.lang }}/5x/api.html#res.end) | End the response process. | +| [res.json()](/{{ page.lang }}/5x/api.html#res.json) | Send a JSON response. | +| [res.jsonp()](/{{ page.lang }}/5x/api.html#res.jsonp) | Send a JSON response with JSONP support. | +| [res.redirect()](/{{ page.lang }}/5x/api.html#res.redirect) | Redirect a request. | +| [res.render()](/{{ page.lang }}/5x/api.html#res.render) | Render a view template. | +| [res.send()](/{{ page.lang }}/5x/api.html#res.send) | Send a response of various types. | +| [res.sendFile()](/{{ page.lang }}/5x/api.html#res.sendFile) | Send a file as an octet stream. | +| [res.sendStatus()](/{{ page.lang }}/5x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. |

    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](/{{ page.lang }}/4x/api.html#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](/{{ page.lang }}/5x/api.html#router). Here is an example of chained route handlers that are defined by using `app.route()`. ```js app.route('/book') - .get(function (req, res) { + .get((req, res) => { res.send('Get a random book') }) - .post(function (req, res) { + .post((req, res) => { res.send('Add a book') }) - .put(function (req, res) { + .put((req, res) => { res.send('Update the book') }) ``` @@ -321,20 +352,22 @@ The following example creates a router as a module, loads a middleware function Create a router file named `birds.js` in the app directory, with the following content: ```js -var express = require('express') -var router = express.Router() +const express = require('express') +const router = express.Router() // middleware that is specific to this router -router.use(function timeLog (req, res, next) { +const timeLog = (req, res, next) => { console.log('Time: ', Date.now()) next() -}) +} +router.use(timeLog) + // define the home page route -router.get('/', function (req, res) { +router.get('/', (req, res) => { res.send('Birds home page') }) // define the about route -router.get('/about', function (req, res) { +router.get('/about', (req, res) => { res.send('About birds') }) @@ -344,7 +377,7 @@ module.exports = router Then, load the router module in the app: ```js -var birds = require('./birds') +const birds = require('./birds') // ... @@ -352,3 +385,9 @@ 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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/en/guide/using-middleware.md b/en/guide/using-middleware.md index bff4454b03..ad5b80ca25 100644 --- a/en/guide/using-middleware.md +++ b/en/guide/using-middleware.md @@ -1,15 +1,16 @@ --- layout: page title: Using Express middleware +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: en redirect_from: "/guide/using-middleware.html" --- + # Using middleware 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. -_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/4x/api.html#req) (`req`), the [response object](/{{ page.lang }}/4x/api.html#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](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#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 can perform the following tasks: @@ -33,15 +34,15 @@ You can also load a series of middleware functions together, which creates a sub

    Application-level middleware

    -Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/4x/api.html#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](/{{ page.lang }}/5x/api.html#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. This example shows a middleware function with no mount path. The function is executed every time the app receives a request. ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() -app.use(function (req, res, next) { +app.use((req, res, next) => { console.log('Time:', Date.now()) next() }) @@ -51,7 +52,7 @@ This example shows a middleware function mounted on the `/user/:id` path. The fu HTTP request on the `/user/:id` path. ```js -app.use('/user/:id', function (req, res, next) { +app.use('/user/:id', (req, res, next) => { console.log('Request Type:', req.method) next() }) @@ -60,7 +61,7 @@ app.use('/user/:id', function (req, res, next) { 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', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { res.send('USER') }) ``` @@ -69,10 +70,10 @@ Here is an example of loading a series of middleware functions at a mount point, It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. ```js -app.use('/user/:id', function (req, res, next) { +app.use('/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl) next() -}, function (req, res, next) { +}, (req, res, next) => { console.log('Request Type:', req.method) next() }) @@ -83,37 +84,44 @@ Route handlers enable you to define multiple routes for a path. The example belo This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. ```js -app.get('/user/:id', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { console.log('ID:', req.params.id) next() -}, function (req, res, next) { +}, (req, res, next) => { res.send('User Info') }) // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { 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. -**NOTE**: `next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. ```js -app.get('/user/:id', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route') // otherwise pass the control to the next middleware function in this stack else next() -}, function (req, res, next) { +}, (req, res, next) => { // send a regular response res.send('regular') }) // handler for the /user/:id path, which sends a special response -app.get('/user/:id', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { res.send('special') }) ``` @@ -133,8 +141,8 @@ function logMethod (req, res, next) { next() } -var logStuff = [logOriginalUrl, logMethod] -app.get('/user/:id', logStuff, function (req, res, next) { +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { res.send('User Info') }) ``` @@ -144,45 +152,45 @@ app.get('/user/:id', logStuff, function (req, res, next) { Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js -var router = express.Router() +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: ```js -var express = require('express') -var app = express() -var router = express.Router() +const express = require('express') +const app = express() +const router = express.Router() // a middleware function with no mount path. This code is executed for every request to the router -router.use(function (req, res, next) { +router.use((req, res, next) => { console.log('Time:', Date.now()) next() }) // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path -router.use('/user/:id', function (req, res, next) { +router.use('/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl) next() -}, function (req, res, next) { +}, (req, res, next) => { console.log('Request Type:', req.method) next() }) // a middleware sub-stack that handles GET requests to the /user/:id path -router.get('/user/:id', function (req, res, next) { +router.get('/user/:id', (req, res, next) => { // if the user ID is 0, skip to the next router if (req.params.id === '0') next('route') // otherwise pass control to the next middleware function in this stack else next() -}, function (req, res, next) { +}, (req, res, next) => { // render a regular page res.render('regular') }) // handler for the /user/:id path, which renders a special page -router.get('/user/:id', function (req, res, next) { +router.get('/user/:id', (req, res, next) => { console.log(req.params.id) res.render('special') }) @@ -197,22 +205,22 @@ to pass control back out of the router instance. This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. ```js -var express = require('express') -var app = express() -var router = express.Router() +const express = require('express') +const app = express() +const router = express.Router() // predicate the router with a check and bail out when needed -router.use(function (req, res, next) { +router.use((req, res, next) => { if (!req.headers['x-auth']) return next('router') next() }) -router.get('/user/:id', function (req, res) { +router.get('/user/:id', (req, res) => { res.send('hello, user!') }) // use the router and 401 anything falling through -app.use('/admin', router, function (req, res) { +app.use('/admin', router, (req, res) => { res.sendStatus(401) }) ``` @@ -220,13 +228,13 @@ app.use('/admin', router, function (req, res) {

    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. +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)`): +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 -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) @@ -241,9 +249,9 @@ functions that were previously included with Express are now in separate modules Express has the following built-in middleware functions: -- [express.static](/en/4x/api.html#express.static) serves static assets such as HTML files, images, and so on. -- [express.json](/en/4x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** -- [express.urlencoded](/en/4x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**

    Third-party middleware

    @@ -253,14 +261,14 @@ Install the Node.js module for the required functionality, then load it in your The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`. -```sh +```bash $ npm install cookie-parser ``` ```js -var express = require('express') -var app = express() -var cookieParser = require('cookie-parser') +const express = require('express') +const app = express() +const cookieParser = require('cookie-parser') // load the cookie-parsing middleware app.use(cookieParser()) diff --git a/en/guide/using-template-engines.md b/en/guide/using-template-engines.md index 6d51adc86a..c043102e88 100755 --- a/en/guide/using-template-engines.md +++ b/en/guide/using-template-engines.md @@ -1,29 +1,20 @@ --- layout: page 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. menu: guide -lang: en redirect_from: "/guide/using-template-engines.html" --- + # Using template engines with Express -A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces 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. -Some popular template engines that work with Express are [Pug](https://pugjs.org/api/getting-started.html), -[Mustache](https://www.npmjs.com/package/mustache), and [EJS](https://www.npmjs.com/package/ejs). -The [Express application generator](/{{ page.lang }}/starter/generator.html) uses [Jade](https://www.npmjs.com/package/jade) as its default, but it also supports several others. - -See [Template Engines (Express wiki)](https://github.com/expressjs/express/wiki#template-engines) -for a list of template engines you can use with Express. -See also [Comparing JavaScript Templating Engines: Jade, Mustache, Dust and More](https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/). - -
    -**Note**: Jade has been renamed to [Pug](https://www.npmjs.com/package/pug). You can continue to use Jade in your app, and it will work just fine. However if you want the latest updates to the template engine, you must replace Jade with Pug in your app. -
    +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. -To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), set in `app.js` in the default app created by the generator: +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: * `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. @@ -31,26 +22,26 @@ This defaults to the `views` directory in the application root directory. Then install the corresponding template engine npm package; for example to install Pug: -```sh +```bash $ npm install pug --save ```
    -Express-compliant template engines such as Jade and Pug export a function named `__express(filePath, options, callback)`, -which is called by the `res.render()` function to render the template code. +Express-compliant template engines such as Pug export a function named `__express(filePath, options, callback)`, +which `res.render()` calls to render the template code. -Some template engines do not follow this convention. The [Consolidate.js](https://www.npmjs.org/package/consolidate) +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.
    After the view engine is set, you don't have to specify the engine or load the template engine module in your app; -Express loads the module internally, as shown below (for the above example). +Express loads the module internally, for example: ```js app.set('view engine', 'pug') ``` -Create a Pug template file named `index.pug` in the `views` directory, with the following content: +Then, create a Pug template file named `index.pug` in the `views` directory, with the following content: ```pug html @@ -60,18 +51,15 @@ html h1= message ``` -Then create a route to render the `index.pug` file. If the `view engine` property is not set, +Create a route to render the `index.pug` file. If the `view engine` property is not set, you must specify the extension of the `view` file. Otherwise, you can omit it. ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index', { title: 'Hey', message: 'Hello there!' }) }) ``` When you make a request to the home page, the `index.pug` file will be rendered as HTML. -Note: The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. - -To learn more about how template engines work in Express, see: -["Developing template engines for Express"](/{{ page.lang }}/advanced/developing-template-engines.html). +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/en/guide/writing-middleware.md b/en/guide/writing-middleware.md index 8b9506b426..0b02f20312 100755 --- a/en/guide/writing-middleware.md +++ b/en/guide/writing-middleware.md @@ -1,15 +1,16 @@ --- layout: page title: Writing middleware for use in Express apps +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: en redirect_from: "/guide/writing-middleware.html" --- + # Writing middleware for use in Express apps

    Overview

    -_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/4x/api.html#req) (`req`), the [response object](/{{ page.lang }}/4x/api.html#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. +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/4x/api.html#req) (`req`), the [response object](/{{ page.lang }}/4x/api.html#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. Middleware functions can perform the following tasks: @@ -22,9 +23,10 @@ If the current middleware function does not end the request-response cycle, it m The following figure shows the elements of a middleware function call: +
    - +
    + + -
    Pfad (Weiterleitung), für den die Middlewarefunktion angewendet wird.
    @@ -40,59 +42,64 @@ Das folgende Beispiel zeigt die Elemente eines Middlewarefunktionsaufrufs:
    HTTP-Anforderungsargument zur Middlewarefunktion, die nach der geltenden Konvention als "req" bezeichnet wird.
    +Elements of a middleware function call -
    HTTP-Methode, für die die Middlewarefunktion angewendet wird.
    +
    +
    HTTP-Methode, für die die Middlewarefunktion angewendet wird.
    +
    + +Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error. -Dies ist ein Beispiel einer einfachen Express-Anwendung namens "Hello World", für die Sie zwei Middlewarefunktionen definieren: +

    Beispiel

    -
    
    -var express = require('express');
    -var app = express();
    +Here is an example of a simple "Hello World" Express application.
    +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.
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.listen(3000);
    -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -

    Entwicklung

    +app.listen(3000) +``` +

    Dies ist ein Beispiel einer einfachen Express-Anwendung namens "Hello World", für die Sie zwei Middlewarefunktionen definieren:

    Dies ist ein einfaches Beispiel einer Middlewarefunktion namens "myLogger". Diese Funktion gibt lediglich "LOGGED" aus, wenn eine Anforderung zur Anwendung über diese Funktion läuft. Die Middlewarefunktion ist der Variablen `myLogger` zugeordnet. -
    -
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    -
    -
    +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
    -Beachten Sie den Aufruf oben zu `next()`. Durch den Aufruf dieser Funktion wird die nächste Middlewarefunktion in der Anwendung aufgerufen. Die Funktion `next()` ist nicht Teil der Node.js- oder Express-API, sondern das dritte Argument, das an die Middlewarefunktion übergeben wird. Die Funktion `next()` kann jeden beliebigen Namen haben, per Konvention erhält sie jedoch immer den Namen "next". Um Unklarheiten zu vermeiden, sollten Sie immer diese Konvention verwenden. +Beachten Sie den Aufruf oben zu `next()`. Durch den Aufruf dieser Funktion wird die nächste Middlewarefunktion in der Anwendung aufgerufen. +Die Funktion `next()` ist nicht Teil der Node.js- oder Express-API, sondern das dritte Argument, das an die Middlewarefunktion übergeben wird. Die Funktion `next()` kann jeden beliebigen Namen haben, per Konvention erhält sie jedoch immer den Namen "next". +Um Unklarheiten zu vermeiden, sollten Sie immer diese Konvention verwenden.
    +Zum Laden der Middlewarefunktion rufen Sie `app.use()` auf und geben die Middlewarefunktion an. +Beispiel: Durch den folgenden Code wird die Middlewarefunktion `myLogger` vor der Weiterleitung zum Stammverzeichnispfad (/) geladen. -Zum Laden der Middlewarefunktion rufen Sie `app.use()` auf und geben die Middlewarefunktion an. Beispiel: Durch den folgenden Code wird die Middlewarefunktion `myLogger` vor der Weiterleitung zum Stammverzeichnispfad (/) geladen. +```js +const express = require('express') +const app = express() -
    -
    -var express = require('express');
    -var app = express();
    +const myLogger = function (req, res, next) {
    +  console.log('LOGGED')
    +  next()
    +}
     
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    +app.use(myLogger)
     
    -app.use(myLogger);
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -app.listen(3000);
    -
    -
    +app.listen(3000) +``` Sobald die Anwendung eine Anforderung erhält, gibt sie die Nachricht "LOGGED" an das Terminal aus. @@ -102,43 +109,112 @@ Wenn `myLogger` nach der Weiterleitung zum Stammverzeichnispfad geladen wird, er Die Middlewarefunktion `myLogger` gibt einfach eine Nachricht aus und übergibt dann die Anforderung zur nächsten Middlewarefunktion im Stack durch Aufruf der Funktion `next()`. +

    Middleware function requestTime

    + Im nächsten Beispiel wird die Eigenschaft `requestTime` zum Anforderungsobjekt hinzugefügt. Diese Middlewarefunktion erhält den Namen "requestTime". -
    -
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    -
    -
    +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` Die Anwendung verwendet nun die Middlewarefunktion `requestTime`. Außerdem verwendet die Callback-Funktion der Weiterleitung zum Stammverzeichnispfad die Eigenschaft, die die Middlewarefunktion zu `req` (dem Anforderungsobjekt) hinzufügt. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    +const requestTime = function (req, res, next) {
    +  req.requestTime = Date.now()
    +  next()
    +}
     
    -app.use(requestTime);
    +app.use(requestTime)
     
    -app.get('/', function (req, res) {
    -  var responseText = 'Hello World!
    '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) -app.listen(3000); -
    -
    +app.listen(3000) +``` Wenn Sie eine Anforderung zum Stammverzeichnis der Anwendung einleiten, zeigt die Anwendung nun die Zeitmarke Ihrer Anforderung im Browser an. +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    + Da Sie Zugriff auf das Anforderungsobjekt, das Antwortobjekt, die nächste Middlewarefunktion im Stack und die gesamte Node.js-API haben, sind die Möglichkeiten, die Sie mit Middlewarefunktionen haben, nahezu unendlich. Weitere Informationen zur Verwendung von Middleware in Express siehe [ Express-Middleware verwenden](/{{ page.lang }}/guide/using-middleware.html). + +

    Configurable middleware

    + +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. + +File: `my-middleware.js` + +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` + +The middleware can now be used as shown below. + +```js +const mw = require('./my-middleware.js') + +app.use(mw({ option1: '1', option2: '2' })) +``` + +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/de/index.md b/de/index.md index a52f08bb5b..ffacc291f9 100644 --- a/de/index.md +++ b/de/index.md @@ -1,50 +1,61 @@ --- layout: home -title: Express - Node.js-Framework von Webanwendungen +title: Express - Node.js Web Application Framework +description: "Express is a fast, unopinionated, minimalist web framework for Node.js, providing a robust set of features for web and mobile applications." menu: home -lang: de +redirect_from: " " --- +
    - {% include header/header-{{ page.lang }}.html %} -
    -
    +
    - - Schnelles, offenes, unkompliziertes Web-Framework für Node.js + +

    Fast, unopinionated, minimalist web framework for Node.js

    -
    $ npm install express --save
    -
    -
    - +
    $ npm install express --save
    -
    - +
    -
    +```javascript +const express = require('express') +const app = express() +const port = 3000 -
    -
    -

    Webanwendungen

    Express ist ein einfaches und flexibles Node.js-Framework von Webanwendungen, das zahlreiche leistungsfähige Features und Funktionen für Webanwendungen und mobile Anwendungen bereitstellt. -
    - -
    -

    APIs

    Mithilfe unzähliger HTTP-Dienstprogrammmethoden und Middlewarefunktionen gestaltet sich das Erstellen einer leistungsfähigen API schnell und einfach.
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -
    -

    Leistung

    Express bietet eine Thin-Layer-Ebene mit grundlegenden Webanwendungsfunktionen, ohne die bekannten Node.js-Features zu überlagern.
    +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` -
    -
    - diff --git a/de/resources/community.md b/de/resources/community.md old mode 100755 new mode 100644 index 084bc9a468..17ff7d1257 --- a/de/resources/community.md +++ b/de/resources/community.md @@ -1,35 +1,88 @@ --- layout: page title: Express-Community +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: de +redirect_from: " " --- # Community -## Mailing-Liste +## Technical committee -Werden Sie Teil von über 2000 Express-Benutzern oder durchsuchen Sie über 5000 -Diskussionen in der [Google Group](https://groups.google.com/group/express-js). +The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, +and other issues relevant to the Express project. Each meeting is typically announced in an +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is +open to all observers. -## Gitter +The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -Der [expressjs/express-Chatroom](https://gitter.im/expressjs/express) eignet sich besonders für Entwickler, die sich für die täglichen Diskussionen zu Express interessieren. +Members of the Express technical committee are: -## IRC-Channel +**Active:** -Hunderte von Entwicklern, die jeden Tag in #express auf freenode auf Ihre Fragen warten. Wenn Sie Fragen zum Framework haben, schauen Sie doch einfach vorbei und holen Sie sich dazu geeignetes Feedback. +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida -## Beispiele +**Inactive:** -Zeigen Sie Dutzende von [Beispielen](https://github.com/expressjs/express/tree/master/examples) zu Express-Anwendungen im Repository an, das alles abdeckt – von API-Design und Authentifizierung bis zur Einbindung von Template-Engines. +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express is made of many modules + +Unsere lebhafte Community hat zu einer Vielzahl von Erweiterungen, [Middlewaremodulen](/{{ page.lang }}/resources/middleware.html) und Frameworks der höheren Ebene geführt. + +Additionally, the Express community maintains modules in these two GitHub orgs: + +- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. + +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). ## Probleme Wenn Sie Ihrer Meinung nach einen Fehler festgestellt haben oder lediglich ein Feature/eine Funktion anfordern wollen, können Sie in der [Issue Queue](https://github.com/expressjs/express/issues) ein Ticket öffnen. -## Andere Anbieter +## Beispiele + +Zeigen Sie Dutzende von [Beispielen](https://github.com/expressjs/express/tree/master/examples) zu Express-Anwendungen im Repository an, das alles abdeckt – von API-Design und Authentifizierung bis zur Einbindung von Template-Engines. + +## Github Discussions + +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. + +# Branding of Express.js + +## Express.js Logo -Unsere lebhafte Community hat zu einer Vielzahl von Erweiterungen, [Middlewaremodulen](/{{ page.lang }}/resources/middleware.html) und Frameworks der höheren Ebene geführt. Diese können Sie im -[Wiki](https://github.com/expressjs/express/wiki) genauer begutachten. +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/de/resources/contributing.md b/de/resources/contributing.md new file mode 100644 index 0000000000..e37cee3122 --- /dev/null +++ b/de/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/de/resources/glossary.md b/de/resources/glossary.md old mode 100755 new mode 100644 index 71f78f6ef1..991a7a584a --- a/de/resources/glossary.md +++ b/de/resources/glossary.md @@ -1,23 +1,16 @@ --- layout: page title: Express-Glossar +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: de +redirect_from: " " --- # Glossar -### Anforderung - -Eine HTTP-Anforderung. Ein Client übergibt eine HTTP-Anforderungsnachricht an einen Server, der wiederum eine Antwort zurückgibt. Bei der Anforderung muss eine der [Anforderungsmethoden](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) wie GET, POST usw. verwendet werden. - -### Antwort - -Eine HTTP-Antwort. Ein Server gibt eine HTTP-Antwortnachricht an den Client zurück. Die Antwort enthält Informationen zum Beendigungsstatus in Bezug auf die Anforderung und kann im Nachrichtenhauptteil auch angeforderten Inhalt enthalten. - ### Anwendung -Im Allgemeinen besteht eine Anwendung aus einem oder mehreren Programmen, über die Operationen für bestimmte Zwecke ausgeführt werden. Im Zusammenhang mit Express ist eine Anwendung ein Programm, das die auf der Node.js-Plattform laufende Express-API nutzt. Wird auch als [Anwendungsobjekt](/{{ page.lang }}/api.html#express) bezeichnet. +Im Allgemeinen besteht eine Anwendung aus einem oder mehreren Programmen, über die Operationen für bestimmte Zwecke ausgeführt werden. Im Zusammenhang mit Express ist eine Anwendung ein Programm, das die auf der Node.js-Plattform laufende Express-API nutzt. Wird auch als [Anwendungsobjekt](/{{ page.lang }}/api.html#express) bezeichnet. ### API @@ -31,26 +24,42 @@ Schnelles, offenes, unkompliziertes Web-Framework für Node.js-Anwendungen. Im A Eine plattformübergreifende Unterstützungsbibliothek, bei der die asynchrone Ein-/Ausgabe im Mittelpunkt steht. Sie wurde in erster Linie für die Verwendung in Node.js entwickelt. -### Middleware +### middleware Eine Funktion, die über die Weiterleitungsebene in Express vor dem letzten Anforderungshandler aufgerufen wird. Deshalb befindet sich diese Funktion in der Mitte zwischen einer unformatierten Anforderung und der endgültigen beabsichtigten Weiterleitung. Nachfolgend finden Sie einige Details zur Middlewareterminologie: - * `var foo = require('middleware')` bedeutet, dass ein Node.js-Modul *benötigt* oder *verwendet* wird. Dann gibt die Anweisung `var mw = foo()` in der Regel die Middleware zurück. - * `app.use(mw)` bedeutet, dass die *Middleware dem globalen Verarbeitungsstack hinzugefügt wird*. - * `app.get('/foo', mw, function (req, res) { ... })` bedeutet, dass die *Middleware dem "GET /foo"-Verarbeitungsstack hinzugefügt wird*. +- `var foo = require('middleware')` bedeutet, dass ein Node.js-Modul _benötigt_ oder _verwendet_ wird. Dann gibt die Anweisung `var mw = foo()` in der Regel die Middleware zurück. +- `app.use(mw)` bedeutet, dass die _Middleware dem globalen Verarbeitungsstack hinzugefügt wird_. +- `app.get('/foo', mw, function (req, res) { ... })` bedeutet, dass die _Middleware dem "GET /foo"-Verarbeitungsstack hinzugefügt wird_. ### Node.js -Eine Softwareplattform, die für die Erstellung skalierbarer Netzanwendungen verwendet wird. Node.js verwendet JavaScript als Scripting-Sprache und erzielt den hohen Durchsatz durch nicht blockierende Ein-/Ausgabe und eine Ereignisschleife mit einem Thread. Siehe auch [nodejs.org](http://nodejs.org/). **Hinweis**: Der ursprüngliche Name lautet "Node.js". Mittlerweile ist die Bezeichnung "Node" geläufig. +Eine Softwareplattform, die für die Erstellung skalierbarer Netzanwendungen verwendet wird. Node.js verwendet JavaScript als Scripting-Sprache und erzielt den hohen Durchsatz durch nicht blockierende Ein-/Ausgabe und eine Ereignisschleife mit einem Thread. Siehe auch [nodejs.org](http://nodejs.org/). **Hinweis**: Der ursprüngliche Name lautet "Node.js". ### Open-Source Bei Verwendung als Adjektiv muss dieser Begriff mit Bindestrichen gekoppelt werden: Beispiel: "Dies ist eine Open-Source-Software." Siehe auch [Open-Source-Software in Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). -### Router +{% capture english-rules %} -Siehe [Router](/{{ page.lang }}/4x/api.html#router) in der API-Referenz. +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. + +{% endcapture %} + +{% include admonitions/note.html content=english-rules %} + +### Anforderung + +Eine HTTP-Antwort. Ein Server gibt eine HTTP-Antwortnachricht an den Client zurück. Die Antwort enthält Informationen zum Beendigungsstatus in Bezug auf die Anforderung und kann im Nachrichtenhauptteil auch angeforderten Inhalt enthalten. + +### Antwort + +Eine HTTP-Anforderung. Ein Client übergibt eine HTTP-Anforderungsnachricht an einen Server, der wiederum eine Antwort zurückgibt. The response contains completion status information about the request and might also contain requested content in its message body. ### Weiterleitung (Route) Teil einer URL, die eine Ressource angibt. Beispiel: In `http://foo.com/products/id` ist "/products/id" die Weiterleitung. + +### Router + +Siehe [Router](/{{ page.lang }}/4x/api.html#router) in der API-Referenz. diff --git a/de/resources/learning.md b/de/resources/learning.md deleted file mode 100755 index 5529984543..0000000000 --- a/de/resources/learning.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: Zusätzliches Lernen -menu: resources -lang: de ---- - -# Zusätzliches Lernen - -
    Disclaimer: Unendorsed community content.
    - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/de/resources/middleware.md b/de/resources/middleware.md old mode 100755 new mode 100644 index a000551777..6342018377 --- a/de/resources/middleware.md +++ b/de/resources/middleware.md @@ -1,64 +1,43 @@ --- -layout: page +layout: middleware title: Express-Middleware +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: de +redirect_from: " " +module: mw-home --- -# Middleware anderer Anbieter +## Express-Middleware Nachfolgend sind einige Express-Middlewaremodule aufgeführt: - - [body-parser](https://github.com/expressjs/body-parser): Bisher: `express.bodyParser`, `json` und `urlencoded`. - Siehe auch: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): Bisher `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): Connect/Express-Middlewaremodule für optimales Image-Serving. Wechselt Images (wenn möglich) zu `.webp` oder `.jxr`. - - [connect-timeout](https://github.com/expressjs/timeout): Bisher: `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): Bisher: `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): Bisher: `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): Bisher: `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): Bisher: `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): Entwicklungstool, mit dem eine Registerkarte mit Informationen zu Vorlagenvariablen (lokalen Variablen), zur aktuellen Sitzung, zu hilfreichen Anforderungsdaten usw. Ihrer Anwendung hinzugefügt werden können. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): Express-Middlewaremodul für die Filterung von Teilen von JSON-Antworten auf Basis der Abfragezeichenfolge `fields` durch Verwendung der Google-API Partial Response. - - [express-session](https://github.com/expressjs/session): Bisher: `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): Express-Middlewaremodul für die Verwendung eines CDN (Content Delivery Network) für statische Assets mit Unterstützung mehrerer Hosts (Beispiel: cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): Express-Middlewaremodul für Benutzer, die hohen Wert auf abschließende Schrägstriche legen. - - [express-stormpath](https://github.com/stormpath/stormpath-express): Express-Middlewaremodul für Benutzerspeicher, Authentifizierung, Autorisierung, SSO und Datensicherheit. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): Middlewaremodul für die Umleitung von HTTP-Anforderungen mit Großbuchstaben in eine kanonische Form mit Kleinbuchstaben. - - [helmet](https://github.com/helmetjs/helmet): Modul zur Sicherung Ihrer Anwendungen durch Festlegung verschiedener HTTP-Header. - - [join-io](https://github.com/coderaiser/join-io "join-io"): Modul für die Verknüpfung von Dateien während der Verarbeitung, um die Anzahl der Anforderungen zu reduzieren. - - [method-override](https://github.com/expressjs/method-override): Bisher: `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): Bisher: `logger` - - [passport](https://github.com/jaredhanson/passport): Express-Middlewaremodul für die Authentifizierung. - - [response-time](https://github.com/expressjs/response-time): Bisher: `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): Bisher: `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): Bisher: `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): Modul für statischen Inhalt. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): URLs mit elektronischem Fingerabdruck oder Caching-Headern für statische Assets einschließlich Unterstützung für eine oder mehrere externe Domänen. - - [vhost](https://github.com/expressjs/vhost): Bisher: `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): Express-Middlewaremodul, das allgemeine Helper-Methoden für Ansichten bereitstellt. - - [sriracha-admin](https://github.com/hdngr/siracha): Express-Middlewaremodul, das eine Administratorsite für Mongoose dynamisch generiert. +| [express-slash](https://github.com/ericf/express-slash): Express-Middlewaremodul für Benutzer, die hohen Wert auf abschließende Schrägstriche legen. | Beschreibung | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | -Einige Middlewaremodule, die bisher zu Connect gehörten, werden vom Connect/Express-Team nicht mehr unterstützt. Diese Module werden durch ein alternatives oder besseres Modul ersetzt. Verwenden Sie eine der folgenden Alternativen: +## Informationen zu weiteren Middlewaremodulen siehe: - - express.cookieParser - - [cookies](https://github.com/jed/cookies) und [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) +These are some additional popular middleware modules. -Informationen zu weiteren Middlewaremodulen siehe: +{% include community-caveat.html %} - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| [express-slash](https://github.com/ericf/express-slash): Express-Middlewaremodul für Benutzer, die hohen Wert auf abschließende Schrägstriche legen. | Beschreibung | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet): Modul zur Sicherung Ihrer Anwendungen durch Festlegung verschiedener HTTP-Header. | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport): Express-Middlewaremodul für die Authentifizierung. | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/de/resources/middleware/body-parser.md b/de/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/de/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/de/resources/middleware/compression.md b/de/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/de/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/de/resources/middleware/connect-rid.md b/de/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/de/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/de/resources/middleware/cookie-parser.md b/de/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/de/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/de/resources/middleware/cookie-session.md b/de/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/de/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/de/resources/middleware/cors.md b/de/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/de/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/de/resources/middleware/errorhandler.md b/de/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/de/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/de/resources/middleware/method-override.md b/de/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/de/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/de/resources/middleware/morgan.md b/de/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/de/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/de/resources/middleware/multer.md b/de/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/de/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/de/resources/middleware/response-time.md b/de/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/de/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/de/resources/middleware/serve-favicon.md b/de/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/de/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/de/resources/middleware/serve-index.md b/de/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/de/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/de/resources/middleware/serve-static.md b/de/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/de/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/de/resources/middleware/session.md b/de/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/de/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/de/resources/middleware/timeout.md b/de/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/de/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/de/resources/middleware/vhost.md b/de/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/de/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/de/resources/utils.md b/de/resources/utils.md new file mode 100644 index 0000000000..0fd21eea69 --- /dev/null +++ b/de/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/de/starter/basic-routing.md b/de/starter/basic-routing.md old mode 100755 new mode 100644 index e59ce41246..eaed71d21a --- a/de/starter/basic-routing.md +++ b/de/starter/basic-routing.md @@ -1,24 +1,24 @@ --- layout: page title: Basisrouting in Express +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: de +redirect_from: " " --- # Basisrouting -Per *Routing* wird bestimmt, wie eine Antwort auf eine Clientanforderung an einem bestimmten Endpunkt antwortet. Dies ist eine URI (oder ein Pfad) und eine bestimmte HTTP-Anforderungsmethode (GET, POST usw.). +Per _Routing_ wird bestimmt, wie eine Antwort auf eine Clientanforderung an einem bestimmten Endpunkt antwortet. Dies ist eine URI (oder ein Pfad) und eine bestimmte HTTP-Anforderungsmethode (GET, POST usw.). Jede Weiterleitung (Route) kann eine oder mehrere Handlerfunktionen haben, die ausgeführt werden, wenn die Weiterleitung abgeglichen wird. Weiterleitungsdefinitionen haben die folgende Struktur: -
    -
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` -Bedeutung: +Where: - `app` ist eine Instanz von `express`. - `METHOD` ist eine [HTTP-Anforderungsmethode](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol). @@ -33,42 +33,36 @@ Die folgenden Beispiele veranschaulichen das Definieren einfacher Weiterleitunge Antworten Sie mit `Hello World!` auf der Homepage: -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -Antworten Sie auf POST-Anforderungen auf die Weiterleitung zum Stammverzeichnis (`/`), der Homepage der Anwendung: +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` Antworten Sie auf eine PUT-Anforderung zur Weiterleitung `/user`: -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` Antworten Sie auf eine DELETE-Anforderung zur Weiterleitung `/user`: -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` Details zum Thema Routing finden Sie in der entsprechenden [Routinganleitung](/{{ page.lang }}/guide/routing.html). + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/de/starter/examples.md b/de/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/de/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/de/starter/faq.md b/de/starter/faq.md old mode 100755 new mode 100644 index 89ba8e6a52..178246ecea --- a/de/starter/faq.md +++ b/de/starter/faq.md @@ -1,8 +1,9 @@ --- layout: page title: Häufig gestellte Fragen zu Express +description: Finden Sie Antworten auf häufig gestellte Fragen zu Express.js, darunter Themen wie Anwendungsstruktur, Models, Authentifizierung, Template-Engines, Fehlerbehandlung und mehr. menu: starter -lang: de +redirect_from: " " --- # Häufig gestellte Fragen @@ -13,14 +14,13 @@ Auf diese Frage gibt es keine verbindliche Antwort. Die Antwort hängt vom Umfan Weiterleitungen und andere anwendungsspezifische Logik können in einer beliebigen Anzahl von Dateien und in jeder von Ihnen bevorzugten Verzeichnisstruktur vorkommen. Die folgenden Beispiele sollen als Entscheidungshilfe dienen: - -* [Weiterleitungslisten](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Weiterleitungszuordnung](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [Controller im MVC-Stil](https://github.com/expressjs/express/tree/master/examples/mvc) +- [Weiterleitungslisten](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [Weiterleitungszuordnung](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [Controller im MVC-Stil](https://github.com/expressjs/express/tree/master/examples/mvc) Darüber hinaus gibt es Erweiterungen anderer Anbieter für Express, die zur Vereinfachung einiger dieser Muster beitragen: -* [Weiterleitung mit "express-resource"](https://github.com/expressjs/express-resource) +- [Weiterleitung mit "express-resource"](https://github.com/expressjs/express-resource) ## Wie definiere ich Modelle? @@ -30,40 +30,51 @@ Express hat keine Vorstellungen von einer Datenbank. Dieses Konzept bleibt Node- ## Wie kann ich Benutzer authentifizieren? -Die Authentifizierung ist ein weiterer meinungsstarker Bereich, in den Express nicht eingreift. Sie können ein Authentifizierungsschema nach Ihren Vorstellungen verwenden. Ein einfaches Benutzername/Kennwort-Schema können Sie in [diesem Beispiel](https://github.com/expressjs/express/tree/master/examples/auth) sehen. - +Die Authentifizierung ist ein weiterer meinungsstarker Bereich, in den Express nicht eingreift. Sie können ein Authentifizierungsschema nach Ihren Vorstellungen verwenden. +Ein einfaches Benutzername/Kennwort-Schema können Sie in [diesem Beispiel](https://github.com/expressjs/express/tree/master/examples/auth) sehen. ## Welche Template-Engines unterstützt Express? -Express unterstützt jede Template-Engine, die der `(path, locals, callback)`-Signatur entspricht. Informationen zur Normalisierung von Template-Engine-Schnittstellen und -Caching siehe das Projekt [consolidate.js](https://github.com/visionmedia/consolidate.js). Nicht aufgelistete Template-Engines können trotzdem die Express-Signatur unterstützen. +Express unterstützt jede Template-Engine, die der `(path, locals, callback)`-Signatur entspricht. +Informationen zur Normalisierung von Template-Engine-Schnittstellen und -Caching siehe das Projekt [consolidate.js](https://github.com/visionmedia/consolidate.js). Nicht aufgelistete Template-Engines können trotzdem die Express-Signatur unterstützen. + +For more information, see [Using template engines with Express](/{{page.lang}}/guide/using-template-engines.html). ## Wie handhabe ich 404-Antworten? In Express sind 404-Antworten nicht das Ergebnis eines Fehlers, sodass diese Antworten von der Fehlerbehandlungsroutine nicht erfasst werden. Dieses Verhalten ist damit zu erklären, dass eine 404-Antwort einfach angibt, dass keine weiteren Arbeiten auszuführen sind. In anderen Worten: Express hat alle Middlewarefunktionen und Weiterleitungen ausgeführt und festgestellt, dass keine Funktion eine Antwort zurückgegeben hat. Sie müssen also bei der Handhabung der 404-Antwort nur eine Middlewarefunktion am Ende des Stacks (unterhalb von allen anderen Funktionen) hinzufügen: -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` + +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## Wie richte ich eine Fehlerbehandlungsroutine ein? Middleware für die Fehlerbehandlung wird in derselben Weise definiert wie andere Middleware; außer dass sie vier anstatt drei Argumente aufweist. Dies gilt speziell bei der Signatur `(err, req, res, next)`: -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Weitere Informationen siehe [Fehlerbehandlung](/{{ page.lang }}/guide/error-handling.html). ## Wie gebe ich normales HTML-Format aus? -Das ist nicht Ihre Aufgabe! Sie müssen kein HTML-Format mit der Funktion `res.render()` ausgeben. Verwenden Sie die Funktion `res.sendFile()`, wenn Sie es mit einer bestimmten Datei zu tun haben. Wenn Sie viele Assets aus einem Verzeichnis bedienen müssen, verwenden Sie die Middlewarefunktion `express.static()`. +Das ist nicht Ihre Aufgabe! Sie müssen kein HTML-Format mit der Funktion `res.render()` ausgeben. +Verwenden Sie die Funktion `res.sendFile()`, wenn Sie es mit einer bestimmten Datei zu tun haben. +Wenn Sie viele Assets aus einem Verzeichnis bedienen müssen, verwenden Sie die Middlewarefunktion `express.static()`. + +## Welche Version von Node.js benötigt Express? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/de/starter/generator.md b/de/starter/generator.md old mode 100755 new mode 100644 index 11be303f78..f59f6e1d1a --- a/de/starter/generator.md +++ b/de/starter/generator.md @@ -1,29 +1,34 @@ --- layout: page title: Express-Anwendungsgenerator +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: de +redirect_from: " " --- # Express-Anwendungsgenerator Mit dem Application Generator Tool `express` können Sie innerhalb kürzester Zeit ein Anwendungsgerüst erstellen. -Installieren Sie `express` mit dem folgenden Befehl: +You can run the application generator with the `npx` command (available in Node.js 8.2.0). -
    -
    -$ npm install express-generator -g
    -
    -
    +```bash +$ npx express-generator +``` + +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` Zeigen Sie die Befehlsoptionen mit der Option `-h` an: -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -34,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` -Im folgenden Beispiel wird eine Express-Anwendung mit dem Namen _myapp_ im aktuellen Arbeitsverzeichnis erstellt: +Im folgenden Beispiel wird eine Express-Anwendung mit dem Namen _myapp_ im aktuellen Arbeitsverzeichnis erstellt: The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -64,40 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` Installieren Sie dann Abhängigkeiten: -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` -Führen Sie unter MacOS oder Linux die Anwendung mit diesem Befehl aus: +Verwenden Sie unter Windows diesen Befehl: -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` -Verwenden Sie unter Windows diesen Befehl: +Führen Sie unter MacOS oder Linux die Anwendung mit diesem Befehl aus: -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` + +On Windows PowerShell, use this command: + +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` Laden Sie dann `http://localhost:3000/` in Ihren Browser, um auf die Anwendung zuzugreifen. Die erstellte Anwendung hat die folgende Verzeichnisstruktur: -
    -
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -117,9 +118,10 @@ Die erstellte Anwendung hat die folgende Verzeichnisstruktur:
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    Die vom Generator erstellte Anwendungsstruktur ist nur eine der vielen Möglichkeiten, Express-Anwendungen zu strukturieren. Sie können diese Struktur verwenden oder sie an Ihre Anforderungen anpassen.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/de/starter/hello-world.md b/de/starter/hello-world.md old mode 100755 new mode 100644 index 3534baba3b..3fd33c8743 --- a/de/starter/hello-world.md +++ b/de/starter/hello-world.md @@ -1,8 +1,9 @@ --- layout: page title: Beispiel "Hello World" in Express +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: de +redirect_from: " " --- # Beispiel "Hello World" @@ -11,12 +12,7 @@ lang: de Dies ist wohl die einfachste Express-Anwendung, die Sie erstellen können. Es handelt sich um eine Anwendung mit nur einer Datei und — *nicht* das, was Sie mit dem [Express Generator](/{{ page.lang }}/starter/generator.html) erhalten würden. Mit dem Generator würde das Gerüst für eine vollständige Anwendung mit zahlreichen JavaScript-Dateien, Jade-Vorlagen und Unterverzeichnissen für verschiedene Zwecke erstellt werden.
    -Erstellen Sie zunächst ein Verzeichnis namens `myapp`, wechseln Sie in das Verzeichnis und führen Sie `npm init` aus. Installieren Sie dann `express` als Abhängigkeit, wie im [Installationshandbuch](/{{ page.lang }}/starter/installing.html) beschrieben. - -Erstellen Sie im Verzeichnis `myapp` eine Datei namens `app.js` und fügen Sie den folgenden Code hinzu: - -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -26,24 +22,26 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    -
    +``` -Die Anwendung startet einen Server und ist an Port 3000 empfangsbereit für Verbindungen. Die Anwendung antwortet mit "Hello World!" auf Anforderungen zur Stamm-URL (`/`) oder zu *route*. Bei jedem anderen Pfad lautet die Antwort **404 Not Found**. +Die Anwendung startet einen Server und ist an Port 3000 empfangsbereit für Verbindungen. Die Anwendung antwortet mit "Hello World!" auf Anforderungen zur Stamm-URL (`/`) oder zu _route_. Bei jedem anderen Pfad lautet die Antwort **404 Not Found**. -
    -`req` (Anforderung) und `res` (Antwort) sind genau dieselben Objekte, die Node bereitstellt. Sie können also `req.pipe()`, `req.on('data', callback)` und alle anderen Tasks, die Sie ausführen wollen, ohne Express ausführen. -
    +### Running Locally + +Erstellen Sie zunächst ein Verzeichnis namens `myapp`, wechseln Sie in das Verzeichnis und führen Sie `npm init` aus. Installieren Sie dann `express` als Abhängigkeit, wie im [Installationshandbuch](/{{ page.lang }}/starter/installing.html) beschrieben. + +Erstellen Sie im Verzeichnis `myapp` eine Datei namens `app.js` und fügen Sie den folgenden Code hinzu: + +
    `req` (Anforderung) und `res` (Antwort) sind genau dieselben Objekte, die Node bereitstellt. Sie können also `req.pipe()`, `req.on('data', callback)` und alle anderen Tasks, die Sie ausführen wollen, ohne Express ausführen.
    Führen Sie die Anwendung mit dem folgenden Befehl aus: -
    -
    +```bash
     $ node app.js
    -
    -
    +``` Laden Sie dann [http://localhost:3000/](http://localhost:3000/) in einen Browser, um die Ausgabe zu sehen. +### [Previous: Installing ](/{{ page.lang }}/starter/installing.html)    [Next: Express Generator ](/{{ page.lang }}/starter/generator.html) diff --git a/de/starter/installing.md b/de/starter/installing.md old mode 100755 new mode 100644 index e47a9c1cb9..e745549656 --- a/de/starter/installing.md +++ b/de/starter/installing.md @@ -1,55 +1,53 @@ --- layout: page title: Express installieren +description: Erfahren Sie, wie Sie Express.js in Ihrer Node.js-Umgebung installieren, wie Sie Ihr Projektverzeichnis aufsetzen und Abhängigkeiten mit npm verwalten. menu: starter -lang: de +redirect_from: " " --- # Installation Angenommen, Sie haben [Node.js](https://nodejs.org/) bereits installiert. Erstellen Sie ein Verzeichnis für Ihre Anwendung und definieren Sie dieses Verzeichnis als Ihr Arbeitsverzeichnis. -
    -
    +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher.
    +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher.
    +
    +```bash
     $ mkdir myapp
     $ cd myapp
    -
    -
    +``` -Erstellen Sie mit dem Befehl `npm init` eine Datei namens `package.json` für Ihre Anwendung. Weitere Informationen zur Funktionsweise von `package.json` finden Sie in den [Angaben zur Handhabung der npm-Datei package.json](https://docs.npmjs.com/files/package.json). +Erstellen Sie mit dem Befehl `npm init` eine Datei namens `package.json` für Ihre Anwendung. +Weitere Informationen zur Funktionsweise von `package.json` finden Sie in den [Angaben zur Handhabung der npm-Datei package.json](https://docs.npmjs.com/files/package.json). -
    -
    +```bash
     $ npm init
    -
    -
    +``` -Dieser Befehl fordert Sie zur Eingabe verschiedener Angaben wie Name und Version Ihrer Anwendung auf. Für den Moment reicht es, die Eingabetaste zu drücken und die Standardwerte für die meisten Angaben zu akzeptieren. Es gilt jedoch folgende Ausnahme: +Dieser Befehl fordert Sie zur Eingabe verschiedener Angaben wie Name und Version Ihrer Anwendung auf. +For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception: -
    -
    +```
     entry point: (index.js)
    -
    -
    +``` Geben Sie `app.js` oder einen Namen Ihrer Vorstellung als Namen für die Hauptdatei ein. Wenn dieser Name `index.js` lauten soll, drücken Sie die Eingabetaste, um den vorgeschlagenen Standarddateinamen zu akzeptieren. Installieren Sie jetzt Express im Verzeichnis `myapp` und speichern Sie es in der Abhängigkeitsliste. Beispiel: -
    -
    -$ npm install express --save
    -
    -
    +```bash +$ npm install express +``` Wenn Sie Express vorübergehend installieren und nicht zur Abhängigkeitsliste hinzufügen wollen, geben Sie die Option `--save` nicht an: -
    -
    -$ npm install express
    -
    -
    +```bash +$ npm install express --no-save +```
    Node-Module, die mit der Option `--save` installiert werden, werden zur `Abhängigkeitsliste` in der Datei `package.json` hinzugefügt. Danach werden bei der Ausführung von `npm install` im Verzeichnis `app` automatisch alle Module in der Abhängigkeitsliste installiert.
    + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/de/starter/static-files.md b/de/starter/static-files.md old mode 100755 new mode 100644 index 9c6197ee3e..620afe0dc0 --- a/de/starter/static-files.md +++ b/de/starter/static-files.md @@ -1,72 +1,79 @@ --- layout: page title: Statische Dateien in Express bereitstellen +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: de +redirect_from: " " --- # Statische Dateien in Express bereitstellen Wenn Sie statische Dateien wie Bilder, CSS-Dateien und JavaScript-Dateien bereitstellen wollen, verwenden Sie die in Express integrierte Middlewarefunktion `express.static`. -Übergeben Sie den Namen des Verzeichnisses mit den statischen Assets an die Middlewarefunktion `express.static`, um direkt mit dem Bereitstellen der Dateien zu beginnen. Beispiel: Verwenden Sie den folgenden Code, um Bilder, CSS-Dateien und JavaScript-Dateien in einem Verzeichnis namens `public` bereitzustellen: +The function signature is: -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +Beispiel: Verwenden Sie den folgenden Code, um Bilder, CSS-Dateien und JavaScript-Dateien in einem Verzeichnis namens `public` bereitzustellen: + +```js +app.use(express.static('public')) +``` Jetzt können Sie die Dateien laden, die sich im Verzeichnis `public` befinden: -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +``` -
    -Express sucht nach den Dateien, die sich auf das Verzeichnis mit den statischen Assets beziehen. Der Name dieses Verzeichnisses ist also nicht Teil der URL.
    +
    Express sucht nach den Dateien, die sich auf das Verzeichnis mit den statischen Assets beziehen. Der Name dieses Verzeichnisses ist also nicht Teil der URL.
    Wenn Sie mehrere Verzeichnisse mit statischen Assets verwenden wollen, rufen Sie die Middlewarefunktion `express.static` mehrmals auf: -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` Express sucht in der Reihenfolge nach den Dateien, in der sie die Verzeichnisse mit den statischen Assets über die Middlewarefunktion `express.static` festgelegt haben. -Wenn Sie ein Präfix für einen virtuellen Pfad (in dem der Pfad nicht wirklich im Dateisystem existiert) für Dateien festlegen wollen, die über die Funktion `express.static` bereitgestellt werden, [müssen Sie einen Mountpfad](/{{ page.lang }}/4x/api.html#app.use) für das Verzeichnis mit den statischen Assets wie unten gezeigt angeben: +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` Jetzt können Sie die Dateien, die sich im Verzeichnis `public` befinden, aus dem Pfadpräfix `/static` laden. -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` Der Pfad, den Sie für die Funktion `express.static` angeben, ist jedoch relativ zum Verzeichnis, aus dem Sie Ihren Prozess `node` starten. Wenn Sie die Express-Anwendung aus einem anderen Verzeichnis ausführen, ist es sicherer, den absoluten Pfad des Verzeichnisses zu verwenden, das Sie bereitstellen wollen: -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +```js +const path = require('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.html). + +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/de/support/index.md b/de/support/index.md new file mode 100644 index 0000000000..3b0c7ad325 --- /dev/null +++ b/de/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +title: Version-Support +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. +menu: support +--- + +# Version-Support + +Es wird nur die neueste Version einer bestimmten Hauptversionslinie unterstützt. + +Versionen, die EOL (End-of-Life) sind, _können_ Updates für kritische Sicherheitslücken erhalten, aber das Express-Team bietet keine Garantie und plant nicht, Fixes für gefundene Fehler zu entwickeln oder zu veröffentlichen. + +| Major Version | Minimale Node.js Version | Support Startdatum | Support-Enddatum | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------ | ---------------------------------------------------------------- | +| [**v5.x**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **läuft derzeit**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **läuft derzeit**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | Oktober 2012 | Juli 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | März 2011 | Juli 2012 | +| **v1.x**{: .eol } | 0.2.0 | Dezember 2010 | März 2011 | +| **v0.14.x**{: .eol } | 0.1.98 | Dezember 2010 | Dezember 2010 | + +## Kommerzielle Support Optionen + +Wenn Sie nicht auf eine unterstützte Version von Express aktualisieren können, wenden Sie sich bitte an einen unserer Partner, um Sicherheitsaktualisierungen zu erhalten: + +- [HeroDevs Never-Ending Support](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/en/3x/api.md b/en/3x/api.md index 7421a648df..b421e2afe6 100644 --- a/en/3x/api.md +++ b/en/3x/api.md @@ -1,24 +1,27 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - API Reference +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: en redirect_from: "/3x/api.html" ---
    - **Express 3.x IS NO LONGER MAINTAINED** + **Express 3.x IS END-OF-LIFE AND NO LONGER MAINTAINED** Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. + + If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options).

    3.x API

    - {% include api/{{ page.lang }}/3x/express.md %} - {% include api/{{ page.lang }}/3x/app.md %} - {% include api/{{ page.lang }}/3x/req.md %} - {% include api/{{ page.lang }}/3x/res.md %} - {% include api/{{ page.lang }}/3x/middleware.md %} + {% include api/en/3x/express.md %} + {% include api/en/3x/app.md %} + {% include api/en/3x/req.md %} + {% include api/en/3x/res.md %} + {% include api/en/3x/middleware.md %}
    diff --git a/en/4x/api.md b/en/4x/api.md index 542148ec89..5c45b6f859 100644 --- a/en/4x/api.md +++ b/en/4x/api.md @@ -1,18 +1,27 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - API Reference +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: en redirect_from: "/4x/api.html" ---

    4.x API

    - {% include api/{{ page.lang }}/4x/express.md %} - {% include api/{{ page.lang }}/4x/app.md %} - {% include api/{{ page.lang }}/4x/req.md %} - {% include api/{{ page.lang }}/4x/res.md %} - {% include api/{{ page.lang }}/4x/router.md %} + {% capture node-version %} + + Express 4.0 requires Node.js 0.10 or higher. + + {% endcapture %} + + {% include admonitions/note.html content=node-version %} + + {% include api/en/4x/express.md %} + {% include api/en/4x/app.md %} + {% include api/en/4x/req.md %} + {% include api/en/4x/res.md %} + {% include api/en/4x/router.md %}
    diff --git a/en/5x/api.md b/en/5x/api.md index 252b5cf954..e406b9c925 100644 --- a/en/5x/api.md +++ b/en/5x/api.md @@ -1,20 +1,27 @@ --- -layout: 5x-api +layout: api +version: 5x title: Express 5.x - API Reference +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. menu: api -lang: en redirect_from: "/5x/api.html" ---

    5.x API

    - {% include note.html content="This is early alpha documentation that may be incomplete and is still under development." %} + {% capture node-version %} - {% include api/{{ page.lang }}/5x/express.md %} - {% include api/{{ page.lang }}/5x/app.md %} - {% include api/{{ page.lang }}/5x/req.md %} - {% include api/{{ page.lang }}/5x/res.md %} - {% include api/{{ page.lang }}/5x/router.md %} + Express 5.0 requires Node.js 18 or higher. + + {% endcapture %} + + {% include admonitions/note.html content=node-version %} + + {% include api/en/5x/express.md %} + {% include api/en/5x/app.md %} + {% include api/en/5x/req.md %} + {% include api/en/5x/res.md %} + {% include api/en/5x/router.md %}
    diff --git a/en/advanced/best-practice-performance.md b/en/advanced/best-practice-performance.md index d0ca92584c..d23e8ee392 100644 --- a/en/advanced/best-practice-performance.md +++ b/en/advanced/best-practice-performance.md @@ -1,15 +1,12 @@ --- layout: page title: Performance Best Practices Using Express in Production +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: en redirect_from: "/advanced/best-practice-performance.html" --- - # Production best practices: performance and reliability -## Overview - 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: @@ -41,9 +38,10 @@ Here are some things you can do in your code to improve your application's perfo 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: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` @@ -55,11 +53,11 @@ Synchronous functions and methods tie up the executing process until they return 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. -If you are using Node.js 4.0+ or io.js 2.1.0+, 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#cli_trace_sync_io) for more information. +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#cli_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_console_1) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. +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 @@ -67,7 +65,7 @@ If you're logging for purposes of debugging, then instead of using `console.log( #### 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 [Winston](https://www.npmjs.com/package/winston) or [Bunyan](https://www.npmjs.com/package/bunyan). For a detailed comparison of these two libraries, see the StrongLoop blog post [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). +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 @@ -82,23 +80,12 @@ Before diving into these topics, you should have a basic understanding of Node/E For more on the fundamentals of error handling, see: -* [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop blog) - -#### 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#process_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. +* [Error Handling in Node.js](https://www.tritondatacenter.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. -Use a tool such as [JSHint](http://jshint.com/) or [JSLint](http://www.jslint.com/) to help you find implicit exceptions like [reference errors on undefined variables](http://www.jshint.com/docs/options/#undef). - 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. @@ -106,9 +93,9 @@ This middleware function accepts a query field parameter named "params" that is app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -121,44 +108,39 @@ However, try-catch works only for synchronous code. Because the Node platform is #### Use promises -Promises will handle any exceptions (both explicit and implicit) in asynchronous code blocks that use `then()`. Just add `.catch(next)` to the end of promise chains. For example: +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -Now all errors asynchronous and synchronous get propagated to the error middleware. - -However, there are two caveats: - -1. All your asynchronous code must return promises (except emitters). If a particular library does not return promises, convert the base object by using a helper function like [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Event emitters (like streams) can still cause uncaught exceptions. So make sure you are handling the error event properly; for example: +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -The `wrap()` function is a wrapper that catches rejected promises and calls `next()` with the error as the first argument. -For details, see [Asynchronous -Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/#cleaner-code-with-generators). +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#process_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. -For more information about error-handling by using promises, see [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/). +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. ## Things to do in your environment / setup {#in-environment} @@ -173,7 +155,7 @@ Here are some things you can do in your system environment to improve your app's ### 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." +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: @@ -181,20 +163,11 @@ Setting NODE_ENV to "production" makes Express: * Cache CSS files generated from CSS extensions. * Generate less verbose error messages. -[Tests indicate](http://apmblog.dynatrace.com/2015/07/22/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! +[Tests indicate](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 or Upstart). 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 Upstart, use the `env` keyword in your job file. For example: - -```sh -# /etc/init/env.conf - env NODE_ENV=production -``` - -For more information, see the [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). +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: @@ -203,7 +176,7 @@ With systemd, use the `Environment` directive in your unit file. For example: Environment=NODE_ENV=production ``` -For more information, see [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### Ensure your app automatically restarts @@ -222,32 +195,13 @@ In addition to restarting your app when it crashes, a process manager can enable * Gain insights into runtime performance and resource consumption. * Modify settings dynamically to improve performance. -* Control clustering (StrongLoop PM and pm2). - -The most popular process managers for Node are as follows: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -For a feature-by-feature comparison of the three process managers, see [http://strong-pm.io/compare/](http://strong-pm.io/compare/). For a more detailed introduction to all three, see [Process managers for Express apps](/{{ page.lang }}/advanced/pm.html). - -Using any of these process managers will suffice to keep your application up, even if it does crash from time to time. - -However, StrongLoop PM has lots of features that specifically target production deployment. You can use it and the related StrongLoop tools to: +* Control clustering (pm2). -* Build and package your app locally, then deploy it securely to your production system. -* Automatically restart your app if it crashes for any reason. -* Manage your clusters remotely. -* View CPU profiles and heap snapshots to optimize performance and diagnose memory leaks. -* View performance metrics for your application. -* Easily scale to multiple hosts with integrated control for Nginx load balancer. - -As explained below, when you install StrongLoop PM as an operating system service using your init system, it will automatically restart when the system restarts. Thus, it will keep your application processes and clusters alive forever. +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 two main init systems in use today are [systemd](https://wiki.debian.org/systemd) and [Upstart](http://upstart.ubuntu.com/). +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: @@ -258,7 +212,7 @@ There are two ways to use init systems with your Express app: 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: +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] @@ -289,93 +243,8 @@ Restart=always [Install] WantedBy=multi-user.target ``` -For more information on systemd, see the [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM as a systemd service -You can easily install StrongLoop Process Manager as a systemd service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. - -To install StrongLoop PM as a systemd service: - -```sh -$ sudo sl-pm-install --systemd -``` - -Then start the service with: - -```sh -$ sudo /usr/bin/systemctl start strong-pm -``` - -For more information, see [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart is a system tool available on many Linux distributions for starting tasks and services during system startup, stopping them during shutdown, and supervising them. You can configure your Express app or process manager as a service and then Upstart will automatically restart it when it crashes. - -An Upstart service is defined in a job configuration file (also called a "job") with filename ending in `.conf`. The following example shows how to create a job called "myapp" for an app named "myapp" with the main file located at `/projects/myapp/index.js`. - -Create a file named `myapp.conf` at `/etc/init/` with the following content (replace the bold text with values for your system and app): - -```sh -# When to start the process -start on runlevel [2345] - -# When to stop the process -stop on runlevel [016] - -# Increase file descriptor limit to be able to handle more requests -limit nofile 50000 50000 - -# Use production mode -env NODE_ENV=production - -# Run as www-data -setuid www-data -setgid www-data - -# Run from inside the app dir -chdir /projects/myapp - -# The process to start -exec /usr/local/bin/node /projects/myapp/index.js - -# Restart the process if it is down -respawn - -# Limit restart attempt to 10 times within 10 seconds -respawn limit 10 10 -``` - -NOTE: This script requires Upstart 1.4 or newer, supported on Ubuntu 12.04-14.10. - -Since the job is configured to run when the system starts, your app will be started along with the operating system, and automatically restarted if the app crashes or the system goes down. - -Apart from automatically restarting the app, Upstart enables you to use these commands: - -* `start myapp` – Start the app -* `restart myapp` – Restart the app -* `stop myapp` – Stop the app. - -For more information on Upstart, see [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM as an Upstart service - -You can easily install StrongLoop Process Manager as an Upstart service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. - -To install StrongLoop PM as an Upstart 1.4 service: - -```sh -$ sudo sl-pm-install -``` - -Then run the service with: - -```sh -$ sudo /sbin/initctl start strong-pm -``` - -NOTE: On systems that don't support Upstart 1.4, the commands are slightly different. See [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) for more information. +For more information on systemd, see the [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). ### Run your app in a cluster @@ -389,31 +258,17 @@ In clustered apps, worker processes can crash individually without affecting the #### Using Node's cluster module -Clustering is made possible with Node's [cluster module](https://nodejs.org/dist/latest-v4.x/docs/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it's far better to use one of the many tools out there that does it for you automatically; for example [node-pm](https://www.npmjs.com/package/node-pm) or [cluster-service](https://www.npmjs.com/package/cluster-service). - -#### Using StrongLoop PM - -If you deploy your application to StrongLoop Process Manager (PM), then you can take advantage of clustering _without_ modifying your application code. - -When StrongLoop Process Manager (PM) runs an application, it automatically runs it in a cluster with a number of workers equal to the number of CPU cores on the system. You can manually change the number of worker processes in the cluster using the slc command line tool without stopping the app. - -For example, assuming you've deployed your app to prod.foo.com and StrongLoop PM is listening on port 8701 (the default), then to set the cluster size to eight using slc: - -```sh -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8 -``` - -For more information on clustering with StrongLoop PM, see [Clustering](https://docs.strongloop.com/display/SLC/Clustering) in StrongLoop documentation. +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](http://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). +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: -```sh +```bash # Start 4 worker processes $ pm2 start npm --name my-app -i 4 -- start # Auto-detect number of available CPUs and start that many worker processes @@ -424,7 +279,7 @@ This can also be configured within a PM2 process file (`ecosystem.config.js` or Once running, the application can be scaled like so: -```sh +```bash # Add 3 more workers $ pm2 scale my-app +3 # Scale to a specific number of workers @@ -437,18 +292,18 @@ For more information on clustering with PM2, see [Cluster Mode](https://pm2.keym 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-cache.org/) or [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/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](http://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). +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](http://socket.io/docs/using-multiple-nodes/). +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://www.nginx.com/) or [HAProxy](http://www.haproxy.org/) in production. +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://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/en/advanced/best-practice-security.md b/en/advanced/best-practice-security.md index ee8fa0d8e4..143cbdddf0 100644 --- a/en/advanced/best-practice-security.md +++ b/en/advanced/best-practice-security.md @@ -1,8 +1,8 @@ --- layout: page title: Security Best Practices for Express in Production +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: en redirect_from: "/advanced/best-practice-security.html" --- @@ -14,25 +14,36 @@ The term _"production"_ refers to the stage in the software lifecycle when an ap Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production. -{% include note.html content="If you believe you have discovered a security vulnerability in Express, please see +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see [Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). -" %} -Security best practices for Express applications in production include: +{% endcapture %} -- [Don’t use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) -- [Use TLS](#use-tls) -- [Use Helmet](#use-helmet) -- [Use cookies securely](#use-cookies-securely) -- [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) -- [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) -- [Avoid other known vulnerabilities](#avoid-other-known-vulnerabilities) -- [Additional considerations](#additional-considerations) +{% include admonitions/note.html content=security-note %} + +Security best practices for Express applications in production include: +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [Use TLS](#use-tls) + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - [Use Helmet](#use-helmet) + - [Reduce fingerprinting](#reduce-fingerprinting) + - [Use cookies securely](#use-cookies-securely) + - [Don't use the default session cookie name](#dont-use-the-default-session-cookie-name) + - [Set cookie security options](#set-cookie-security-options) + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) + - [Avoid other known vulnerabilities](#avoid-other-known-vulnerabilities) + - [Additional considerations](#additional-considerations) ## Don't use deprecated or vulnerable versions of Express -Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html). +Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html) or consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/{{ page.lang }}/advanced/security-updates.html). If you are, update to one of the stable releases, preferably the latest. @@ -40,29 +51,63 @@ Also ensure you are not using any of the vulnerable Express versions listed on t If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). +You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_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/). +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## Use Helmet -[Helmet](https://www.npmjs.com/package/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. +[Helmet][helmet] can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. + +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: -Helmet is actually just a collection of smaller middleware functions that set security-related HTTP response headers: +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* [csp](https://github.com/helmetjs/csp) sets the `Content-Security-Policy` header to help prevent cross-site scripting attacks and other cross-site injections. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) removes the `X-Powered-By` header. -* [hsts](https://github.com/helmetjs/hsts) sets `Strict-Transport-Security` header that enforces secure (HTTP over SSL/TLS) connections to the server. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) sets `X-Download-Options` for IE8+. -* [noCache](https://github.com/helmetjs/nocache) sets `Cache-Control` and Pragma headers to disable client-side caching. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) sets `X-Content-Type-Options` to prevent browsers from MIME-sniffing a response away from the declared content-type. -* [frameguard](https://github.com/helmetjs/frameguard) sets the `X-Frame-Options` header to provide [clickjacking](https://www.owasp.org/index.php/Clickjacking) protection. -* [xssFilter](https://github.com/helmetjs/x-xss-protection) sets `X-XSS-Protection` to disable the buggy Cross-site scripting (XSS) filter in web browsers. +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. Install Helmet like any other module: -```sh -$ npm install --save helmet +```bash +$ npm install helmet ``` Then to use it in your code: @@ -70,28 +115,58 @@ Then to use it in your code: ```js // ... -var helmet = require('helmet') +const helmet = require('helmet') app.use(helmet()) // ... ``` -### At a minimum, disable X-Powered-By header +## Reduce fingerprinting -If you don't want to use Helmet, then at least disable the `X-Powered-By` header. Attackers can use this header (which is enabled by default) to detect apps running Express and then launch specifically-targeted attacks. +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. -So, best practice is to turn off the header with the `app.disable()` method: +By default, Express sends the `X-Powered-By` response header that you can +disable using the `app.disable()` method: ```js app.disable('x-powered-by') ``` -If you use `helmet.js`, it takes care of this for you. +{% capture powered-advisory %} -{% include note.html content="Disabling the `X-Powered-By header` does not prevent -a sophisticated attacker from determining that an app is running Express. It may +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may discourage a casual exploit, but there are other ways to determine an app is running -Express. "%} +Express. + +{% endcapture %} + +{% include admonitions/note.html content=powered-advisory %} + +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): + +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## Use cookies securely @@ -102,18 +177,18 @@ There are two main middleware cookie session modules: * [express-session](https://www.npmjs.com/package/express-session) that replaces `express.session` middleware built-in to Express 3.x. * [cookie-session](https://www.npmjs.com/package/cookie-session) that replaces `express.cookieSession` middleware built-in to Express 3.x. -The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. 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). +The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. 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). -In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then express-session may be a better choice. +In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then `express-session` may be a better choice. ### Don't use the default session cookie name -Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. +Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. To avoid this problem, use generic cookie names; for example using [express-session](https://www.npmjs.com/package/express-session) middleware: ```js -var session = require('express-session') +const session = require('express-session') app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 's3Cur3', @@ -134,11 +209,11 @@ Set the following cookie options to enhance security: Here is an example using [cookie-session](https://www.npmjs.com/package/cookie-session) middleware: ```js -var session = require('cookie-session') -var express = require('express') -var app = express() +const session = require('cookie-session') +const express = require('express') +const app = express() -var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour app.use(session({ name: 'session', keys: ['key1', 'key2'], @@ -157,18 +232,18 @@ app.use(session({ Make sure login endpoints are protected to make private data more secure. A simple and powerful technique is to block authorization attempts using two metrics: -1. The first is number of consecutive failed attempts by the same user name and IP address. -1. The second is number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. +1. The number of consecutive failed attempts by the same user name and IP address. +1. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. -[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](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) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) ## Ensure your dependencies are secure -Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. +Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. -Since npm@6, npm automatically reviews every install request. Also you can use 'npm audit' to analyze your dependency tree. +Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. -```sh +```bash $ npm audit ``` @@ -176,36 +251,31 @@ 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: -```sh +```bash $ npm install -g snyk $ cd your-app ``` Use this command to test your application for vulnerabilities: -```sh +```bash $ snyk test ``` -Use this command to open a wizard that walks you through the process of applying updates or patches to fix the vulnerabilities that were found: - -```sh -$ snyk wizard -``` - -## Avoid other known vulnerabilities +### Avoid other known vulnerabilities -Keep an eye out for [Node Security Project](https://npmjs.com/advisories) or [Snyk](https://snyk.io/vuln/) 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. +Keep an eye out for [Node Security Project](https://npmjs.com/advisories) or [Snyk](https://snyk.io/vuln/) 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/index.php/Top_10-2017_Top_10) 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://www.owasp.org/www-project-top-ten/) and take precautions to avoid them. ## Additional considerations -Here are some further recommendations from the excellent [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Refer to that blog post for all the details on these recommendations: +Here are some further recommendations from the excellent [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Refer to that blog post for all the details on these recommendations: -* Use [csurf](https://www.npmjs.com/package/csurf) middleware to protect against cross-site request forgery (CSRF). * 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 [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. + +[helmet]: https://helmetjs.github.io/ \ No newline at end of file diff --git a/en/advanced/developing-template-engines.md b/en/advanced/developing-template-engines.md index 9a8ba5fb40..5e84f2b4e0 100755 --- a/en/advanced/developing-template-engines.md +++ b/en/advanced/developing-template-engines.md @@ -1,8 +1,8 @@ --- layout: page title: Developing template engines for Express +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: en redirect_from: "/advanced/developing-template-engines.html" --- @@ -13,14 +13,14 @@ Use the `app.engine(ext, callback)` method to create your own template engine. ` The following code is an example of implementing a very simple template engine for rendering `.ntl` files. ```js -var fs = require('fs') // this engine requires the fs module -app.engine('ntl', function (filePath, options, callback) { // define the template engine - fs.readFile(filePath, function (err, content) { +const fs = require('fs') // this engine requires the fs module +app.engine('ntl', (filePath, options, callback) => { // define the template engine + fs.readFile(filePath, (err, content) => { if (err) return callback(err) // this is an extremely simple template engine - var rendered = content.toString() - .replace('#title#', '' + options.title + '') - .replace('#message#', '

    ' + options.message + '

    ') + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

    ${options.message}

    `) return callback(null, rendered) }) }) @@ -30,15 +30,15 @@ app.set('view engine', 'ntl') // register the template engine Your app will now be able to render `.ntl` files. Create a file named `index.ntl` in the `views` directory with the following content. -```text +```pug #title# #message# ``` Then, create the following route in your app. ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index', { title: 'Hey', message: 'Hello there!' }) }) ``` -When you make a request to the home page, `index.ntl` will be rendered as HTML. +When you make a request to the home page, `index.ntl` will be rendered as HTML. \ No newline at end of file diff --git a/en/advanced/healthcheck-graceful-shutdown.md b/en/advanced/healthcheck-graceful-shutdown.md index ca1eb19d36..4398238fad 100644 --- a/en/advanced/healthcheck-graceful-shutdown.md +++ b/en/advanced/healthcheck-graceful-shutdown.md @@ -1,8 +1,8 @@ --- layout: page 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. menu: advanced -lang: en redirect_from: "/advanced/healthcheck-graceful-shutdown.html" --- @@ -10,9 +10,10 @@ redirect_from: "/advanced/healthcheck-graceful-shutdown.html" ## Graceful shutdown -When you deploy a new version of your application, you must replace the previous version. The [process manager](pm.html) 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. +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 -### Example Graceful Shutdown ```js const server = app.listen(port) @@ -29,153 +30,4 @@ process.on('SIGTERM', () => { 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-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. - -## Third-party solutions - -{% include community-caveat.html %} - -### Terminus - -[Terminus](https://github.com/godaddy/terminus) is an open-source project that adds health checks and graceful shutdown to your application to eliminate the need to write boilerplate code. You just provide the cleanup logic for graceful shutdowns and the health check logic for health checks, and terminus handles the rest. - -Install terminus as follows: - -```sh -npm i @godaddy/terminus --save -``` - -Here's a basic template that illustrates using terminus. For more information, see . - -```js -const http = require('http') -const express = require('express') -const { createTerminus } = require('@godaddy/terminus') - -const app = express() - -app.get('/', (req, res) => { - res.send('ok') -}) - -const server = http.createServer(app) - -function onSignal () { - console.log('server is starting cleanup') - // start cleanup of resource, like databases or file descriptors -} - -async function onHealthCheck () { - // checks if the system is healthy, like the db connection is live - // resolves, if health, rejects if not -} - -createTerminus(server, { - signal: 'SIGINT', - healthChecks: { '/healthcheck': onHealthCheck }, - onSignal -}) - -server.listen(3000) -``` - -### Lightship - -[Lightship](https://github.com/gajus/lightship) is an open-source project that adds health, readiness and liveness checks to your application. Lightship is a standalone HTTP-service that runs as a separate HTTP service; this allows having health-readiness-liveness HTTP endpoints without exposing them on the public interface. - -Install Lightship as follows: - -```sh -npm install lightship - -``` - -Basic template that illustrates using Lightship: - -```js -const http = require('http') -const express = require('express') -const { - createLightship -} = require('lightship') - -// Lightship will start a HTTP service on port 9000. -const lightship = createLightship() - -const app = express() - -app.get('/', (req, res) => { - res.send('ok') -}) - -app.listen(3000, () => { - lightship.signalReady() -}) - -// You can signal that the service is not ready using `lightship.signalNotReady()`. -``` - -[Lightship documentation](https://github.com/gajus/lightship) provides examples of the corresponding [Kubernetes configuration](https://github.com/gajus/lightship#lightship-usage-kubernetes-container-probe-configuration) and a complete example of integration with [Express.js](https://github.com/gajus/lightship#using-with-expressjs). - -### http-terminator - -[http-terminator](https://github.com/gajus/http-terminator) implements logic for gracefully terminating an express.js server. - -Terminating a HTTP server in Node.js requires keeping track of all open connections and signaling them that the server is shutting down. http-terminator implements the logic for tracking all connections and their termination upon a timeout. http-terminator also ensures graceful communication of the server intention to shutdown to any clients that are currently receiving response from this server. - -Install http-terminator as follows: - -```sh -npm install http-terminator - -``` - -Basic template that illustrates using http-terminator: - -```js -const express = require('express') -const { createHttpTerminator } = require('http-terminator') - -const app = express() - -const server = app.listen(3000) - -const httpTerminator = createHttpTerminator({ server }) - -app.get('/', (req, res) => { - res.send('ok') -}) - -// A server will terminate after invoking `httpTerminator.terminate()`. -// Note: Timeout is used for illustration of delayed termination purposes only. -setTimeout(() => { - httpTerminator.terminate() -}, 1000) -``` - -[http-terminator documentation](https://github.com/gajus/http-terminator) provides API documentation and comparison to other existing third-party solutions. - -### express-actuator - -[express-actuator](https://github.com/rcruzper/express-actuator) is a middleware to add endpoints to help you monitor and manage applications. - -Install express-actuator as follows: - -```sh -npm install --save express-actuator -``` - -Basic template that illustrates using express-actuator: - -```js -const express = require('express') -const actuator = require('express-actuator') - -const app = express() - -app.use(actuator()) - -app.listen(3000) -``` - -The [express-actuator documentation](https://github.com/rcruzper/express-actuator) provides different options for customization. +* `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. \ No newline at end of file diff --git a/en/advanced/pm.md b/en/advanced/pm.md deleted file mode 100755 index 43251d6252..0000000000 --- a/en/advanced/pm.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: page -title: Process managers for Express apps -menu: advanced -lang: en -redirect_from: "/advanced/pm.html" ---- - -# Process managers for Express apps - -{% include community-caveat.html %} - -When you run Express apps for production, it is helpful to use a _process manager_ to: - -- Restart the app automatically if it crashes. -- Gain insights into runtime performance and resource consumption. -- Modify settings dynamically to improve performance. -- Control clustering. - -A process manager is somewhat like an application server: it's a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. - -The most popular process managers for Express and other Node.js applications are: - -- **[Forever](https://github.com/foreverjs/forever){: target="_blank"}**: A simple command-line interface tool to ensure that a script runs continuously (forever). Forever's simple interface makes it ideal for running smaller deployments of Node.js apps and scripts. -- **[PM2](https://github.com/Unitech/pm2){: target="_blank"}**: A production process manager for Node.js applications that has a built-in load balancer. PM2 enables you to keep applications alive forever, reloads them without downtime, helps you to manage application logging, monitoring, and clustering. -- **[StrongLoop Process Manager (Strong-PM)](http://strong-pm.io/)**: A production process manager for Node.js applications with built-in load balancing, monitoring, and multi-host deployment. Includes a CLI to build, package, and deploy Node.js applications to a local or remote system. -- **SystemD**: The default process manager on modern Linux distributions, that makes it simple to run a Node application as a service. For more information, see ["Run node.js service with systemd" by Ralph Slooten (@axllent)](https://www.axllent.org/docs/view/nodejs-service-with-systemd/). diff --git a/en/advanced/security-updates.md b/en/advanced/security-updates.md index 1846728906..19edff3e21 100755 --- a/en/advanced/security-updates.md +++ b/en/advanced/security-updates.md @@ -1,23 +1,42 @@ --- layout: page title: Express security updates +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: en redirect_from: "/advanced/security-updates.html" --- + # Security updates
    -Node.js vulnerabilities directly affect Express. Therefore [keep a watch on Node.js vulnerabilities](http://blog.nodejs.org/vulnerability/) and make sure you are using the latest stable version of Node.js. +Node.js vulnerabilities directly affect Express. Therefore, [keep a watch on Node.js vulnerabilities](https://nodejs.org/en/blog/vulnerability/) and make sure you are using the latest stable version of Node.js.
    The list below enumerates the Express vulnerabilities that were fixed in the specified version update. -**NOTE**: If you believe you have discovered a security vulnerability in Express, please see + +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see [Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} -## 4.x +{% include admonitions/note.html content=security-policy %} +## 4.x + * 4.21.2 + * The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). + * 4.21.1 + * The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. + * 4.20.0 + * Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + * The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + * The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + * The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + * The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. + * 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 + * The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. * 4.16.0 * The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. @@ -44,9 +63,11 @@ The list below enumerates the Express vulnerabilities that were fixed in the spe ## 3.x
    - **Express 3.x IS NO LONGER MAINTAINED** + **Express 3.x IS END-OF-LIFE AND NO LONGER MAINTAINED** + + Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. - Known and unknown security issues in 3.x have not been addressed since the last update (1 August, 2015). Using the 3.x line should not be considered secure. + If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options).
    * 3.19.1 @@ -61,4 +82,4 @@ The list below enumerates the Express vulnerabilities that were fixed in the spe * Sparse arrays that have extremely high indexes in query string could cause the process to run out of memory and crash the server. * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. * 3.3.0 - * The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks. + * The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks. \ No newline at end of file diff --git a/en/api.md b/en/api.md index 16227d369e..41382818cc 100644 --- a/en/api.md +++ b/en/api.md @@ -1,26 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - API Reference -lang: en +layout: api +version: 5x +title: Express 5.x - API Reference +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api redirect_from: "/api.html" ---
    - -

    4.x API

    - +

    5.x API

    - {% include api/{{ page.lang }}/4x/express.md %} - + {% include api/en/5x/express.md %} - {% include api/{{ page.lang }}/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/{{ page.lang }}/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/{{ page.lang }}/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/{{ page.lang }}/4x/router.md %} - + {% include api/en/5x/router.md %}
    diff --git a/en/blog/posts.md b/en/blog/posts.md new file mode 100644 index 0000000000..b5be34e66c --- /dev/null +++ b/en/blog/posts.md @@ -0,0 +1,28 @@ +--- +layout: post +title: Express Blog Posts +description: Explore the latest articles, announcements, and updates from the Express.js team and community on the Express blog. +menu: blog +redirect_from: "/blog/posts.html" +--- + +Want to write a post? See the submission [guidelines.](/en/blog/write-post.html) + +{% if site.posts.size != 0 %} +
    +{% for post in site.posts %} +
    + +
    + {% include blog/authors.html authors=post.authors %} +
    {{ post.date | date:"%b %d, %Y" }}
    +
    +
    {{post.excerpt | truncate: 240 | markdownify }}
    +
    +{% endfor %} +
    +{% else %} + There are currently no blog posts. +{% endif %} diff --git a/en/blog/write-post.md b/en/blog/write-post.md new file mode 100644 index 0000000000..21cfc5b4b3 --- /dev/null +++ b/en/blog/write-post.md @@ -0,0 +1,51 @@ +--- +layout: post +title: How to write a blog post +description: Learn how to propose and write a blog post for the Express.js blog, including submission guidelines and steps to contribute your content. +menu: blog +redirect_from: "/blog/write.html" +--- + +![Blogger]({{site.url}}/images/blogger.jpg) + +If you have an idea for a blog post, follow these steps to propose it and potentially get it published! + +1. ### Propose your post +Before taking the time to write a post, please confirm that we will be able to publish it. We're looking for topics specifically related to Express, and so we want to pre-approve all posts. For the moment, this means we aren't accepting any unsolicited posts. To propose a blog post, [open an issue](https://github.com/expressjs/expressjs.com/issues) entitled `Blog post proposal: `. + + +1. ### Fork the repository +If the Express TC accepts your proposal, start to write your post by forking the [expressjs.com](https://github.com/expressjs/expressjs.com) repository and cloning it to your local machine. Once you open a pull request, you'll be able to preview your post on GitHub. See step six below. + + Optional: To run the site locally and preview your post before opening a PR, see the [setup instructions in the README](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#expressjscom). + {: .doc-box .doc-info} + +1. ### Create a new file +Create a new file in the `_posts` directory named using following the format: `YYYY-MM-DD-title.md`. + +1. ### Add the required front matter + Copy the following front matter, including the dotted lines, and paste it at the top of file you just created. Replace the placeholder values with as desired. + + ```markdown + --- + title: + sub_title: + description: + tags: + authors: + - name: + github: + --- + ``` + + The `github` property of an author is optional. Including your username only (not your full profile URL) will ensure that your blog post links out to it. + +2. ### Add your content + Finally, start writing your content below the front matter. Use standard markdown formatting. + +1. ### Open a pull request (PR) + Once you open a PR, you will be able to preview your results: There will be a section on the page entitled `Deploy Preview for expressjscom-preview ready!` Click the link to see the site rendered from your fork/branch. + + You can use this feature over multiple commits to refine your post by making a `draft` pull request. Once it's ready for review, switch it to a formal PR. + + \ No newline at end of file diff --git a/en/changelog/4x.md b/en/changelog/4x.md deleted file mode 100644 index c30ef0d5ca..0000000000 --- a/en/changelog/4x.md +++ /dev/null @@ -1,337 +0,0 @@ ---- -layout: page -title: Express 4.x changelog -menu: changelog -lang: en -redirect_from: "/changelog/4x.html" ---- - -# Release Change Log - -## 4.17.1 - Release date: 2019-05-25 -{: id="4.17.1"} - -The 4.17.1 patch release includes one bug fix: - -
      -
    • - The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). - -## 4.17.0 - Release date: 2019-05-16 -{: id="4.17.0"} - -The 4.17.0 minor release includes bug fixes and some new features, including: - -
      -
    • - The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. -
    • - -
    • - The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. -
    • - -
    • - When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. -
    • - -
    • - Starting with this version, Express supports Node.js 10.x and 12.x. -
    • - -
    • - The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. -
    • - -
    • - The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). - -## 4.16.4 - Release date: 2018-10-10 -{: id="4.16.4"} - -The 4.16.4 patch release includes various bug fixes: - -
      -
    • - Fix issue where `"Request aborted"` may be logged in `res.sendfile`. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). - -## 4.16.3 - Release date: 2018-03-12 -{: id="4.16.3"} - -The 4.16.3 patch release includes various bug fixes: - -
      -
    • - Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. -
    • - -
    • - Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. -
    • - -
    • - Fix the generated HTML document for `express.static` redirect responses to properly include ``. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). - -## 4.16.2 - Release date: 2017-10-09 -{: id="4.16.2"} - -The 4.16.2 patch release includes a regression bug fix: - -
      -
    • - Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). - -## 4.16.1 - Release date: 2017-09-29 -{: id="4.16.1"} - -The 4.16.1 patch release includes a regression bug fix: - -
      -
    • - Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). - -## 4.16.0 - Release date: 2017-09-28 -{: id="4.16.0"} - -The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: - -
      -
    • - Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. -
    • - -
    • - Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. -
    • - -
    • - The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express.js with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. -
    • - -
    • - Starting with this version, Express supports Node.js 8.x. -
    • - -
    • - The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. -
    • - -
    • - The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. -
    • - -
    • - The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. -
    • - -
    • - The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. -
    • - -
    • - The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). - -## 4.15.5 - Release date: 2017-09-24 -{: id="4.15.5"} - -The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: - -
      -
    • - Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. -
    • - -
    • - Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. -
    • - -
    • - Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). - -## 4.15.4 - Release date: 2017-08-06 -{: id="4.15.4"} - -The 4.15.4 patch release includes some minor bug fixes: - -
      -
    • - Fix array being set for `"trust proxy"` value being manipulated in certain conditions. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). - -## 4.15.3 - Release date: 2017-05-16 -{: id="4.15.3"} - -The 4.15.3 patch release includes a security update and some minor bug fixes: - -
      -
    • - Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. -
    • - -
    • - Fix error when `res.set` cannot add charset to `Content-Type`. -
    • - -
    • - Fix missing `` in HTML document. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). - -## 4.15.2 - Release date: 2017-03-06 -{: id="4.15.2"} - -The 4.15.2 patch release includes a minor bug fix: - -
      -
    • - Fix regression parsing keys starting with `[` in the extended (default) query parser. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). - -## 4.15.1 - Release date: 2017-03-05 -{: id="4.15.1"} - -The 4.15.1 patch release includes a minor bug fix: - -
      -
    • - Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). - -## 4.15.0 - Release date: 2017-03-01 -{: id="4.15.0"} - -The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: - -
      -
    • - Starting with this version, Express supports Node.js 7.x. -
    • - -
    • - The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. -
    • - -
    • - Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). -
    • - -
    • - Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). - -## 4.14.1 - Release date: 2017-01-28 -{: id="4.14.1"} - -The 4.14.1 patch release includes bug fixes and performance improvements, including: - -
      -
    • - Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). - -## 4.14.0 - Release date: 2016-06-16 -{: id="4.14.0"} - -The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: - -
      -
    • - Starting with this version, Express supports Node.js 6.x. -
    • - -
    • - Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). -
    • - -
    • - The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. - - - `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. - - - `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. - - - `res.sendFile` has also been updated to handle `Range` header and redirections better. -
    • - -
    • - The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. -
    • - -
    • - The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. -
    • - -
    • - The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). NOTE: This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. - - The possible value for the `sameSite` option are: - - - `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. - - `false`, which does not set the `SameSite` attribute. - - `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. - - `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. -
    • - -
    • - Absolute path checking on Windows, which was incorrect for some cases, has been fixed. -
    • - -
    • - IP address resolution with proxies has been greatly improved. -
    • - -
    • - The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. -
    • -
    - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). diff --git a/en/changelog/index.md b/en/changelog/index.md new file mode 100644 index 0000000000..85bebed4fa --- /dev/null +++ b/en/changelog/index.md @@ -0,0 +1,597 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - "/changelog/4x.html" + - "en/changelog/4x.html" +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +* Support for sending responses as Uint8Array +* Added support for ETag option in `res.sendFile()` +* Added support for adding multiple links with the same rel with `res.links()` +* Performance: Use loop for acceptParams +* [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + * Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + * Remove `unpipe` & `destroy` +* [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + * Restore `debug`. Now with the `router` scope instead of `express`. + * Remove legacy node.js support checks for `setImmediate` + * Deprecate non-native promise support + * Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +* [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + * Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + * Remove `unpipe` +* Transitioned all remaining dependencies to use `^` ranges instead of locked versions +* Add package.json funding field to highlight our OpenCollective +* See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) +### 5.0.1 - Release date: 2024-10-08 +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +* Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +* Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +* Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +* Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +* The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +* The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +* The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +* Adds support for named matching groups in the routes using a regex +* Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 +{: id="4.19.2"} + +* Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 +{: id="4.19.1"} + +* Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 +{: id="4.19.0"} + +* Prevent open redirect allow list bypass due to encodeurl +* deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + + - `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + + - `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + + - `res.sendFile` has also been updated to handle `Range` header and redirections better. +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + + {% capture note-4-14-0 %} + + This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. + + {% endcapture %} + {% include admonitions/note.html content=note-4-14-0 %} + + The possible value for the `sameSite` option are: + + - `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + - `false`, which does not set the `SameSite` attribute. + - `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. + - `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/en/guide/behind-proxies.md b/en/guide/behind-proxies.md index 1c49e4003b..38109f5a96 100755 --- a/en/guide/behind-proxies.md +++ b/en/guide/behind-proxies.md @@ -1,10 +1,11 @@ --- layout: page title: Express behind proxies +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: en redirect_from: "/guide/behind-proxies.html" --- + # Express behind proxies When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy. @@ -26,7 +27,7 @@ If `true`, the client's IP address is understood as the left-most entry in the ` If `false`, the app is understood as directly facing the client and the client's IP address is derived from `req.socket.remoteAddress`. This is the default setting.
    -When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overring all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto` otherwise it may be possible for the client to provide any value. +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value.
    - +Elements of a middleware function call
    HTTP method for which the middleware function applies.
    @@ -40,6 +42,7 @@ The following figure shows the elements of a middleware function call:
    HTTP request argument to the middleware function, called "req" by convention.
    +
    Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error. @@ -51,10 +54,10 @@ one called `myLogger` that prints a simple log message, one called `requestTime` displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies. ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('Hello World!') }) @@ -65,15 +68,15 @@ app.listen(3000) Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. The middleware function is assigned to a variable named `myLogger`. ```js -var myLogger = function (req, res, next) { +const myLogger = function (req, res, next) { console.log('LOGGED') next() } ```
    -Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. -The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next". +Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. +The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next". To avoid confusion, always use this convention.
    @@ -81,17 +84,17 @@ To load the middleware function, call `app.use()`, specifying the middleware fun For example, the following code loads the `myLogger` middleware function before the route to the root path (/). ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() -var myLogger = function (req, res, next) { +const myLogger = function (req, res, next) { console.log('LOGGED') next() } app.use(myLogger) -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('Hello World!') }) @@ -112,7 +115,7 @@ Next, we'll create a middleware function called "requestTime" and add a property to the request object. ```js -var requestTime = function (req, res, next) { +const requestTime = function (req, res, next) { req.requestTime = Date.now() next() } @@ -121,19 +124,19 @@ var requestTime = function (req, res, next) { The app now uses the `requestTime` middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to `req` (the request object). ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() -var requestTime = function (req, res, next) { +const requestTime = function (req, res, next) { req.requestTime = Date.now() next() } app.use(requestTime) -app.get('/', function (req, res) { - var responseText = 'Hello World!
    ' - responseText += 'Requested at: ' + req.requestTime + '' +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` res.send(responseText) }) @@ -158,14 +161,14 @@ async function cookieValidator (cookies) { } ``` -Here we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. ```js -var express = require('express') -var cookieParser = require('cookie-parser') -var cookieValidator = require('./cookieValidator') +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') -var app = express() +const app = express() async function validateCookies (req, res, next) { await cookieValidator(req.cookies) @@ -177,7 +180,7 @@ app.use(cookieParser()) app.use(validateCookies) // error handler -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { res.status(400).send(err.message) }) @@ -185,7 +188,7 @@ app.listen(3000) ```
    -Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware 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. @@ -210,7 +213,7 @@ module.exports = function (options) { The middleware can now be used as shown below. ```js -var mw = require('./my-middleware.js') +const mw = require('./my-middleware.js') app.use(mw({ option1: '1', option2: '2' })) ``` diff --git a/en/resources/community.md b/en/resources/community.md index 75c22866cc..ec8a3d1463 100755 --- a/en/resources/community.md +++ b/en/resources/community.md @@ -1,8 +1,8 @@ --- layout: page title: Express community +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: en redirect_from: "/resources/community.html" --- @@ -23,12 +23,16 @@ Members of the Express technical committee are: - [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey - [@crandmck](https://github.com/crandmck) - Rand McKinney -- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson - [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier - [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida **Inactive:** +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson - [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa - [@jonathanong](https://github.com/jonathanong) - jongleberry - [@niftylettuce](https://github.com/niftylettuce) - niftylettuce @@ -37,20 +41,14 @@ Members of the Express technical committee are: ## Express is made of many modules Our vibrant community has created a large variety of extensions, -[middleware modules](/{{ page.lang }}/resources/middleware.html) and -[higher-level frameworks](frameworks.html). +[middleware modules](/{{ page.lang }}/resources/middleware.html) and higher-level frameworks. Additionally, the Express community maintains modules in these two GitHub orgs: - [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). - [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. -To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.com/statusboard). - -## Gitter - -The [expressjs/express chatroom](https://gitter.im/expressjs/express) is great place -for developers interested in the everyday discussions related to Express. +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). ## Issues @@ -62,13 +60,35 @@ a feature request open a ticket in the [issue queue](https://github.com/expressj View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples) in the repository covering everything from API design and authentication to template engine integration. -## Mailing List - -Join over 2000 Express users or browse over 5000 -discussions in the [Google Group](https://groups.google.com/group/express-js). - -## IRC channel - -Hundreds of developers idle in #express on freenode every day. -If you have questions about the framework, jump in for quick -feedback. +## Github Discussions + +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. + + +# Branding of Express.js + +## Express.js Logo + +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. + +
    +
    +

    Logotype

    + + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/en/resources/companies-using-express.md b/en/resources/companies-using-express.md deleted file mode 100644 index a6b215853b..0000000000 --- a/en/resources/companies-using-express.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -layout: page -title: Companies using Express -menu: resources -lang: en -redirect_from: "/resources/companies-using-express.html" ---- - -# Companies using Express in production - - diff --git a/en/resources/contributing.md b/en/resources/contributing.md index 8754ea721d..ec46e78b14 100644 --- a/en/resources/contributing.md +++ b/en/resources/contributing.md @@ -1,14 +1,16 @@ --- layout: page title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. menu: resources -lang: en redirect_from: "/resources/community.html" --- # Contributing to Express -Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [Node.js Foundation](https://nodejs.org/foundation/). +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. * [Technical committee](#technical-committee) @@ -18,11 +20,11 @@ These projects are governed under the general policies and guidelines of the Nod ## Technical committee -The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). ## Community contributing guide - + The goal of this document is to create a contribution process that: @@ -36,6 +38,7 @@ contributors can be involved in decision making. * A **Contributor** is any individual creating or commenting on an issue or pull request. * A **Committer** is a subset of contributors who have been given write access to the repository. +* A **Project Captain** is the lead maintainer of a repository. * A **TC (Technical Committee)** is a group of committers representing the required technical expertise to resolve rare disputes. * A **Triager** is a subset of contributors who have been given triage access to the repository. @@ -84,35 +87,21 @@ compromise among committers be the default resolution mechanism. ### Becoming a Triager Anyone can become a triager! Read more about the process of being a triager in -[the triage process document](Triager-Guide.md). - -[Open an issue in `expressjs/express` repo](https://github.com/expressjs/express/issues/new) -to request the triage role. State that you have read and agree to the -[Code of Conduct](Code-Of-Conduct.md) and details of the role. - -Here is an example issue content you can copy and paste: +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). -``` -Title: Request triager role for - -I have read and understood the project's Code of Conduct. -I also have read and understood the process and best practices around Express triaging. +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. -I request for a triager role for the following GitHub organizations: - -jshttp -pillarjs -express -``` - -Once you have opened your issue, a member of the TC will add you to the `triage` team in -the organizations requested. They will then close the issue. - -Happy triaging! +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. ### Becoming a Committer -All contributors who land a non-trivial contribution should be on-boarded in a timely manner, +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, and added as a committer, and be given write access to the repository. Committers are expected to follow this policy and continue to send pull requests, go through @@ -126,28 +115,135 @@ If a consensus cannot be reached that has no objections then a majority wins vot is called. It is also expected that the majority of decisions made by the TC are via a consensus seeking process and that voting is only used as a last-resort. -Resolution may involve returning the issue to committers with suggestions on how to -move forward towards a consensus. It is not expected that a meeting of the TC +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC will resolve all issues on its agenda during that meeting and may prefer to continue -the discussion happening among the committers. +the discussion happening among the project captains. -Members can be added to the TC at any time. Any committer can nominate another committer +Members can be added to the TC at any time. 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. Members who do not participate consistently at the level of -a majority of the other members are expected to resign. +not to add this new member. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +* Repos can have as many captains as make sense for the scope of work. +* A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Inactivity and Emeritus Policy for Any Role + +To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation. + +Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months. + +#### Exceptions + +Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive. + +#### Inactivity Process + +* If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again. +* The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time. + +#### Accountability + +* The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams. +* In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team. + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` ## Collaborator's guide - + ### Website Issues Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + ### PRs and Code contributions * Tests must pass. -* Follow the [JavaScript Standard Style](http://standardjs.com/) and `npm run lint`. +* Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. * If you fix a bug, add a test. ### Branches @@ -155,14 +251,14 @@ Open issues for the expressjs.com website in https://github.com/expressjs/expres Use the `master` branch for bug fixes or minor work that is intended for the current release stream. -Use the correspondingly named branch, e.g. `5.0`, for anything intended for +Use the correspondingly named branch, e.g. `6.x`, for anything intended for a future release of Express. ### Steps for contributing -1. [Create an issue](https://github.com/expressjs/express/issues/new) for the +1. Create an issue for the bug you want to fix or the feature that you want to add. -2. Create your own [fork](https://github.com/expressjs/express) on GitHub, then +2. Create your own fork on GitHub, then checkout your fork. 3. Write your code in your local copy. It's good practice to create a branch for each new issue you work on, although not compulsory. @@ -190,9 +286,16 @@ Things that will help get your question issue looked at: If you post a question and do not outline the above items or make it easy for us to understand and reproduce your issue, it will be closed. +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. ## Security Policies and Procedures - + This document outlines security procedures and general policies for the Express project. @@ -208,7 +311,11 @@ Thank you for improving the security of Express. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions. -Report security bugs by emailing the lead maintainer in the Readme.md file. +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling @@ -217,8 +324,13 @@ endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. Report security bugs in third-party modules to the person or team maintaining -the module. You can also report a vulnerability through the -[Node Security Project](https://nodesecurity.io/report). +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. ### Disclosure Policy @@ -231,8 +343,137 @@ involving the following steps: * Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible to npm. +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + ### Comments on this Policy If you have suggestions on how this process could be improved please submit a pull request. +---- +# Contributing to Expressjs.com {#expressjs-website-contributing} + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + + + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue +So you've found a problem that you want to fix, or have a site enhancement you want to make. +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** +- These files make up the individual blog posts. If you want to contribute a blog post please +follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + + +1. __Run Locally__: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. __Run using Deploy Preview__: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a *draft* pull request. + 2. After the build steps are complete, you'll have access to a __Deploy Preview__ tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/en/resources/frameworks.md b/en/resources/frameworks.md deleted file mode 100644 index 86b791bee8..0000000000 --- a/en/resources/frameworks.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -layout: page -title: Frameworks built on Express -menu: frameworks -lang: en ---- - -# Frameworks built on Express - -{% include community-caveat.html %} - -Several popular Node.js frameworks are built on Express: - -- **[Feathers](http://feathersjs.com)**: Build prototypes in minutes and production ready real-time apps in days. -- **[ItemsAPI](https://www.itemsapi.com/)**: Search backend for web and mobile applications built on Express and Elasticsearch. -- **[KeystoneJS](http://keystonejs.com/)**: Website and API Application Framework / CMS with an auto-generated React.js Admin UI. -- **[Poet](http://jsantell.github.io/poet)**: Lightweight Markdown Blog Engine with instant pagination, tag and category views. -- **[Kraken](http://krakenjs.com/)**: Secure and scalable layer that extends Express by providing structure and convention. -- **[LoopBack](http://loopback.io)**: Highly-extensible, open-source Node.js framework for quickly creating dynamic end-to-end REST APIs. -- **[Sails](http://sailsjs.org/)**: MVC framework for Node.js for building practical, production-ready apps. -- **[Hydra-Express](https://github.com/flywheelsports/fwsp-hydra-express)**: Hydra-Express is a light-weight library which facilitates building Node.js Microservices using ExpressJS. -- **[Blueprint](http://github.com/onehilltech/blueprint)**: a SOLID framework for building APIs and backend services -- **[Locomotive](http://locomotivejs.org/)**: Powerful MVC web framework for Node.js from the maker of Passport.js -- **[graphql-yoga](https://github.com/graphcool/graphql-yoga)**: Fully-featured, yet simple and lightweight GraphQL server -- **[Express Gateway](https://express-gateway.io)**: Fully-featured and extensible API Gateway using Express as foundation -- **[Dinoloop](https://github.com/ParallelTask/dinoloop)**: Rest API Application Framework powered by typescript with dependency injection -- **[Kites](https://kites.nodejs.vn/)**: Template-based Web Application Framework -- **[FoalTS](https://foalts.org/)**: Elegant and all-inclusive Node.Js web framework based on TypeScript. -- **[NestJs](https://github.com/nestjs/nest)**: A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications on top of TypeScript & JavaScript (ES6, ES7, ES8) -- **[Expressive Tea](https://github.com/Zero-OneiT/expresive-tea)**: A Small framework for building modulable, clean, fast and descriptive server-side applications with Typescript and Express out of the box. diff --git a/en/resources/glossary.md b/en/resources/glossary.md index 08823b7016..837894eeba 100755 --- a/en/resources/glossary.md +++ b/en/resources/glossary.md @@ -1,8 +1,8 @@ --- layout: page title: Express glossary +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: en redirect_from: "/resources/glossary.html" --- @@ -14,11 +14,11 @@ In general, one or more programs that are designed to carry out operations for a ### API -Application programming interface. Spell out the abbreviation when it is first used. +Application programming interface. Spell out the abbreviation when it is first used. ### Express -A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable. +A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable. ### libuv @@ -26,23 +26,31 @@ A multi-platform support library which focuses on asynchronous I/O, primarily de ### middleware -A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: +A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: - * `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware. + * `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware. * `app.use(mw)` is called _adding the middleware to the global processing stack_. * `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_. ### Node.js -A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". +A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". ### open-source, open source -When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Note: Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. +When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). + +{% capture english-rules %} + +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. + +{% endcapture %} + +{% include admonitions/note.html content=english-rules %} ### request -An HTTP request. A client submits an HTTP request message to a server, which returns a response. 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. +An HTTP request. A client submits an HTTP request message to a server, which returns a response. 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 @@ -50,7 +58,7 @@ An HTTP response. A server returns an HTTP response message to the client. The r ### route -Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route. +Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route. ### router diff --git a/en/resources/learning.md b/en/resources/learning.md deleted file mode 100644 index 09e248f3f2..0000000000 --- a/en/resources/learning.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -layout: page -title: Additional learning -menu: resources -lang: en -redirect_from: "/resources/learning.html" ---- - -# Additional learning - -{% include community-caveat.html %} - -## Books - -Here are a few of the many books on Express: - -- **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, April 2016. - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Getting MEAN with Mongo, Express, Angular, and Node, Second Edition](http://www.manning.com/sholmes2/)**, -Manning Publications, April 2017. - - **[Pro Express.js: Master Express.js: The Node.js Framework For Your Web Development](http://www.apress.com/9781484200384)**, -Apress, December 2014. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 -- **[Builder Book: Build a Full Stack JavaScript Web App from Scratch](https://builderbook.org)**, self-published, February 2018. -- **[MERN Quick Start Guide](https://www.amazon.com/dp/1787281086)**, Packt Publishing, May 2018 -- **[Functional Design Patterns for Express.js](https://jonathanleemartin.com/books/)**, self-published, June 2019. -- **[SaaS Boilerplate Book: Build a Production-Ready SaaS Web App from Scratch](https://builderbook.org/book)**, self-published, August 2020. - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](https://strongloop.com/strongblog/tag_Express.html) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Baboon Blog: Express category](http://www.baboon.ir/tutorials/expressjs/) (Persian language) -- [Techforgeek Blog: Express category](http://techforgeek.com/expressjs/) -- [RoseHosting.com Blog: Express tag](https://www.rosehosting.com/blog/tag/express/) -- [ThisHosting.Rocks: Express tag](https://thishosting.rocks/tag/express-js/) -- [Code with Hugo blog: Express tag](https://codewithhugo.com/tags/express) -- [Dev.to blog: Express category](https://dev.to/ghvstcode/understanding-express-middleware-a-beginners-guide-g73) -- [LinuxStans Blog: Express tag](https://linuxstans.com/tag/express-js/) -- [ButterCMS blog: Express category](https://buttercms.com/blog/tag/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## The DEV community - -[DEV's express tag](https://dev.to/t/express) is a place to share Express projects, articles and tutorials as well as start discussions and ask for feedback on Express-related topics. Developers of all skill-levels are welcome to take part. - -## Video tutorials -- [Learning ExpressJS: Express category](https://getbuzz.io/c/learning-expressjs) -- [Learn Express.js in 14 days](https://iLoveCoding.org/courses/expressjs) - Practice Projects included diff --git a/en/resources/middleware.md b/en/resources/middleware.md index a591f23679..309c03f478 100755 --- a/en/resources/middleware.md +++ b/en/resources/middleware.md @@ -1,8 +1,8 @@ --- layout: middleware title: Express middleware +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: en redirect_from: "/resources/middleware.html" module: mw-home --- @@ -12,26 +12,25 @@ module: mw-home The Express middleware modules listed here are maintained by the [Expressjs team](https://github.com/orgs/expressjs/people). -|Middleware module | Description | Replaces built-in function (Express 3)| -|---------------------------|---------------------|----------------------| -| [body-parser](/resources/middleware/body-parser.html) | Parse HTTP request body. See also: [body](https://github.com/raynos/body), [co-body](https://github.com/visionmedia/co-body), and [raw-body](https://github.com/stream-utils/raw-body). | express.bodyParser | -| [compression](/resources/middleware/compression.html) | Compress HTTP responses. | express.compress | -| [connect-rid](/resources/middleware/connect-rid.html) | Generate unique request ID. | NA | -| [cookie-parser](/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies) and [keygrip](https://github.com/jed/keygrip). | express.cookieParser| -| [cookie-session](/resources/middleware/cookie-session.html) | Establish cookie-based sessions.| express.cookieSession | -| [cors](/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options.| NA -| [csurf](/resources/middleware/csurf.html) | Protect from CSRF exploits.|express.csrf | -| [errorhandler](/resources/middleware/errorhandler.html) |Development error-handling/debugging. |express.errorHandler | -| [method-override](/resources/middleware/method-override.html) |Override HTTP methods using header. |express.methodOverride | -| [morgan](/resources/middleware/morgan.html) | HTTP request logger. | express.logger | -| [multer](/resources/middleware/multer.html) | Handle multi-part form data. | express.bodyParser | -| [response-time](/resources/middleware/response-time.html) | Record HTTP response time. |express.responseTime | -| [serve-favicon](/resources/middleware/serve-favicon.html) | Serve a favicon. |express.favicon | -| [serve-index](/resources/middleware/serve-index.html) | Serve directory listing for a given path.| express.directory | -| [serve-static](/resources/middleware/serve-static.html) |Serve static files. |express.static | -| [session](/resources/middleware/session.html) | Establish server-based sessions (development only). | express.session | -| [timeout](/resources/middleware/timeout.html) | Set a timeout period for HTTP request processing.|express.timeout | -| [vhost](/resources/middleware/vhost.html) |Create virtual domains.|express.vhost| +| Middleware module | Description | +| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | ## Additional middleware modules @@ -39,21 +38,7 @@ These are some additional popular middleware modules. {% include community-caveat.html %} -|Middleware module | Description | -|---------------------------|---------------------| -| [cls-rtracer](https://github.com/puzpuzpuz/cls-rtracer) | Middleware for CLS-based request id generation. An out-of-the-box solution for adding request ids into your logs.| -| [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus) | Optimize image serving. Switches images to `.webp` or `.jxr`, if possible.| -| [express-debug](https://github.com/devoidfury/express-debug) | Development tool that adds information about template variables (locals), current session, and so on.| -| [express-partial-response](https://github.com/nemtsov/express-partial-response) | Filters out parts of JSON responses based on the `fields` query-string; by using Google API's Partial Response.| -| [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn) | Use a CDN for static assets, with multiple host support.| -| [express-slash](https://github.com/ericf/express-slash) | Handles routes with and without trailing slashes.| -| [express-stormpath](https://github.com/stormpath/stormpath-express) | User storage, authentication, authorization, SSO, and data security.| -| [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize) | Redirects HTTP requests containing uppercase to a canonical lowercase form.| -| [helmet](https://github.com/helmetjs/helmet) |Helps secure your apps by setting various HTTP headers.| -| [join-io](https://github.com/coderaiser/join-io) | Joins files on the fly to reduce the requests count.| -| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [http://passportjs.org/](http://passportjs.org/) for more information.| -| [static-expiry](https://github.com/paulwalker/connect-static-expiry) | Fingerprint URLs or caching headers for static assets.| -| [view-helpers](https://github.com/madhums/node-view-helpers) | Common helper methods for views.| -| [sriracha-admin](https://github.com/hdngr/siracha) | Dynamically generate an admin site for Mongoose. | - -For more middleware modules, see [http-framework](https://github.com/Raynos/http-framework#modules). +| Middleware module | Description | +| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/en/resources/middleware/body-parser.md b/en/resources/middleware/body-parser.md index bf7d7e94f2..8ccac905c5 100644 --- a/en/resources/middleware/body-parser.md +++ b/en/resources/middleware/body-parser.md @@ -2,7 +2,6 @@ layout: middleware title: Express body-parser middleware menu: resources -lang: en redirect_from: '/resources/middleware/body-parser.html' module: body-parser --- diff --git a/en/resources/middleware/compression.md b/en/resources/middleware/compression.md index 93f5374692..a3cc042841 100644 --- a/en/resources/middleware/compression.md +++ b/en/resources/middleware/compression.md @@ -2,7 +2,6 @@ layout: middleware title: Express compression middleware menu: resources -lang: en redirect_from: '/resources/middleware/compression.html' module: compression --- diff --git a/en/resources/middleware/connect-rid.md b/en/resources/middleware/connect-rid.md index aa2da99077..ea5e61ea4d 100644 --- a/en/resources/middleware/connect-rid.md +++ b/en/resources/middleware/connect-rid.md @@ -2,7 +2,6 @@ layout: middleware title: Express connect-rid middleware menu: resources -lang: en redirect_from: '/resources/middleware/connect-rid.html' module: connect-rid --- diff --git a/en/resources/middleware/cookie-parser.md b/en/resources/middleware/cookie-parser.md index 2866eec3e8..4e5c6de057 100644 --- a/en/resources/middleware/cookie-parser.md +++ b/en/resources/middleware/cookie-parser.md @@ -2,7 +2,6 @@ layout: middleware title: Express cookie-parser middleware menu: resources -lang: en redirect_from: '/resources/middleware/cookie-parser.html' module: cookie-parser --- diff --git a/en/resources/middleware/cookie-session.md b/en/resources/middleware/cookie-session.md index 282e0c1c1e..31766811d5 100644 --- a/en/resources/middleware/cookie-session.md +++ b/en/resources/middleware/cookie-session.md @@ -2,7 +2,6 @@ layout: middleware title: Express cookie-session middleware menu: resources -lang: en redirect_from: '/resources/middleware/cookie-session.html' module: cookie-session --- diff --git a/en/resources/middleware/cors.md b/en/resources/middleware/cors.md index f4fa033c1a..21f2169ec5 100644 --- a/en/resources/middleware/cors.md +++ b/en/resources/middleware/cors.md @@ -2,7 +2,6 @@ layout: middleware title: Express cors middleware menu: resources -lang: en redirect_from: '/resources/middleware/cors.html' module: cors --- diff --git a/en/resources/middleware/csurf.md b/en/resources/middleware/csurf.md deleted file mode 100644 index 432404e8f6..0000000000 --- a/en/resources/middleware/csurf.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: middleware -title: Express csurf middleware -menu: resources -lang: en -redirect_from: '/resources/middleware/csurf.html' -module: csurf ---- diff --git a/en/resources/middleware/errorhandler.md b/en/resources/middleware/errorhandler.md index d552407463..208524bc55 100644 --- a/en/resources/middleware/errorhandler.md +++ b/en/resources/middleware/errorhandler.md @@ -2,7 +2,6 @@ layout: middleware title: Express errorhandler middleware menu: resources -lang: en redirect_from: '/resources/middleware/errorhandler.html' module: errorhandler --- diff --git a/en/resources/middleware/method-override.md b/en/resources/middleware/method-override.md index e0145af722..a3e5544f37 100644 --- a/en/resources/middleware/method-override.md +++ b/en/resources/middleware/method-override.md @@ -2,7 +2,6 @@ layout: middleware title: Express method-override middleware menu: resources -lang: en redirect_from: '/resources/middleware/method-override.html' module: method-override --- diff --git a/en/resources/middleware/morgan.md b/en/resources/middleware/morgan.md index 36ea8986ff..5407b23ae2 100644 --- a/en/resources/middleware/morgan.md +++ b/en/resources/middleware/morgan.md @@ -2,7 +2,6 @@ layout: middleware title: Express morgan middleware menu: resources -lang: en redirect_from: '/resources/middleware/morgan.html' module: morgan --- diff --git a/en/resources/middleware/multer.md b/en/resources/middleware/multer.md index ad389f6ab6..621660a92e 100644 --- a/en/resources/middleware/multer.md +++ b/en/resources/middleware/multer.md @@ -2,7 +2,6 @@ layout: middleware title: Express multer middleware menu: resources -lang: en redirect_from: '/resources/middleware/multer.html' module: multer --- diff --git a/en/resources/middleware/response-time.md b/en/resources/middleware/response-time.md index ff7d2e1630..e005f72465 100644 --- a/en/resources/middleware/response-time.md +++ b/en/resources/middleware/response-time.md @@ -2,7 +2,6 @@ layout: middleware title: Express response-time middleware menu: resources -lang: en redirect_from: '/resources/middleware/response-time.html' module: response-time --- diff --git a/en/resources/middleware/serve-favicon.md b/en/resources/middleware/serve-favicon.md index 897d84b1a5..b0e9fac621 100644 --- a/en/resources/middleware/serve-favicon.md +++ b/en/resources/middleware/serve-favicon.md @@ -2,7 +2,6 @@ layout: middleware title: Express serve-favicon middleware menu: resources -lang: en redirect_from: '/resources/middleware/serve-favicon.html' module: serve-favicon --- diff --git a/en/resources/middleware/serve-index.md b/en/resources/middleware/serve-index.md index f91ab07f04..0adf89229f 100644 --- a/en/resources/middleware/serve-index.md +++ b/en/resources/middleware/serve-index.md @@ -2,7 +2,6 @@ layout: middleware title: Express serve-index middleware menu: resources -lang: en redirect_from: '/resources/middleware/serve-index.html' module: serve-index --- diff --git a/en/resources/middleware/serve-static.md b/en/resources/middleware/serve-static.md index 343a1d7fea..6103a26b40 100644 --- a/en/resources/middleware/serve-static.md +++ b/en/resources/middleware/serve-static.md @@ -2,7 +2,6 @@ layout: middleware title: Express serve-static middleware menu: resources -lang: en redirect_from: '/resources/middleware/serve-static.html' module: serve-static --- diff --git a/en/resources/middleware/session.md b/en/resources/middleware/session.md index 69322de1b6..2e95e8456c 100644 --- a/en/resources/middleware/session.md +++ b/en/resources/middleware/session.md @@ -2,7 +2,6 @@ layout: middleware title: Express session middleware menu: resources -lang: en redirect_from: '/resources/middleware/session.html' module: session --- diff --git a/en/resources/middleware/timeout.md b/en/resources/middleware/timeout.md index 00d313556d..0b9d2253f8 100644 --- a/en/resources/middleware/timeout.md +++ b/en/resources/middleware/timeout.md @@ -2,7 +2,6 @@ layout: middleware title: Express timeout middleware menu: resources -lang: en redirect_from: '/resources/middleware/timeout.html' module: timeout --- diff --git a/en/resources/middleware/vhost.md b/en/resources/middleware/vhost.md index 4c6fb44d03..7f42ece96b 100644 --- a/en/resources/middleware/vhost.md +++ b/en/resources/middleware/vhost.md @@ -2,7 +2,6 @@ layout: middleware title: Express vhost middleware menu: resources -lang: en redirect_from: '/resources/middleware/vhost.html' module: vhost --- diff --git a/en/resources/open-source-using-express.md b/en/resources/open-source-using-express.md deleted file mode 100644 index 8cc8f6df40..0000000000 --- a/en/resources/open-source-using-express.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -layout: page -title: Open source using Express -menu: resources -lang: en -redirect_from: "/resources/open-source-using-express.html" ---- - -# Open source projects using Express - -{% include community-caveat.html %} - -Some open-source projects that use Express: - -- **[Builder Book](https://github.com/builderbook/builderbook)**: Open source web app to publish documentation or books. Built with React, Material-UI, Next, Express, Mongoose, MongoDB. -- **[SaaS Boilerplate](https://github.com/async-labs/saas)**: Open source web app to build your own SaaS product. Built with React, Material-UI, Next, MobX, Express, Mongoose, MongoDB, Typescript. -- **[BitMidi](https://bitmidi.com)**: Open source web app powered by Express. BitMidi is a historical archive of MIDI files from the early web era. It uses the latest modern web technology including WebAssembly and Web Audio to bring MIDI back to life. ([source code](https://github.com/feross/bitmidi.com)) diff --git a/en/resources/template-engines.md b/en/resources/template-engines.md deleted file mode 100644 index 9d8e3bff2d..0000000000 --- a/en/resources/template-engines.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -layout: page -title: Template Engines -menu: resources -lang: en -redirect_from: "/resources/template-engines.html" ---- - -# Template engines - -{% include warning.html content="The packages listed below may be outdated, no longer maintained or even broken. Listing here does not constitute an endorsement or recommendation from the Expressjs project team. Use at your own risk." %} - -These template engines work "out-of-the-box" with Express: - -- **[Pug](https://github.com/pugjs/pug)**: Haml-inspired template engine (formerly Jade). -- **[Haml.js](https://github.com/tj/haml.js)**: Haml implementation. -- **[EJS](https://github.com/mde/ejs)**: Embedded JavaScript template engine. -- **[hbs](https://github.com/pillarjs/hbs)**: Adapter for Handlebars.js, an extension of Mustache.js template engine. -- **[Squirrelly](https://github.com/squirrellyjs/squirrelly)**: Blazing-fast template engine that supports partials, helpers, custom tags, filters, and caching. Not white-space sensitive, works with any language. -- **[Eta](https://github.com/eta-dev/eta)**: Super-fast lightweight embedded JS template engine. Supports custom delimiters, async, whitespace control, partials, caching, plugins. -- **[React](https://github.com/reactjs/express-react-views)**: Renders React components on the server. It renders static markup and does not support mounting those views on the client. -- **[combyne.js](https://github.com/tbranyen/combyne)**: A template engine that hopefully works the way you'd expect. -- **[Nunjucks](https://github.com/mozilla/nunjucks)**: Inspired by jinja/twig. -- **[marko](https://github.com/marko-js/marko)**: A fast and lightweight HTML-based templating engine that compiles templates to CommonJS modules and supports streaming, async rendering and custom tags. (Renders directly to the HTTP response stream). -- **[whiskers](https://github.com/gsf/whiskers.js)**: Small, fast, mustachioed. -- **[Blade](https://github.com/bminer/node-blade)**: HTML Template Compiler, inspired by Jade & Haml. -- **[Haml-Coffee](https://github.com/netzpirat/haml-coffee)**: Haml templates where you can write inline CoffeeScript. -- **[express-hbs](https://github.com/barc/express-hbs)**: Handlebars with layouts, partials and blocks for express 3 from Barc. -- **[express-handlebars](https://github.com/express-handlebars/express-handlebars)**: A Handlebars view engine for Express which doesn't suck. -- **[express-views-dom](https://github.com/AndersDJohnson/express-views-dom)**: A DOM view engine for Express. -- **[rivets-server](https://github.com/AndersDJohnson/rivets-server)**: Render Rivets.js templates on the server. -- **[LiquidJS](https://github.com/harttle/liquidjs)**: A simple, expressive and safe template engine. -- **[express-tl](https://github.com/Drulac/express-tl)**: A template-literal engine implementation for Express. -- **[Twing](https://www.npmjs.com/package/twing)**: First-class Twig engine for Node.js. -- **[Sprightly](https://www.npmjs.com/package/sprightly)**: A very light-weight JS template engine (45 lines of code), that consists of all the bare-bones features that you want to see in a template engine. - -The [Consolidate.js](https://github.com/tj/consolidate.js) library unifies the APIs of these template engines to a single Express-compatible API. - - - -### Add your template engine here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/en/resources/template-engines.md) and add a link to your project, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/en/resources/utils.md b/en/resources/utils.md index 2f2b9bea6c..9865e4594b 100644 --- a/en/resources/utils.md +++ b/en/resources/utils.md @@ -1,14 +1,14 @@ --- layout: page 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. menu: resources -lang: en redirect_from: "/resources/utilities.html" --- ## Express utility functions -The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules +The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules for utility functions that may be generally useful. | Utility modules | Description| @@ -17,13 +17,10 @@ for utility functions that may be generally useful. | [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-match](https://www.npmjs.com/package/path-match) | Thin wrapper around [path-to-regexp](https://github.com/component/path-to-regexp) to make extracting parameter names easier.| | [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. | -| [routington](https://www.npmjs.com/package/routington) | Trie-based URL router for defining and matching URLs. | | [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.| -| [templation](https://www.npmjs.com/package/templation) | View system similar to `res.render()` inspired by [co-views](https://github.com/visionmedia/co-views) and [consolidate.js](https://github.com/visionmedia/consolidate.js/). | -For additional low-level HTTP-related modules, see [jshttp](http://jshttp.github.io/) . +For additional low-level HTTP-related modules, see [jshttp](http://jshttp.github.io/). diff --git a/en/starter/basic-routing.md b/en/starter/basic-routing.md index e209499681..00a65988ab 100755 --- a/en/starter/basic-routing.md +++ b/en/starter/basic-routing.md @@ -1,8 +1,8 @@ --- layout: page title: Express basic routing +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: en redirect_from: "/starter/basic-routing.html" --- @@ -34,15 +34,15 @@ The following examples illustrate defining simple routes. Respond with `Hello World!` on the homepage: ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('Hello World!') }) ``` -Respond to POST request on the root route (`/`), the application's home page: +Respond to a POST request on the root route (`/`), the application's home page: ```js -app.post('/', function (req, res) { +app.post('/', (req, res) => { res.send('Got a POST request') }) ``` @@ -50,7 +50,7 @@ app.post('/', function (req, res) { Respond to a PUT request to the `/user` route: ```js -app.put('/user', function (req, res) { +app.put('/user', (req, res) => { res.send('Got a PUT request at /user') }) ``` @@ -58,7 +58,7 @@ app.put('/user', function (req, res) { Respond to a DELETE request to the `/user` route: ```js -app.delete('/user', function (req, res) { +app.delete('/user', (req, res) => { res.send('Got a DELETE request at /user') }) ``` diff --git a/en/starter/examples.md b/en/starter/examples.md index 3d651cf6b8..ca376a2e64 100755 --- a/en/starter/examples.md +++ b/en/starter/examples.md @@ -1,12 +1,21 @@ --- layout: page title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. menu: starter -lang: en redirect_from: "/starter/examples.html" --- {% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} {{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} -### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/en/starter/faq.md b/en/starter/faq.md index 91026c86eb..80ce90b3bf 100755 --- a/en/starter/faq.md +++ b/en/starter/faq.md @@ -1,8 +1,8 @@ --- layout: page title: Express FAQ +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: en redirect_from: "/starter/faq.html" --- @@ -37,7 +37,7 @@ See [LoopBack](http://loopback.io) for an Express-based framework that is center ## How can I authenticate users? Authentication is another opinionated area that Express does not -venture into. You may use any authentication scheme you wish. +venture into. You may use any authentication scheme you wish. For a simple username / password scheme, see [this example](https://github.com/expressjs/express/tree/master/examples/auth). @@ -61,7 +61,7 @@ do is add a middleware function at the very bottom of the stack (below all other to handle a 404 response: ```js -app.use(function (req, res, next) { +app.use((req, res, next) => { res.status(404).send("Sorry can't find that!") }) ``` @@ -75,7 +75,7 @@ You define error-handling middleware in the same way as other middleware, except with four arguments instead of three; specifically with the signature `(err, req, res, next)`: ```js -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) @@ -90,4 +90,9 @@ If you have a specific file, use the `res.sendFile()` function. If you are serving many assets from a directory, use the `express.static()` middleware function. +## What version of Node.js does Express require? + +* [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +* [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + ### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/en/starter/generator.md b/en/starter/generator.md index b042dcb177..a95c9dcbfe 100755 --- a/en/starter/generator.md +++ b/en/starter/generator.md @@ -1,8 +1,8 @@ --- layout: page title: Express application generator +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: en redirect_from: "/starter/generator.html" --- @@ -12,20 +12,20 @@ Use the application generator tool, `express-generator`, to quickly create an ap You can run the application generator with the `npx` command (available in Node.js 8.2.0). -```sh +```bash $ npx express-generator ``` For earlier Node versions, install the application generator as a global npm package and then launch it: -```sh +```bash $ npm install -g express-generator $ express ``` Display the command options with the `-h` option: -```sh +```bash $ express -h Usage: express [options] [dir] @@ -47,7 +47,7 @@ $ express -h For example, the following creates an Express app named _myapp_. The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: -```sh +```bash $ express --view=pug myapp create : myapp @@ -71,35 +71,35 @@ $ express --view=pug myapp Then install dependencies: -```sh +```bash $ cd myapp $ npm install ``` On MacOS or Linux, run the app with this command: -```sh +```bash $ DEBUG=myapp:* npm start ``` On Windows Command Prompt, use this command: -```sh +```bash > set DEBUG=myapp:* & npm start ``` On Windows PowerShell, use this command: -```sh +```bash PS> $env:DEBUG='myapp:*'; npm start ``` -Then load `http://localhost:3000/` in your browser to access the app. +Then, load `http://localhost:3000/` in your browser to access the app. The generated app has the following directory structure: -```sh +```bash . ├── app.js ├── bin diff --git a/en/starter/hello-world.md b/en/starter/hello-world.md index e5c66a8b5f..67c9aee082 100755 --- a/en/starter/hello-world.md +++ b/en/starter/hello-world.md @@ -1,8 +1,8 @@ --- layout: page title: Express "Hello World" example +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: en redirect_from: "/starter/hello-world.html" --- @@ -12,8 +12,7 @@ redirect_from: "/starter/hello-world.html" Embedded below is essentially the simplest Express app you can create. It is a single file app — _not_ what you'd get if you use the [Express generator](/{{ page.lang }}/starter/generator.html), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes.
    - -
    
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -23,25 +22,18 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    +``` This app starts a server and listens on port 3000 for connections. The app responds with "Hello World!" for requests to the root URL (`/`) or _route_. For every other path, it will respond with a **404 Not Found**. -The example above is actually a working server: Go ahead and click on the URL shown. You'll get a response, with real-time logs on the page, and any changes you make will be reflected in real time. This is powered by [RunKit](https://runkit.com), which provides an interactive JavaScript playground connected to a complete Node environment that runs in your web browser. -Below are instructions for running the same app on your local machine. - -
    -RunKit is a third-party service not affiliated with the Express project. -
    - ### Running Locally -First create a directory named `myapp`, change to it and run `npm init`. Then install `express` as a dependency, as per the [installation guide](/{{ page.lang }}/starter/installing.html). +First create a directory named `myapp`, change to it and run `npm init`. Then, install `express` as a dependency, as per the [installation guide](/{{ page.lang }}/starter/installing.html). -In the `myapp` directory, create a file named `app.js` and copy in the code from the example above. +In the `myapp` directory, create a file named `app.js` and copy the code from the example above.
    The `req` (request) and `res` (response) are the exact same objects that Node provides, so you can invoke @@ -50,7 +42,7 @@ The `req` (request) and `res` (response) are the exact same objects that Node pr Run the app with the following command: -```sh +```bash $ node app.js ``` diff --git a/en/starter/installing.md b/en/starter/installing.md index 326fc696f7..9f99a681f2 100755 --- a/en/starter/installing.md +++ b/en/starter/installing.md @@ -1,8 +1,8 @@ --- layout: page title: Installing Express +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: en redirect_from: "/starter/installing.html" --- @@ -10,7 +10,10 @@ redirect_from: "/starter/installing.html" Assuming you've already installed [Node.js](https://nodejs.org/), create a directory to hold your application, and make that your working directory. -```sh +* [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +* [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +```bash $ mkdir myapp $ cd myapp ``` @@ -18,33 +21,33 @@ $ cd myapp Use the `npm init` command to create a `package.json` file for your application. For more information on how `package.json` works, see [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). -```sh +```bash $ npm init ``` This command prompts you for a number of things, such as the name and version of your application. For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception: -```sh +``` entry point: (index.js) ``` Enter `app.js`, or whatever you want the name of the main file to be. If you want it to be `index.js`, hit RETURN to accept the suggested default file name. -Now install Express in the `myapp` directory and save it in the dependencies list. For example: +Now, install Express in the `myapp` directory and save it in the dependencies list. For example: -```sh -$ npm install express --save +```bash +$ npm install express ``` To install Express temporarily and not add it to the dependencies list: -```sh +```bash $ npm install express --no-save ```
    -By default with version npm 5.0+ npm install adds the module to the `dependencies` list in the `package.json` file; with earlier versions of npm, you must specify the `--save` option explicitly. Then, afterwards, running `npm install` in the app directory will automatically install modules in the dependencies list. +By default with version npm 5.0+, `npm install` adds the module to the `dependencies` list in the `package.json` file; with earlier versions of npm, you must specify the `--save` option explicitly. Then, afterwards, running `npm install` in the app directory will automatically install modules in the dependencies list.
    -### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/en/starter/static-files.md b/en/starter/static-files.md index 3699839925..3d5e4309bf 100755 --- a/en/starter/static-files.md +++ b/en/starter/static-files.md @@ -1,8 +1,8 @@ --- layout: page title: Serving static files in Express +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: en redirect_from: "/starter/static-files.html" --- @@ -17,7 +17,7 @@ express.static(root, [options]) ``` The `root` argument specifies the root directory from which to serve static assets. -For more information on the `options` argument, see [express.static](/{{page.lang}}/4x/api.html#express.static). +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). For example, use the following code to serve images, CSS files, and JavaScript files in a directory named `public`: @@ -27,7 +27,7 @@ app.use(express.static('public')) Now, you can load the files that are in the `public` directory: -```plain-text +```text http://localhost:3000/images/kitten.jpg http://localhost:3000/css/style.css http://localhost:3000/js/app.js @@ -48,10 +48,12 @@ app.use(express.static('files')) Express looks up the files in the order in which you set the static directories with the `express.static` middleware function. -
    NOTE: For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. -
    +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/4x/api.html#app.use) for the static directory, as shown below: +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: ```js app.use('/static', express.static('public')) @@ -59,7 +61,7 @@ app.use('/static', express.static('public')) Now, you can load the files that are in the `public` directory from the `/static` path prefix. -```plain-text +```text http://localhost:3000/static/images/kitten.jpg http://localhost:3000/static/css/style.css http://localhost:3000/static/js/app.js diff --git a/en/support/index.md b/en/support/index.md new file mode 100644 index 0000000000..dcd2620b8f --- /dev/null +++ b/en/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/es/3x/api.md b/es/3x/api.md old mode 100755 new mode 100644 index d33cc2114f..686bac7ccc --- a/es/3x/api.md +++ b/es/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - Referencia de API +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: es +redirect_from: " " --- +
    **Express 3.x YA NO SE MANTIENE** - Los problemas de rendimiento y seguridad conocidos y desconocidos en 3.x no se han solucionado desde la última actualización (1 de agosto de 2015). Se recomienda especialmente utilizar la última versión de Express. -
    - -

    API de 3.x

    +Los problemas de rendimiento y seguridad conocidos y desconocidos en 3.x no se han solucionado desde la última actualización (1 de agosto de 2015). Se recomienda especialmente utilizar la última versión de Express. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
    - - {% include api/en/3x/res.md %} +

    API de 3.x

    - - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %}
    diff --git a/es/4x/api.md b/es/4x/api.md old mode 100755 new mode 100644 index 1a6f448e14..469f55025c --- a/es/4x/api.md +++ b/es/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - Referencia de API +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: es +redirect_from: " " --- +

    API de 4.x

    - - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
    diff --git a/es/5x/api.md b/es/5x/api.md new file mode 100644 index 0000000000..8817b56a14 --- /dev/null +++ b/es/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - Referencia de API +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
    + +

    5.x API

    + +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
    diff --git a/es/advanced/best-practice-performance.md b/es/advanced/best-practice-performance.md old mode 100755 new mode 100644 index d5573a1ae4..2d04813695 --- a/es/advanced/best-practice-performance.md +++ b/es/advanced/best-practice-performance.md @@ -1,51 +1,48 @@ --- layout: page title: Mejores prácticas de rendimiento cuando se utiliza Express en producción +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: es +redirect_from: " " --- -# Mejores prácticas de producción: rendimiento y fiabilidad - -## Visión general +# Production best practices: performance and reliability En este artículo se describen las mejores prácticas de rendimiento y fiabilidad para las aplicaciones Express desplegadas en producción. Este tema entra claramente dentro del área de "DevOps", que abarca operaciones y desarrollos tradicionales. Por lo tanto, la información se divide en dos partes: -- Cosas que hacer en el código (la parte de desarrollo): - - [Utilizar la compresión de gzip](#utilizar-la-compresión-de-gzip) - - [No utilizar funciones síncronas](#no-utilizar-funciones-síncronas) - - [Realizar un registro correcto](#realizar-un-registro-correcto) - - [Manejar las excepciones correctamente](#manejar-las-excepciones-correctamente) -- Cosas que hacer en el entorno / configuración (la parte de operaciones): - - - [Establecer NODE_ENV en "production"](#establecer-node_env-en-production) - - [Asegurarse de que la aplicación se reinicia automáticamente](#asegurarse-de-que-la-aplicación-se-reinicia-automáticamente) - - [Ejecutar la aplicación en un clúster](#ejecutar-la-aplicación-en-un-clúster) - - [Almacenar en la caché los resultados de la solicitud](#almacenar-en-la-caché-los-resultados-de-la-solicitud) - - [Utilizar un equilibrador de carga](#utilizar-un-equilibrador-de-carga) - - [Utilizar un proxy inverso](#utilizar-un-proxy-inverso) - - +- Cosas que hacer en el código (la parte de desarrollo): + - [Utilizar la compresión de gzip](#utilizar-la-compresión-de-gzip) + - [No utilizar funciones síncronas](#no-utilizar-funciones-síncronas) + - [Realizar un registro correcto](#realizar-un-registro-correcto) + - [Manejar las excepciones correctamente](#manejar-las-excepciones-correctamente) +- Cosas que hacer en el entorno / configuración (la parte de operaciones): + - [Establecer NODE_ENV en "production"](#establecer-node_env-en-production) + - [Asegurarse de que la aplicación se reinicia automáticamente](#asegurarse-de-que-la-aplicación-se-reinicia-automáticamente) + - [Ejecutar la aplicación en un clúster](#ejecutar-la-aplicación-en-un-clúster) + - [Almacenar en la caché los resultados de la solicitud](#almacenar-en-la-caché-los-resultados-de-la-solicitud) + - [Utilizar un equilibrador de carga](#utilizar-un-equilibrador-de-carga) + - [Utilizar un proxy inverso](#utilizar-un-proxy-inverso) ## Cosas que hacer en el código Estas son algunas de las cosas que puede hacer en el código para mejorar el rendimiento de la aplicación: -- [Utilizar la compresión de gzip](#utilizar-la-compresión-de-gzip) -- [No utilizar funciones síncronas](#no-utilizar-funciones-síncronas) -- [Realizar un registro correcto](#realizar-un-registro-correcto) -- [Manejar las excepciones correctamente](#manejar-las-excepciones-correctamente) +- [Utilizar la compresión de gzip](#utilizar-la-compresión-de-gzip) +- [No utilizar funciones síncronas](#no-utilizar-funciones-síncronas) +- [Realizar un registro correcto](#realizar-un-registro-correcto) +- [Manejar las excepciones correctamente](#manejar-las-excepciones-correctamente) ### Utilizar la compresión de gzip -La compresión de gzip puede disminuir significativamente el tamaño del cuerpo de respuesta y, por lo tanto, aumentar la velocidad de una aplicación web. Utilice el middleware de [compresión](https://www.npmjs.com/package/compression) para la compresión de gzip en la aplicación Express. Por ejemplo: +La compresión de gzip puede disminuir significativamente el tamaño del cuerpo de respuesta y, por lo tanto, aumentar la velocidad de una aplicación web. Utilice el middleware de [compresión](https://www.npmjs.com/package/compression) para la compresión de gzip en la aplicación Express. For example: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` @@ -57,21 +54,19 @@ Las funciones síncronas y los métodos impiden el avance del proceso de ejecuci Aunque Node y muchos módulos proporcionan versiones síncronas y asíncronas de las funciones, utilice siempre la versión asíncrona en producción. La única vez que está justificado utilizar una función síncrona es en el arranque inicial. -Si utiliza Node.js 4.0+ o io.js 2.1.0+, puede utilizar el distintivo de línea de mandatos `--trace-sync-io` para imprimir un aviso y un seguimiento de la pila siempre que la aplicación utilice una API síncrona. Desde luego, no deseará utilizarlo en producción, sólo para garantizar que el código está listo para producción. Consulte [Weekly update for io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0) para obtener más información. +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. Desde luego, no deseará utilizarlo en producción, sólo para garantizar que el código está listo para producción. Consulte [Weekly update for io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0) para obtener más información. ### Realizar un registro correcto -En general, hay dos motivos para realizar un registro desde la aplicación: a efectos de depuración o para registrar la actividad de la aplicación (básicamente, todo lo demás). El uso de `console.log()` o `console.err()` para imprimir mensajes de registro en el terminal es una práctica común en el desarrollo. No obstante, [estas funciones son síncronas](https://nodejs.org/api/console.html#console_console_1) cuando el destino es un terminal o un archivo, por lo que no son adecuadas para producción, a menos que canalice la salida a otro programa. +En general, hay dos motivos para realizar un registro desde la aplicación: a efectos de depuración o para registrar la actividad de la aplicación (básicamente, todo lo demás). El uso de `console.log()` o `console.err()` para imprimir mensajes de registro en el terminal es una práctica común en el desarrollo. 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. -#### A efectos de depuración +#### For debugging Si realiza el registro a efectos de depuración, en lugar de utilizar `console.log()`, utilice un módulo de depuración especial como [debug](https://www.npmjs.com/package/debug). Este módulo permite utilizar la variable de entorno DEBUG para controlar qué mensajes de depuración se envían a `console.err()`, si se envía alguno. Para mantener la aplicación básicamente asíncrona, deberá canalizar `console.err()` a otro programa. Pero en este caso, realmente no va a depurar en producción, ¿no? #### Para la actividad de la aplicación -Si está registrando la actividad de la aplicación (por ejemplo, realizando un seguimiento del tráfico o las llamadas de API), en lugar de utilizar `console.log()`, utilice una biblioteca de registro como [Winston](https://www.npmjs.com/package/winston) o [Bunyan](https://www.npmjs.com/package/bunyan). Para ver una comparación detallada de estas dos bibliotecas, consulte el post del blog StrongLoop [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - - +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. ### Manejar las excepciones correctamente @@ -79,32 +74,19 @@ Las aplicaciones Node se bloquean cuando encuentran una excepción no capturada. Para asegurarse de manejar todas las excepciones, siga estas técnicas: -- [Utilizar try-catch](#try-catch) -- [Utilizar promesas](#utilizar-promesas) +- [Utilizar try-catch](#try-catch) +- [Utilizar promesas](#utilizar-promesas) Antes de profundizar en estos temas, deberá tener unos conocimientos básicos del manejo de errores de Node/Express: el uso de devoluciones de llamada error-first y la propagación de errores en el middleware. Node utiliza un convenio de "devolución de llamada error-first" para devolver los errores de las funciones asíncronas, donde el primer parámetro en la función de devolución de llamada es el objeto de error, seguido de los datos de resultados en los parámetros posteriores. Para indicar que no hay ningún error, pase null como el primer parámetro. La función de devolución de llamada debe seguir por lo tanto el convenio de devolución de llamada error-first para manejar correctamente el error. En Express, la práctica recomendada es utilizar la función next() para propagar los errores a través de la cadena de middleware. Para obtener más información sobre los aspectos básicos del manejo de errores, consulte: -- [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -- [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (blog StrongLoop) - -#### Qué no debe hacer - -Algo que _no_ debe hacer es escuchar el suceso `uncaughtException`, que se emite cuando una excepción se reproduce hacia atrás en el bucle de sucesos. La adición de un escucha de sucesos para `uncaughtException` cambiará el comportamiento predeterminado del proceso que se encuentra con la excepción; el proceso continuará ejecutándose a pesar de la excepción. Esto puede parecer una buena forma de evitar el bloqueo de la aplicación, pero continuar ejecutando la aplicación después de una excepción no capturada es una práctica peligrosa y no se recomienda, ya que el estado del proceso se vuelve imprevisible y poco fiable. - -Asimismo, el uso de `uncaughtException` se reconoce oficialmente como un mecanismo [arduo](https://nodejs.org/api/process.html#process_event_uncaughtexception) y hay una [propuesta](https://github.com/nodejs/node-v0.x-archive/issues/2582) para eliminarlo del núcleo. Por lo tanto, la escucha `uncaughtException` no es una buena idea. Es por esto por lo que se recomiendan varios procesos y supervisores; el bloqueo y el reinicio es a menudo la forma más fiable de recuperarse de un error. - -Tampoco se recomienda el uso de [dominios](https://nodejs.org/api/domain.html). Generalmente no soluciona el problema y es un módulo en desuso. - - +- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### Utilizar try-catch Try-catch es una construcción de lenguaje JavaScript que puede utilizar para capturar excepciones en código síncrono. Por ejemplo, utilice try-catch para manejar los errores de análisis de JSON, como se muestra a continuación. -Utilice una herramienta como [JSHint](http://jshint.com/) o [JSLint](http://www.jslint.com/) para buscar excepciones implícitas como [errores de referencia o variables sin definir](http://www.jshint.com/docs/options/#undef). - A continuación, se muestra un ejemplo de uso de try-catch para manejar una posible excepción de bloqueo de proceso. Esta función de middleware acepta un parámetro de campo de consulta denominado "params" que es un objeto JSON. @@ -112,9 +94,9 @@ Esta función de middleware acepta un parámetro de campo de consulta denominado app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -125,104 +107,84 @@ app.get('/search', (req, res) => { No obstante, try-catch sólo funciona para el código síncrono. Como la plataforma de Node es principalmente asíncrona (particularmente en un entorno de producción), try-catch no capturará muchas excepciones. - +#### Use promises -#### Utilizar promesas - -Las promesas manejarán todas las excepciones (explícitas e implícitas) en los bloques de códigos asíncronos que utilicen `then()`. Sólo tiene que añadir `.catch(next)` al final de las cadenas de promesas. Por ejemplo: +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -Ahora todos los errores, asíncronos y síncronos, se propagarán al middleware de errores. - -No obstante, hay dos advertencias: - -1. Todo el código asíncrono debe devolver promesas (excepto los emisores). Si una determinada biblioteca no devuelve promesas, convierta el objeto base utilizando una función de ayuda como [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Los emisores de sucesos (como las secuencias) todavía pueden provocar excepciones no capturadas. Por lo tanto, asegúrese de que está manejando el suceso de error correctamente; por ejemplo: +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -La función `wrap()` es un envoltorio que toma las promesas rechazadas y llama a `next()` con el error como primer argumento. Para más detalles, vea [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/). +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. -Para más información acerca del manejo de errores utilizando promesas, vea [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/). +#### Qué no debe hacer + +Algo que _no_ debe hacer es escuchar el suceso `uncaughtException`, que se emite cuando una excepción se reproduce hacia atrás en el bucle de sucesos. La adición de un escucha de sucesos para `uncaughtException` cambiará el comportamiento predeterminado del proceso que se encuentra con la excepción; el proceso continuará ejecutándose a pesar de la excepción. Esto puede parecer una buena forma de evitar el bloqueo de la aplicación, pero continuar ejecutando la aplicación después de una excepción no capturada es una práctica peligrosa y no se recomienda, ya que el estado del proceso se vuelve imprevisible y poco fiable. + +Asimismo, el uso de `uncaughtException` se reconoce oficialmente como un mecanismo [arduo](https://nodejs.org/api/process.html#process_event_uncaughtexception) y hay una [propuesta](https://github.com/nodejs/node-v0.x-archive/issues/2582) para eliminarlo del núcleo. Por lo tanto, la escucha `uncaughtException` no es una buena idea. Es por esto por lo que se recomiendan varios procesos y supervisores; el bloqueo y el reinicio es a menudo la forma más fiable de recuperarse de un error. + +Tampoco se recomienda el uso de [dominios](https://nodejs.org/api/domain.html). Generalmente no soluciona el problema y es un módulo en desuso. ## Cosas que hacer en el entorno / configuración Estas son algunas de las cosas que puede hacer en el entorno del sistema para mejorar el rendimiento de la aplicación: -- [Establecer NODE_ENV en "production"](#establecer-node_env-en-production) -- [Asegurarse de que la aplicación se reinicia automáticamente](#asegurarse-de-que-la-aplicación-se-reinicia-automáticamente) -- [Ejecutar la aplicación en un clúster](#ejecutar-la-aplicación-en-un-clúster) -- [Almacenar en la caché los resultados de la solicitud](#almacenar-en-la-caché-los-resultados-de-la-solicitud) -- [Utilizar un equilibrador de carga](#utilizar-un-equilibrador-de-carga) -- [Utilizar un proxy inverso](#utilizar-un-proxy-inverso) +- [Establecer NODE_ENV en "production"](#establecer-node_env-en-production) +- [Asegurarse de que la aplicación se reinicia automáticamente](#asegurarse-de-que-la-aplicación-se-reinicia-automáticamente) +- [Ejecutar la aplicación en un clúster](#ejecutar-la-aplicación-en-un-clúster) +- [Almacenar en la caché los resultados de la solicitud](#almacenar-en-la-caché-los-resultados-de-la-solicitud) +- [Utilizar un equilibrador de carga](#utilizar-un-equilibrador-de-carga) +- [Utilizar un proxy inverso](#utilizar-un-proxy-inverso) ### Establecer NODE_ENV en "production" -La variable de entorno NODE_ENV especifica el entorno en el que se ejecuta una aplicación (normalmente, desarrollo o producción). Una de las cosas más sencillas que puede hacer para mejorar el rendimiento es establecer NODE_ENV en "production". +La variable de entorno NODE_ENV especifica el entorno en el que se ejecuta una aplicación (normalmente, desarrollo o producción). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. Si establece NODE_ENV en "production", Express: -- Almacena en la caché las plantillas de vistas. -- Almacena en la caché los archivos CSS generados en las extensiones CSS. -- Genera menos mensajes de error detallados. - -Las [pruebas indican](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) que sólo esta acción puede mejorar hasta tres veces el rendimiento de la aplicación. - -Si necesita escribir código específico del entorno, puede comprobar el valor de NODE_ENV con `process.env.NODE_ENV`. Tenga en cuenta que comprobar el valor de una variable de entorno supone una reducción de rendimiento, por lo que debe hacerse moderadamente. - -En el desarrollo, normalmente establece las variables de entorno en el shell interactivo, por ejemplo, utilizando `export` o su archivo `.bash_profile`. Sin embargo, en general, no debe hacerlo en un servidor de producción; en su lugar, utilice el sistema init de su sistema operativo (systemd o Upstart). En la siguiente sección se proporcionan más detalles sobre el uso del sistema init en general, pero el establecimiento de NODE_ENV es tan importante (y fácil de hacer) para el rendimiento, que se resalta aquí. +- Almacena en la caché las plantillas de vistas. +- Almacena en la caché los archivos CSS generados en las extensiones CSS. +- Genera menos mensajes de error detallados. -Con Upstart, utilice la palabra clave `env` en el archivo de trabajo. Por ejemplo: +[Tests indicate](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! -
    -
    -# /etc/init/env.conf
    - env NODE_ENV=production
    -
    -
    +If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Tenga en cuenta que comprobar el valor de una variable de entorno supone una reducción de rendimiento, por lo que debe hacerse moderadamente. -Para obtener más información, consulte [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). +En el desarrollo, normalmente establece las variables de entorno en el shell interactivo, por ejemplo, utilizando `export` o su archivo `.bash_profile`. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). En la siguiente sección se proporcionan más detalles sobre el uso del sistema init en general, pero el establecimiento de NODE_ENV es tan importante (y fácil de hacer) para el rendimiento, que se resalta aquí. -Con systemd, utilice la directiva `Environment` en el archivo unit. Por ejemplo: +Con systemd, utilice la directiva `Environment` en el archivo unit. For example: -
    -
    +```sh
     # /etc/systemd/system/myservice.service
     Environment=NODE_ENV=production
    -
    -
    - -Para obtener más información, consulte [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). +``` -Si está utilizando StrongLoop Process Manager, también puede [establecer la variable de entorno cuando instala StrongLoop PM como un servicio](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### Asegurarse de que la aplicación se reinicia automáticamente En la producción, no desea que la aplicación esté nunca fuera de línea. Esto significa que debe asegurarse de que se reinicia si la aplicación o el servidor se bloquean. Aunque espera que no se produzca ninguno de estos sucesos, si somos realistas, debe tener en cuenta ambas eventualidades de la siguiente manera: -- Utilizando un gestor de procesos para reiniciar la aplicación (y Node) cuando se bloquea. -- Utilizando el sistema init que proporciona su sistema operativo para reiniciar el gestor de procesos cuando se bloquea el sistema operativo. También puede utilizar el sistema init sin un gestor de procesos. +- Utilizando un gestor de procesos para reiniciar la aplicación (y Node) cuando se bloquea. +- Utilizando el sistema init que proporciona su sistema operativo para reiniciar el gestor de procesos cuando se bloquea el sistema operativo. También puede utilizar el sistema init sin un gestor de procesos. Las aplicaciones Node se bloquean si encuentran una excepción no capturada. Lo primero que debe hacer es asegurarse de que se realizan las pruebas correctas en la aplicación y que se manejan todas las excepciones (consulte [Manejar correctamente las excepciones](#exceptions) para obtener detalles). No obstante, para estar libre de errores, aplique un mecanismo para garantizar que cuando se bloquee la aplicación, se reinicie automáticamente. @@ -232,55 +194,35 @@ En el desarrollo, la aplicación se inicia simplemente desde la línea de mandat Además de reiniciar la aplicación cuando se bloquea, un gestor de procesos permite: -- Obtener información útil sobre el rendimiento en tiempo de ejecución y el consumo de recursos. -- Modificar dinámicamente los valores para mejorar el rendimiento. -- Controlar la agrupación en clúster (StrongLoop PM y pm2). - -Los gestores de procesos más conocidos para Node son los siguientes: - -- [StrongLoop Process Manager](http://strong-pm.io/) -- [PM2](https://github.com/Unitech/pm2) -- [Forever](https://www.npmjs.com/package/forever) - -Para ver una comparación característica a característica de los tres gestores de procesos, consulte [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Para ver una introducción más detallada de los tres, consulte [Gestores de procesos para las aplicaciones Express](/{{ page.lang }}/advanced/pm.html). +- Obtener información útil sobre el rendimiento en tiempo de ejecución y el consumo de recursos. +- Modificar dinámicamente los valores para mejorar el rendimiento. +- Control clustering (pm2). -El uso de cualquiera de estos gestores de procesos bastará para mantener activa la aplicación, aunque se bloquee cada cierto tiempo. - -No obstante, StrongLoop PM tiene muchas características especialmente indicadas para el despliegue de producción. Puede utilizarlo y las herramientas relacionadas de StrongLoop para: - -- Crear y empaquetar la aplicación localmente y, a continuación, desplegarla de forma segura en el sistema de producción. -- Reiniciar automáticamente la aplicación si se bloque por cualquier motivo. -- Gestionar los clústeres de forma remota. -- Ver perfiles de CPU e instantáneas de almacenamiento dinámico para optimizar el rendimiento y diagnosticar fugas de memoria. -- Ver medidas de rendimiento para la aplicación. -- Escalar fácilmente a varios hosts con control integrado para el equilibrador de carga Nginx. - -Como se explica a continuación, cuando instala StrongLoop PM como un servicio de sistema operativo utilizando el sistema init, se reinicia automáticamente cuando se reinicia el sistema. De esta forma, mantiene activos siempre los clústeres y los procesos de aplicaciones. +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. #### Utilizar un sistema init -La siguiente capa de fiabilidad es garantizar que la aplicación se reinicie cuando se reinicie el servidor. Los sistemas pueden bloquearse por una amplia variedad de motivos. Para garantizar que la aplicación se reinicie si se bloquea el servidor, utilice el sistema init incorporado en su sistema operativo. Los dos principales sistemas init que se utilizan hoy día son [systemd](https://wiki.debian.org/systemd) y [Upstart](http://upstart.ubuntu.com/). +La siguiente capa de fiabilidad es garantizar que la aplicación se reinicie cuando se reinicie el servidor. Los sistemas pueden bloquearse por una amplia variedad de motivos. Para garantizar que la aplicación se reinicie si se bloquea el servidor, utilice el sistema init incorporado en su sistema operativo. The main init system in use today is [systemd](https://wiki.debian.org/systemd). Hay dos formas de utilizar los sistemas init con la aplicación Express: -- Ejecutar la aplicación en un gestor de procesos e instalar el gestor de procesos como un servicio con el sistema init. El gestor de procesos reiniciará la aplicación cuando esta se bloquee y el sistema init reiniciará el gestor de procesos cuando se reinicie el sistema operativo. Este es el enfoque recomendado. -- Ejecutar la aplicación (y Node) directamente con el sistema init. Esta opción parece más simple, pero no tiene las ventajas adicionales de utilizar el gestor de procesos. +- Ejecutar la aplicación en un gestor de procesos e instalar el gestor de procesos como un servicio con el sistema init. El gestor de procesos reiniciará la aplicación cuando esta se bloquee y el sistema init reiniciará el gestor de procesos cuando se reinicie el sistema operativo. This is the recommended approach. +- Ejecutar la aplicación (y Node) directamente con el sistema init. Esta opción parece más simple, pero no tiene las ventajas adicionales de utilizar el gestor de procesos. ##### Systemd Systemd es un administrador de servicios y sistemas Linux. La mayoría de las principales distribuciones Linux han adoptado systemd como su sistema init predeterminado. -Un archivo de configuración de servicio de systemd se denomina un _archivo unit_, con un nombre de archivo terminado en .service. A continuación, se muestra un archivo unit de ejemplo para gestionar directamente una aplicación Node (sustituya el texto en negrita por los valores de su sistema y su aplicación): +Un archivo de configuración de servicio de systemd se denomina un _archivo unit_, con un nombre de archivo terminado en .service. A continuación, se muestra un archivo unit de ejemplo para gestionar directamente una aplicación Node (sustituya el texto en negrita por los valores de su sistema y su aplicación): Replace the values enclosed in `` for your system and app: -
    -
    +```sh
     [Unit]
    -Description=Awesome Express App
    +Description=
     
     [Service]
     Type=simple
    -ExecStart=/usr/local/bin/node /projects/myapp/index.js
    -WorkingDirectory=/projects/myapp
    +ExecStart=/usr/local/bin/node 
    +WorkingDirectory=
     
     User=nobody
     Group=nogroup
    @@ -301,112 +243,15 @@ Restart=always
     
     [Install]
     WantedBy=multi-user.target
    -
    -
    +``` Para obtener más información sobre systemd, consulte [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). -##### StrongLoop PM como un servicio systemd - -Puede instalar fácilmente StrongLoop Process Manager como un servicio systemd. A continuación, cuando se reinicie el servidor, se reiniciará automáticamente StrongLoop PM, que a su vez reiniciará todas las aplicaciones que esté gestionando. - -Para instalar StrongLoop PM como un servicio systemd: - -
    -
    -$ sudo sl-pm-install --systemd
    -
    -
    - -A continuación, inicie el servicio con: - -
    -
    -$ sudo /usr/bin/systemctl start strong-pm
    -
    -
    - -Para obtener más información, consulte [Setting up a production host (documentación de StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart es una herramienta del sistema disponible en muchas distribuciones Linux para iniciar tareas y servicios durante el arranque del sistema, detenerlos durante la conclusión y supervisarlos. Puede configurar la aplicación Express o el gestor de procesos como un servicio y, a continuación, Upstart lo reiniciará automáticamente cuando se bloquee. - -Un servicio de Upstart se define en un archivo de configuración de trabajo (también denominado un "trabajo") con un nombre de archivo terminado en `.conf`. El siguiente ejemplo muestra cómo crear un trabajo denominado "myapp" para una aplicación denominada "myapp" con el archivo principal ubicado en `/projects/myapp/index.js`. - -Cree un archivo denominado `myapp.conf` en `/etc/init/` con el siguiente contenido (sustituya el texto en negrita por los valores de su sistema y su aplicación): - -
    -
    -# When to start the process
    -start on runlevel [2345]
    -
    -# When to stop the process
    -stop on runlevel [016]
    -
    -# Increase file descriptor limit to be able to handle more requests
    -limit nofile 50000 50000
    -
    -# Use production mode
    -env NODE_ENV=production
    -
    -# Run as www-data
    -setuid www-data
    -setgid www-data
    -
    -# Run from inside the app dir
    -chdir /projects/myapp
    -
    -# The process to start
    -exec /usr/local/bin/node /projects/myapp/index.js
    -
    -# Restart the process if it is down
    -respawn
    -
    -# Limit restart attempt to 10 times within 10 seconds
    -respawn limit 10 10
    -
    -
    - -NOTA: este script requiere Upstart 1.4 o posterior, soportado en Ubuntu 12.04-14.10. - -Como el trabajo se configura para ejecutarse cuando se inicia el sistema, la aplicación se iniciará junto con el sistema operativo, y se reiniciará automáticamente si la aplicación se bloquea o el sistema se cuelga. - -Aparte reiniciar automáticamente la aplicación, Upstart permite utilizar estos mandatos: - -- `start myapp` – Iniciar la aplicación -- `restart myapp` – Reiniciar la aplicación -- `stop myapp` – Detener la aplicación - -Para obtener más información sobre Upstart, consulte [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM como un servicio Upstart - -Puede instalar fácilmente StrongLoop Process Manager como un servicio Upstart. A continuación, cuando se reinicie el servidor, se reiniciará automáticamente StrongLoop PM, que a su vez reiniciará todas las aplicaciones que esté gestionando. - -Para instalar StrongLoop PM como un servicio Upstart 1.4: - -
    -
    -$ sudo sl-pm-install
    -
    -
    - -A continuación, ejecute el servicio con: - -
    -
    -$ sudo /sbin/initctl start strong-pm
    -
    -
    - -NOTA: en los sistemas que no dan soporte a Upstart 1.4, los mandatos son ligeramente diferentes. Consulte [Setting up a production host (documentación de StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) para obtener más información. - ### Ejecutar la aplicación en un clúster En un sistema multinúcleo, puede multiplicar el rendimiento de una aplicación Node iniciando un clúster de procesos. Un clúster ejecuta varias instancias de la aplicación, idealmente una instancia en cada núcleo de CPU, lo que permite distribuir la carga y las tareas entre las instancias. - +![Balancing between application instances using the cluster API](/images/clustering.png) IMPORTANTE: como las instancias de aplicación se ejecutan como procesos independientes, no comparten el mismo espacio de memoria. Es decir, los objetos son locales para cada instancia de la aplicación. Por lo tanto, no puede mantener el estado en el código de aplicación. No obstante, puede utilizar un almacén de datos en memoria como [Redis](http://redis.io/) para almacenar los datos y los estados relacionados con la sesión. Esta advertencia se aplica básicamente a todas las formas de escalado horizontal, ya sean clústeres con varios procesos o varios servidores físicos. @@ -414,45 +259,52 @@ En las aplicaciones en clúster, los procesos de trabajador pueden bloquearse in #### Mediante el módulo de clúster de Node -La agrupación en clústeres es posible gracias al [módulo de clúster](https://nodejs.org/docs/latest/api/cluster.html) de Node. Esto permite al proceso maestro generar procesos de trabajador y distribuir las conexiones entrantes entre los trabajadores. No obstante, en lugar de utilizar este módulo directamente, es mucho mejor utilizar una de las muchas herramientas que lo hacen automáticamente, por ejemplo, [node-pm](https://www.npmjs.com/package/node-pm) o [cluster-service](https://www.npmjs.com/package/cluster-service). +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). Esto permite al proceso maestro generar procesos de trabajador y distribuir las conexiones entrantes entre los trabajadores. -#### Mediante StrongLoop PM +#### Using PM2 -Si despliega la aplicación en StrongLoop Process Manager (PM), puede aprovechar la agrupación en clúster _sin_ modificar el código de aplicación. +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). -Cuando StrongLoop Process Manager (PM) ejecuta una aplicación, la ejecuta automáticamente en un clúster con un número de trabajadores igual al número de núcleos de CPU en el sistema. Puede cambiar manualmente el número de procesos de trabajador en el clúster utilizando la herramienta de línea de mandatos slc sin detener la aplicación. +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. -Por ejemplo, suponiendo que ha desplegado la aplicación en prod.foo.com y que StrongLoop PM escucha en el puerto 8701 (el valor predeterminado), para establecer el tamaño de clúster en ocho utilizando slc: +To enable cluster mode, start your application like so: -
    -
    -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
    -
    -
    +```bash +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ pm2 start npm --name my-app -i max -- start +``` -Para obtener más información sobre la agrupación en clúster con StrongLoop PM, consulte [Clustering](https://docs.strongloop.com/display/SLC/Clustering) en la documentación de StrongLoop. +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 +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ 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. ### Almacenar en la caché los resultados de la solicitud Otra estrategia para mejorar el rendimiento en la producción es almacenar en la caché el resultado de las solicitudes, para que la aplicación no repita la operación de dar servicio a la misma solicitud repetidamente. -Utilice un servidor de almacenamiento en memoria caché como [Varnish](https://www.varnish-cache.org/) o [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (consulte también [Nginx Caching](https://serversforhackers.com/nginx-caching/)) para mejorar significativamente la velocidad y el rendimiento de la aplicación. +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### Utilizar un equilibrador de carga Independientemente de lo optimizada que esté una aplicación, una única instancia sólo puede manejar una cantidad limitada de carga y tráfico. Una forma de escalar una aplicación es ejecutar varias instancias de la misma y distribuir el tráfico utilizando un equilibrador de carga. La configuración de un equilibrador de carga puede mejorar el rendimiento y la velocidad de la aplicación, lo que permite escalarla más que con una única instancia. -Un equilibrador de carga normalmente es un proxy inverso que orquesta el tráfico hacia y desde los servidores y las instancias de aplicación. Puede configurar fácilmente un equilibrador de carga para la aplicación utilizando [Nginx](http://nginx.org/en/docs/http/load_balancing.html) o [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). - -Con el equilibrio de carga, deberá asegurarse de que las solicitudes asociadas con un determinado ID de sesión se conecten al proceso que las ha originado. Esto se conoce como _afinidad de sesiones_ o _sesiones adhesivas_, y puede solucionarse con la recomendación anterior de utilizar un almacén de datos como, por ejemplo, Redis para los datos de sesión (dependiendo de la aplicación). Para obtener más información, consulte [Using multiple nodes](http://socket.io/docs/using-multiple-nodes/). - -#### Mediante StrongLoop PM con un equilibrador de carga Nginx +Un equilibrador de carga normalmente es un proxy inverso que orquesta el tráfico hacia y desde los servidores y las instancias de aplicación. 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). -[StrongLoop Process Manager](http://strong-pm.io/) se integra con un Nginx Controller, lo que simplifica las configuraciones de entornos de producción de varios hosts. Para obtener más información, consulte [Scaling to multiple servers](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (documentación de StrongLoop). - +Con el equilibrio de carga, deberá asegurarse de que las solicitudes asociadas con un determinado ID de sesión se conecten al proceso que las ha originado. Esto se conoce como _afinidad de sesiones_ o _sesiones adhesivas_, y puede solucionarse con la recomendación anterior de utilizar un almacén de datos como, por ejemplo, Redis para los datos de sesión (dependiendo de la aplicación). Para obtener más información, consulte [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). ### Utilizar un proxy inverso Un proxy inverso se coloca delante de una aplicación web y realiza operaciones de soporte en las solicitudes, aparte de dirigir las solicitudes a la aplicación. Puede manejar las páginas de errores, la compresión, el almacenamiento en memoria caché, el servicio de archivos y el equilibrio de carga, entre otros. -La entrega de tareas que no necesitan saber el estado de la aplicación a un proxy inverso permite a Express realizar tareas de aplicación especializadas. Por este motivo, se recomienda ejecutar Express detrás de un proxy inverso como [Nginx](https://www.nginx.com/) o [HAProxy](http://www.haproxy.org/) en la producción. +La entrega de tareas que no necesitan saber el estado de la aplicación a un proxy inverso permite a Express realizar tareas de aplicación especializadas. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/es/advanced/best-practice-security.md b/es/advanced/best-practice-security.md old mode 100755 new mode 100644 index 2ed644440e..7aaf8bb415 --- a/es/advanced/best-practice-security.md +++ b/es/advanced/best-practice-security.md @@ -1,35 +1,49 @@ --- layout: page title: Mejores prácticas de seguridad para Express en producción +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: es +redirect_from: " " --- -# Mejores prácticas de producción: seguridad +# Production Best Practices: Security -## Visión general +## Overview -El término *"producción"* hace referencia a la etapa del ciclo de vida del software donde una aplicación o una API tiene disponibilidad general para sus consumidores o usuarios finales. Por su parte, en la etapa de *"desarrollo"*, todavía estás escribiendo y probando activamente el código, y la aplicación no está abierta para el acceso externo. Los correspondientes entornos del sistema se conocen como los entornos de *producción* y *desarrollo*, respectivamente. +El término _"producción"_ hace referencia a la etapa del ciclo de vida del software donde una aplicación o una API tiene disponibilidad general para sus consumidores o usuarios finales. Por su parte, en la etapa de _"desarrollo"_, todavía estás escribiendo y probando activamente el código, y la aplicación no está abierta para el acceso externo. Los correspondientes entornos del sistema se conocen como los entornos de _producción_ y _desarrollo_, respectivamente. Los entornos de desarrollo y producción se configuran normalmente de forma diferente y tiene requisitos también muy diferentes. Lo que funciona en el desarrollo puede que no sea aceptable en la producción. Por ejemplo, en un entorno de desarrollo, puede que desee el registro detallado de errores a efecto de depuración, mientras que el mismo comportamiento puede suponer un problema de seguridad en un entorno de producción. De la misma forma, en el desarrollo, no es necesario preocuparse por la escalabilidad, la fiabilidad y el rendimiento, mientras que estos son clave en la producción. -{% include note.html content="Si crees haber encontrado una vulnerabilidad de seguridad en Express, por favor mira nuestras [Políticas de Seguridad y Procedimientos](/en/resources/contributing.html#security-policies-and-procedures). -" %} +{% capture security-note %} -Las mejores prácticas de seguridad para aplicaciones Express en producción incluyen: +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). -- [No utilizar versiones en desuso o vulnerables de Express](#no-utilizar-versiones-en-desuso-o-vulnerables-de-express) -- [Utilizar TLS](#utilizar-tls) -- [Utilizar Helmet](#utilizar-helmet) -- [Utilizar cookies de forma segura](#utilizar-cookies-de-forma-segura) -- [Prevenir ataques de fuerza bruta a la autenticación](#prevenir-ataques-de-fuerza-bruta-a-la-autenticación) -- [Asegurarse de que las dependencias sean seguras](#asegurarse-de-que-las-dependencias-sean-seguras) -- [Evitar otras vulnerabilidades conocidas](#evitar-otras-vulnerabilidades-conocidas) -- [Consideraciones adicionales](#consideraciones-adicionales) +{% endcapture %} + +{% include admonitions/note.html content=security-note %} + +Security best practices for Express applications in production include: + +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [Utilizar TLS](#utilizar-tls) + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - [Utilizar Helmet](#utilizar-helmet) + - [Reduce fingerprinting](#reduce-fingerprinting) + - [Utilizar cookies de forma segura](#utilizar-cookies-de-forma-segura) + - [noCache](https://github.com/helmetjs/nocache) establece cabeceras `Cache-Control` y Pragma para inhabilitar el almacenamiento en memoria caché del lado de cliente. + - [ieNoOpen](https://github.com/helmetjs/ienoopen) establece `X-Download-Options` para IE8+. + - [Prevenir ataques de fuerza bruta a la autenticación](#prevenir-ataques-de-fuerza-bruta-a-la-autenticación) + - [Asegurarse de que las dependencias sean seguras](#asegurarse-de-que-las-dependencias-sean-seguras) + - [Evitar otras vulnerabilidades conocidas](#evitar-otras-vulnerabilidades-conocidas) + - [Consideraciones adicionales](#consideraciones-adicionales) ## No utilizar versiones en desuso o vulnerables de Express -Express 2.x y 3.x ya no se mantienen. Los problemas de seguridad y rendimiento en estas versiones no se solucionarán. No las utilice. Si no ha cambiado todavía a la versión 4, siga la [guía de migración](/{{ page.lang }}/guide/migrating-4.html). +Express 2.x y 3.x ya no se mantienen. Los problemas de seguridad y rendimiento en estas versiones no se solucionarán. No las utilice. Si no ha cambiado todavía a la versión 4, siga la [guía de migración](/{{ page.lang }}/guide/migrating-4.html). Asimismo, asegúrese de que no está utilizando ninguna de las versiones vulnerables de Express que se listan en la [página Actualizaciones de seguridad](/{{ page.lang }}/advanced/security-updates.html). Si las utiliza, actualícese a uno de los releases estables, preferiblemente el más reciente. @@ -37,121 +51,180 @@ Asimismo, asegúrese de que no está utilizando ninguna de las versiones vulnera Si la aplicación maneja o transmite datos confidenciales, utilice [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) para proteger la conexión y los datos. Esta tecnología cifra los datos antes de enviarlos desde el cliente al servidor, lo que evita algunos de los ataques de pirateo más comunes (y sencillos). Aunque las solicitudes Ajax y POST no sean obvias visiblemente y parezca que están "ocultas" en los navegadores, su tráfico de red es vulnerable para los [rastreos de paquetes](https://en.wikipedia.org/wiki/Packet_analyzer) y los [ataques de intermediarios](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -Es posible que esté familiarizado con el cifrado SSL (Secure Socket Layer). [TLS es simplemente el siguiente paso después de SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). Es decir, si antes utilizaba SSL, se recomienda actualizar a TLS. En general, se recomienda Nginx para manejar TLS. Encontrará una buena referencia para configurar TLS en Nginx (y otros servidores) en [la wiki de Mozilla Recommended Server Configurations](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). +Es posible que esté familiarizado con el cifrado SSL (Secure Socket Layer). [TLS es simplemente el siguiente paso después de SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx). Es decir, si antes utilizaba SSL, se recomienda actualizar a TLS. En general, se recomienda Nginx para manejar TLS. Encontrará una buena referencia para configurar TLS en Nginx (y otros servidores) en [la wiki de Mozilla Recommended Server Configurations](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). Asimismo, una herramienta muy útil para obtener un certificado de TLS gratis es [Let's Encrypt](https://letsencrypt.org/about/), una entidad emisora de certificados (CA) abierta, automatizada y gratuita proporcionada por [Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/). +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## Utilizar Helmet [Helmet](https://www.npmjs.com/package/helmet) ayuda a proteger la aplicación de algunas vulnerabilidades web conocidas mediante el establecimiento correcto de cabeceras HTTP. -Helmet es realmente una colección de nueve funciones de middleware más paquetes que establecen cabeceras HTTP relacionadas con la seguridad: +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* [csp](https://github.com/helmetjs/csp) establece la cabecera `Content-Security-Policy` para evitar ataques de scripts entre sitios y otras inyecciones entre sitios. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) elimina la cabecera `X-Powered-By`. -* [hsts](https://github.com/helmetjs/hsts) establece la cabecera `Strict-Transport-Security` que fuerza conexiones seguras (HTTP sobre SSL/TLS) con el servidor. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) establece `X-Download-Options` para IE8+. -* [noCache](https://github.com/helmetjs/nocache) establece cabeceras `Cache-Control` y Pragma para inhabilitar el almacenamiento en memoria caché del lado de cliente. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) establece `X-Content-Type-Options` para evitar que los navegadores rastreen mediante MIME una respuesta del tipo de contenido declarado. -* [frameguard](https://github.com/helmetjs/frameguard) establece la cabecera `X-Frame-Options` para proporcionar protección contra el [clickjacking](https://www.owasp.org/index.php/Clickjacking). -* [xssFilter](https://github.com/helmetjs/x-xss-protection) establece `X-XSS-Protection` para habilitar el filtro de scripts entre sitios (XSS) en los navegadores web más recientes. +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. Instale Helmet como cualquier otro módulo: -
    -
    -$ npm install --save helmet
    -
    -
    +```bash +$ npm install helmet +``` A continuación, utilícelo en el código: -
    -
    -...
    -var helmet = require('helmet');
    -app.use(helmet());
    -...
    -
    -
    +```js +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... +``` -### Como mínimo, inhabilitar la cabecera X-Powered-By +## Reduce fingerprinting -Si no desea utilizar Helmet, como mínimo, inhabilite la cabecera `X-Powered-By`. Los atacantes pueden utilizar esta cabecera (que está habilitada de forma predeterminada) para detectar las aplicaciones que ejecutan Express e iniciar ataques con destinos específicos. +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. Por lo tanto, se recomienda desactivar la cabecera con el método `app.disable()`: -
    -
    -app.disable('x-powered-by');
    -
    -
    +```js +app.disable('x-powered-by') +``` + +{% capture powered-advisory %} + +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. -Si utiliza `helmet.js`, lo hace automáticamente. +{% endcapture %} -## Utilizar cookies de forma segura +{% include admonitions/note.html content=powered-advisory %} + +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): + +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` + +## Establecer las opciones de seguridad de las cookies Para garantizar que las cookies no abran la aplicación para ataques, no utilice el nombre de cookie de sesión predeterminado y establezca las opciones de seguridad de las cookies correctamente. Hay dos módulos de sesión de cookies de middleware principales: -* [express-session](https://www.npmjs.com/package/express-session), que sustituye el middleware `express.session` incorporado en Express 3.x. -* [cookie-session](https://www.npmjs.com/package/cookie-session), que sustituye el middleware `express.cookieSession` incorporado en Express 3.x. +- [express-session](https://www.npmjs.com/package/express-session), que sustituye el middleware `express.session` incorporado en Express 3.x. +- [cookie-session](https://www.npmjs.com/package/cookie-session), que sustituye el middleware `express.cookieSession` incorporado en Express 3.x. -La principal diferencia entre los dos módulos es cómo guardan los datos de sesión de las cookies. El middleware [express-session](https://www.npmjs.com/package/express-session) almacena los datos de sesión en el servidor; sólo guarda el ID de sesión en la propia cookie, no los datos de sesión. De forma predeterminada, utiliza el almacenamiento en memoria y no está diseñado para un entorno de producción. En la producción, deberá configurar un almacenamiento de sesión escalable; consulte la lista de [almacenes de sesión compatibles](https://github.com/expressjs/session#compatible-session-stores). +La principal diferencia entre los dos módulos es cómo guardan los datos de sesión de las cookies. El middleware [express-session](https://www.npmjs.com/package/express-session) almacena los datos de sesión en el servidor; sólo guarda el ID de sesión en la propia cookie, no los datos de sesión. De forma predeterminada, utiliza el almacenamiento en memoria y no está diseñado para un entorno de producción. En la producción, deberá configurar un almacenamiento de sesión escalable; consulte la lista de [almacenes de sesión compatibles](https://github.com/expressjs/session#compatible-session-stores). -Por su parte, el middleware [cookie-session](https://www.npmjs.com/package/cookie-session) implementa un almacenamiento basado en cookies: serializa la sesión completa en la cookie, en lugar de sólo una clave de sesión. Utilícelo sólo cuando los datos de sesión sean relativamente pequeños y fácilmente codificables como valores primitivos (en lugar de objetos). Aunque se supone que los navegadores pueden dar soporte a 4096 bytes por cookie como mínimo, para no exceder el límite, no supere un tamaño de 4093 bytes por dominio. Asimismo, asegúrese de que los datos de la cookie estén visibles para el cliente, para que si se deben proteger u ocultar por cualquier motivo, se utilice mejor la opción express-session. +Por su parte, el middleware [cookie-session](https://www.npmjs.com/package/cookie-session) implementa un almacenamiento basado en cookies: serializa la sesión completa en la cookie, en lugar de sólo una clave de sesión. Utilícelo sólo cuando los datos de sesión sean relativamente pequeños y fácilmente codificables como valores primitivos (en lugar de objetos). Aunque se supone que los navegadores pueden dar soporte a 4096 bytes por cookie como mínimo, para no exceder el límite, no supere un tamaño de 4093 bytes por dominio. Asimismo, asegúrese de que los datos de la cookie estén visibles para el cliente, para que si se deben proteger u ocultar por cualquier motivo, se utilice mejor la opción express-session. ### No utilizar el nombre de cookie de sesión predeterminado -Si utiliza el nombre de cookie de sesión predeterminado, la aplicación puede quedar abierta a los ataques. El problema de seguridad que supone es similar a `X-Powered-By`: un posible atacante puede utilizarlo para firmar digitalmente el servidor y dirigir los ataques en consecuencia. +Si utiliza el nombre de cookie de sesión predeterminado, la aplicación puede quedar abierta a los ataques. El problema de seguridad que supone es similar a `X-Powered-By`: un posible atacante puede utilizarlo para firmar digitalmente el servidor y dirigir los ataques en consecuencia. Para evitar este problema, utilice nombres de cookie genéricos, por ejemplo, con el middleware [express-session](https://www.npmjs.com/package/express-session): -
    -
    -var session = require('express-session');
    +```js
    +const session = require('express-session')
     app.set('trust proxy', 1) // trust first proxy
    -app.use( session({
    -   secret : 's3Cur3',
    -   name : 'sessionId',
    -  })
    -);
    -
    -
    +app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) +``` -### Establecer las opciones de seguridad de las cookies +### Utilizar cookies de forma segura Establezca las siguientes opciones de cookies para mejorar la seguridad: -* `secure` - Garantiza que el navegador sólo envíe la cookie a través de HTTPS. -* `httpOnly` - Garantiza que la cookie sólo se envíe a través de HTTP(S), no a través de JavaScript de cliente, para la protección contra ataques de scripts entre sitios. -* `domain` - Indica el dominio de la cookie; utilícelo para compararlo con el dominio del servidor donde se está solicitando el URL. Si coinciden, compruebe el atributo de vía de acceso a continuación. -* `path` - Indica la vía de acceso de la cookie; utilícela para compararla con la vía de acceso de la solicitud. Si esta y el dominio coinciden, envíe la cookie en la solicitud. -* `expires` - Se utiliza para establecer la fecha de caducidad de las cookies persistentes. +- `secure` - Garantiza que el navegador sólo envíe la cookie a través de HTTPS. +- `httpOnly` - Garantiza que la cookie sólo se envíe a través de HTTP(S), no a través de JavaScript de cliente, para la protección contra ataques de scripts entre sitios. +- `domain` - Indica el dominio de la cookie; utilícelo para compararlo con el dominio del servidor donde se está solicitando el URL. Si coinciden, compruebe el atributo de vía de acceso a continuación. +- `path` - Indica la vía de acceso de la cookie; utilícela para compararla con la vía de acceso de la solicitud. Si esta y el dominio coinciden, envíe la cookie en la solicitud. +- `expires` - Se utiliza para establecer la fecha de caducidad de las cookies persistentes. A continuación, se muestra un ejemplo de uso del middleware [cookie-session](https://www.npmjs.com/package/cookie-session): -
    -
    -var session = require('cookie-session');
    -var express = require('express');
    -var app = express();
    +```js
    +const session = require('cookie-session')
    +const express = require('express')
    +const app = express()
     
    -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
    +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
     app.use(session({
       name: 'session',
       keys: ['key1', 'key2'],
    -  cookie: { secure: true,
    -            httpOnly: true,
    -            domain: 'example.com',
    -            path: 'foo/bar',
    -            expires: expiryDate
    -          }
    -  })
    -);
    -
    -
    + cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) +``` ## Prevenir ataques de fuerza bruta a la autenticación @@ -166,11 +239,11 @@ El paquete [rate-limiter-flexible](https://github.com/animir/node-rate-limiter-f ## Asegurarse de que las dependencias sean seguras -El uso de npm para gestionar las dependencias de la aplicación es muy útil y cómodo. No obstante, los paquetes que utiliza pueden contener vulnerabilidades de seguridad críticas que también pueden afectar a la aplicación. La seguridad de la aplicación sólo es tan fuerte como el "enlace más débil" de las dependencias. +El uso de npm para gestionar las dependencias de la aplicación es muy útil y cómodo. No obstante, los paquetes que utiliza pueden contener vulnerabilidades de seguridad críticas que también pueden afectar a la aplicación. La seguridad de la aplicación sólo es tan fuerte como el "enlace más débil" de las dependencias. -Desde npm@6, npm revisa automáticamente cada solicitud de instalación. También puedes utilizar 'npm audit' para analizar tu árbol de dependencias. +Since npm@6, npm automatically reviews every install request. También puedes utilizar 'npm audit' para analizar tu árbol de dependencias. -```sh +```bash $ npm audit ``` @@ -178,37 +251,31 @@ Si quieres mantener más seguro, considera [Snyk](https://snyk.io/). Snyk ofrece tanto [herramienta de línea de comandos](https://www.npmjs.com/package/snyk) como una [integración de Github](https://snyk.io/docs/github) que comprueba tu aplicación contra [la base de datos de código abierto sobre vulnerabilidades de Snyk](https://snyk.io/vuln/) por cualquier vulnerabilidad conocida en tus dependencias. Instala la interfaz de línea de comandos: -```sh +```bash $ npm install -g snyk $ cd your-app ``` Usa este comando para comprobar tu aplicación contra vulnerabilidades: -```sh +```bash $ snyk test ``` -Usa este comando para abrir un asistente que te guiará mediante el proceso de aplicar actualizaciones o parches para arreglar las vulnerabilidades que hayan sido encontradas: - -```sh -$ snyk wizard -``` +### Avoid other known vulnerabilities -## Evitar otras vulnerabilidades conocidas +Esté atento a las advertencias de [Node Security Project](https://npmjs.com/advisories) que puedan afectar a Express u otros módulos que utilice la aplicación. En general, Node Security Project es un excelente recurso de herramientas e información sobre la seguridad de Node. -Esté atento a las advertencias de [Node Security Project](https://npmjs.com/advisories) que puedan afectar a Express u otros módulos que utilice la aplicación. En general, Node Security Project es un excelente recurso de herramientas e información sobre la seguridad de Node. +Por último, las aplicaciones de Express, como cualquier otra aplicación web, son vulnerables a una amplia variedad de ataques basados en web. Familiarícese con las [vulnerabilidades web](https://www.owasp.org/www-project-top-ten/) conocidas y tome precauciones para evitarlas. -Por último, las aplicaciones de Express, como cualquier otra aplicación web, son vulnerables a una amplia variedad de ataques basados en web. Familiarícese con las [vulnerabilidades web](https://www.owasp.org/index.php/Top_10_2013-Top_10) conocidas y tome precauciones para evitarlas. +## Additional considerations -## Consideraciones adicionales +A continuación, se muestran algunas recomendaciones para la excelente lista de comprobación [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Consulte el post de este blog para ver todos los detalles de estas recomendaciones: -A continuación, se muestran algunas recomendaciones para la excelente lista de comprobación [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Consulte el post de este blog para ver todos los detalles de estas recomendaciones: +- Filtre y sanee siempre la entrada de usuario para protegerse contra los ataques de scripts entre sitios (XSS) e inyección de mandatos. +- Defiéndase contra los ataques de inyección de SQL utilizando consultas parametrizadas o sentencias preparadas. +- Utilice la herramienta [sqlmap](http://sqlmap.org/) de código abierto para detectar vulnerabilidades de inyección de SQL en la aplicación. +- Utilice las herramientas [nmap](https://nmap.org/) y [sslyze](https://github.com/nabla-c0d3/sslyze) para probar la configuración de los cifrados SSL, las claves y la renegociación, así como la validez del certificado. +- Utilice [safe-regex](https://www.npmjs.com/package/safe-regex) para asegurarse de que las expresiones regulares no sean susceptibles de ataques de [denegación de servicio de expresiones regulares](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). -* Implemente el límite de velocidad para evitar ataques de fuerza bruta contra la autenticación. Una forma de hacerlo es utilizar [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) para forzar una política de limitación de velocidad. También puede utilizar middleware como [express-limiter](https://www.npmjs.com/package/express-limiter), aunque para ello deberá modificar el código de alguna forma. -* Utilice el middleware [csurf](https://www.npmjs.com/package/csurf) para protegerse contra la falsificación de solicitudes entre sitios (CSRF). -* Filtre y sanee siempre la entrada de usuario para protegerse contra los ataques de scripts entre sitios (XSS) e inyección de mandatos. -* Defiéndase contra los ataques de inyección de SQL utilizando consultas parametrizadas o sentencias preparadas. -* Utilice la herramienta [sqlmap](http://sqlmap.org/) de código abierto para detectar vulnerabilidades de inyección de SQL en la aplicación. -* Utilice las herramientas [nmap](https://nmap.org/) y [sslyze](https://github.com/nabla-c0d3/sslyze) para probar la configuración de los cifrados SSL, las claves y la renegociación, así como la validez del certificado. -* Utilice [safe-regex](https://www.npmjs.com/package/safe-regex) para asegurarse de que las expresiones regulares no sean susceptibles de ataques de [denegación de servicio de expresiones regulares](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). +[helmet]: \ No newline at end of file diff --git a/es/advanced/developing-template-engines.md b/es/advanced/developing-template-engines.md old mode 100755 new mode 100644 index 89399b84f1..f10cda9ac9 --- a/es/advanced/developing-template-engines.md +++ b/es/advanced/developing-template-engines.md @@ -1,8 +1,9 @@ --- layout: page title: Desarrollo de motores de plantilla para Express +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: es +redirect_from: " " --- # Desarrollo de motores de plantilla para Express @@ -11,38 +12,35 @@ Utilice el método `app.engine(ext, callback)` para crear su propio motor de pla El siguiente código es un ejemplo de implementación de un motor de plantilla muy simple para la representación de archivos `.ntl`. -
    -
    -var fs = require('fs'); // this engine requires the fs module
    -app.engine('ntl', function (filePath, options, callback) { // define the template engine
    -  fs.readFile(filePath, function (err, content) {
    -    if (err) return callback(new Error(err));
    +```js
    +const fs = require('fs') // this engine requires the fs module
    +app.engine('ntl', (filePath, options, callback) => { // define the template engine
    +  fs.readFile(filePath, (err, content) => {
    +    if (err) return callback(err)
         // this is an extremely simple template engine
    -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
    -    .replace('#message#', '

    '+ options.message +'

    '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
    -
    + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

    ${options.message}

    `) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine +``` La aplicación ahora podrá representar archivos `.ntl`. Cree un archivo denominado `index.ntl` en el directorio `views` con el siguiente contenido. -
    -
    +```pug
     #title#
     #message#
    -
    -
    +``` + A continuación, cree la ruta siguiente en la aplicación. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    -Cuando realice una solicitud a la página de inicio, `index.ntl` se representará como HTML. +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` + +Cuando realice una solicitud a la página de inicio, `index.ntl` se representará como HTML. \ No newline at end of file diff --git a/es/advanced/healthcheck-graceful-shutdown.md b/es/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..20069a8903 --- /dev/null +++ b/es/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/es/advanced/pm.md b/es/advanced/pm.md deleted file mode 100755 index 32e1893f63..0000000000 --- a/es/advanced/pm.md +++ /dev/null @@ -1,283 +0,0 @@ ---- -layout: page -title: Gestores de procesos para las aplicaciones Express -menu: advanced -lang: es ---- - -# Gestores de procesos para las aplicaciones Express - -Cuando ejecuta aplicaciones Express en producción, es muy útil utilizar un *gestor de procesos* para realizar las siguientes tareas: - -- Reiniciar la aplicación automáticamente si se bloquea. -- Obtener información útil sobre el rendimiento en tiempo de ejecución y el consumo de recursos. -- Modificar dinámicamente los valores para mejorar el rendimiento. -- Controlar la agrupación en clúster. - -Un gestor de procesos es una especie de servidor de aplicaciones: un "contenedor" de aplicaciones que facilita el despliegue, proporciona una alta disponibilidad y permite gestionar la aplicación en el tiempo de ejecución. - -Los gestores de procesos más conocidos para Express y otras aplicaciones Node.js son los siguientes: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -El uso de estas tres herramientas puede ser muy útil, aunque StrongLoop Process Manager es la única que proporciona una solución completa de despliegue y tiempo de ejecución que gestiona el ciclo de vida completo de la aplicación Node.js, con herramientas para cada paso antes y después de la producción, en una interfaz unificada. - -A continuación, se describe brevemente cada una de estas herramientas. -Para ver una comparación detallada, consulte [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) es un gestor de procesos de producción para las aplicaciones Node.js. StrongLoop PM tiene incorporado un despliegue de equilibrio de carga, supervisión y varios hosts, así como una consola gráfica. -Puede utilizar StrongLoop PM para las siguientes tareas: - -- Crear, empaquetar y desplegar la aplicación Node.js en un sistema local o remoto. -- Ver perfiles de CPU e instantáneas de almacenamiento dinámico para optimizar el rendimiento y diagnosticar fugas de memoria. -- Mantener activos siempre los clústeres y los procesos. -- Ver medidas de rendimiento sobre la aplicación. -- Gestionar fácilmente los despliegues de varios hosts con la integración de Nginx. -- Unificar varios StrongLoop PM en un tiempo de ejecución de microservicios distribuidos que se gestiona desde Arc. - -Puede trabajar con StrongLoop PM utilizando una potente herramienta de interfaz de línea de mandatos denominada `slc` o una herramienta gráfica denominada Arc. Arc es de código abierto, con soporte profesional proporcionado por StrongLoop. - -Para obtener más información, consulte [http://strong-pm.io/](http://strong-pm.io/). - -Documentación completa: - -- [Operating Node apps (documentación de StrongLoop)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Instalación -
    -
    -$ [sudo] npm install -g strongloop
    -
    -
    - -### Uso básico -
    -
    -$ cd my-app
    -$ slc start
    -
    -
    - -Vea el estado del gestor de procesos y todas las aplicaciones desplegadas: - -
    -
    -$ slc ctl
    -Service ID: 1
    -Service Name: my-app
    -Environment variables:
    -  No environment variables defined
    -Instances:
    -    Version  Agent version  Cluster size
    -     4.1.13      1.5.14           4
    -Processes:
    -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
    -    1.1.57692  57692   0
    -    1.1.57693  57693   1     0.0.0.0:3001
    -    1.1.57694  57694   2     0.0.0.0:3001
    -    1.1.57695  57695   3     0.0.0.0:3001
    -    1.1.57696  57696   4     0.0.0.0:3001
    -
    -
    - -Liste todas las aplicaciones (servicios) que se están gestionando: - -
    -
    -$ slc ctl ls
    -Id          Name         Scale
    - 1          my-app       1
    -
    -
    - -Detenga una aplicación: - -
    -
    -$ slc ctl stop my-app
    -
    -
    - -Reinicie una aplicación: - -
    -
    -$ slc ctl restart my-app
    -
    -
    - -También puede realizar un "reinicio suave", que da a los procesos de trabajador un periodo de gracia para cerrar las conexiones existentes y, a continuación, reinicia la aplicación actual: - -
    -
    -$ slc ctl soft-restart my-app
    -
    -
    - -Para eliminar una aplicación de la gestión: - -
    -
    -$ slc ctl remove my-app
    -
    -
    - -## PM2 - -PM2 es un gestor de procesos de producción para las aplicaciones Node.js que tiene un equilibrador de carga incorporado. PM2 permite mantener siempre activas las aplicaciones y volver a cargarlas sin ningún tiempo de inactividad, a la vez que facilita tareas comunes de administrador del sistema. PM2 también permite gestionar el registro de aplicaciones, la supervisión y la agrupación en clúster. - -Para obtener más información, consulte [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Instalación - -
    -
    -$ [sudo] npm install pm2 -g
    -
    -
    - -### Uso básico - -Cuando inicia una aplicación utilizando el mandato `pm2`, debe especificar la vía de acceso de la aplicación. No obstante, cuando detiene, reinicia o suprime una aplicación, sólo puede especificar el nombre o el ID de la aplicación. - -
    -
    -$ pm2 start npm --name my-app -- start
    -[PM2] restartProcessId process id 0
    -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
    -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
    -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
    -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
    -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
    - Use the `pm2 show ` command to get more details about an app.
    -
    -
    - -Cuando inicia una aplicación utilizando el mandato `pm2`, la aplicación se envía inmediatamente al segundo plano. Puede controlar la aplicación en segundo plano desde la línea de mandatos utilizando varios mandatos `pm2`. - -Cuando se inicia una aplicación utilizando el mandato `pm2`, se registra en la lista de procesos de PM2 con un ID. Por lo tanto, puede gestionar las aplicaciones con el mismo nombre de distintos directorios en el sistema utilizando su ID. - -Tenga en cuenta que si se ejecuta más de una aplicación con el mismo nombre, los mandatos `pm2` se aplican en todas ellas. Por lo tanto, utilice ID en lugar de nombres para gestionar aplicaciones individuales. - -Liste todos los procesos en ejecución: - -
    -
    -$ pm2 list
    -
    -
    - -Detenga una aplicación: - -
    -
    -$ pm2 stop 0
    -
    -
    - -Reinicie una aplicación: - -
    -
    -$ pm2 restart 0
    -
    -
    - -Para ver información detallada sobre una aplicación: - -
    -
    -$ pm2 show 0
    -
    -
    - -Para eliminar una aplicación del registro de PM2: - -
    -
    -$ pm2 delete 0
    -
    -
    - - -## Forever - -Forever es una herramienta de interfaz de línea de mandatos simple que permite garantizar la ejecución continua (forever/siempre) de un determinado script. La sencilla interfaz de Forever hace que sea ideal para ejecutar los despliegues más pequeños de scripts y aplicaciones Node.js. - -Para obtener más información, consulte [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Instalación - -
    -
    -$ [sudo] npm install forever -g
    -
    -
    - -### Uso básico - -Para iniciar un script, utilice el mandato `forever start` y especifique la vía de acceso del script: - -
    -
    -$ forever start script.js
    -
    -
    - -Este mandato ejecutará el script en modalidad daemon (en segundo plano). - -Para ejecutar el script para que se adjunte al terminal, omita `start`: - -
    -
    -$ forever script.js
    -
    -
    - -Se recomienda registrar la salida de la herramienta Forever y el script utilizando las opciones de registro `-l`, `-o` y `-e`, como se muestra en este ejemplo: - -
    -
    -$ forever start -l forever.log -o out.log -e err.log script.js
    -
    -
    - -Para ver la lista de scripts que ha iniciado Forever: - -
    -
    -$ forever list
    -
    -
    - -Para detener un script iniciado por Forever, utilice el mandato `forever stop` y especifique el índice de procesos (como se lista con el mandato `forever list`). - -
    -
    -$ forever stop 1
    -
    -
    - -De manera alternativa, puede especificar la vía de acceso del archivo: - -
    -
    -$ forever stop script.js
    -
    -
    - -Para detener todos los scripts que ha iniciado Forever: - -
    -
    -$ forever stopall
    -
    -
    - -Forever tiene más opciones y también proporciona una API mediante programación. diff --git a/es/advanced/security-updates.md b/es/advanced/security-updates.md old mode 100755 new mode 100644 index 794bdfc777..2762211374 --- a/es/advanced/security-updates.md +++ b/es/advanced/security-updates.md @@ -1,44 +1,87 @@ --- layout: page title: Actualizaciones de seguridad de Express +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: es +redirect_from: " " --- # Actualizaciones de seguridad
    -Las vulnerabilidades de Node.js afectan directamente a Express. Por lo tanto, [vigile las vulnerabilidades de Node.js](http://blog.nodejs.org/vulnerability/) y asegúrese de utilizar la versión estable más reciente de Node.js. +Node.js vulnerabilities directly affect Express. Por lo tanto, [vigile las vulnerabilidades de Node.js](https://nodejs.org +/en/blog/vulnerability/) y asegúrese de utilizar la versión estable más reciente de Node.js.
    En la lista siguiente se muestran las vulnerabilidades de Express que se han solucionado en la actualización de versión especificada. +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} + ## 4.x - * 4.11.1 - * Se ha solucionado la vulnerabilidad de divulgación de vía de acceso raíz en `express.static`, `res.sendfile` y `res.sendFile` - * 4.10.7 - * Se ha solucionado la vulnerabilidad de Open Redirect en `express.static` ([anuncio](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 4.8.8 - * Se han solucionado las vulnerabilidades de cruce de directorios en `express.static` ([anuncio](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 puede tener fugas de `fd` en determinadas situaciones que afectan a `express.static` y `res.sendfile`. Las solicitudes maliciosas pueden provocar la fuga de `fd` y, en última instancia, generar errores `EMFILE` y anular la capacidad de respuesta del servidor. - * 4.8.0 - * Las matrices dispersas que tienen índices extremadamente altos en la serie de consulta pueden hacer que el proceso se quede sin memoria y se bloquee el servidor. - * Los objetos de serie de consulta extremadamente anidados pueden hacer que se bloquee el proceso y anular la capacidad de respuesta del servidor temporalmente. +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. + - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. +- 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +- 4.15.2 + - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - Se ha solucionado la vulnerabilidad de divulgación de vía de acceso raíz en `express.static`, `res.sendfile` y `res.sendFile` +- 4.10.7 + - Se ha solucionado la vulnerabilidad de Open Redirect en `express.static` ([anuncio](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 4.8.8 + - Se han solucionado las vulnerabilidades de cruce de directorios en `express.static` ([anuncio](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 puede tener fugas de `fd` en determinadas situaciones que afectan a `express.static` y `res.sendfile`. Las solicitudes maliciosas pueden provocar la fuga de `fd` y, en última instancia, generar errores `EMFILE` y anular la capacidad de respuesta del servidor. +- 4.8.0 + - Las matrices dispersas que tienen índices extremadamente altos en la serie de consulta pueden hacer que el proceso se quede sin memoria y se bloquee el servidor. + - Los objetos de serie de consulta extremadamente anidados pueden hacer que se bloquee el proceso y anular la capacidad de respuesta del servidor temporalmente. ## 3.x - * 3.19.1 - * Se ha solucionado la vulnerabilidad de divulgación de vía de acceso raíz en `express.static`, `res.sendfile` y `res.sendFile` - * 3.19.0 - * Se ha solucionado la vulnerabilidad de Open Redirect en `express.static` ([anuncio](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Se han solucionado las vulnerabilidades de cruce de directorios en `express.static`. - * 3.16.6 - * Node.js 0.10 puede tener fugas de `fd` en determinadas situaciones que afectan a `express.static` y `res.sendfile`. Las solicitudes maliciosas pueden provocar la fuga de `fd` y, en última instancia, generar errores `EMFILE` y anular la capacidad de respuesta del servidor. - * 3.16.0 - * Las matrices dispersas que tienen índices extremadamente altos en la serie de consulta pueden hacer que el proceso se quede sin memoria y se bloquee el servidor. - * Los objetos de serie de consulta extremadamente anidados pueden hacer que se bloquee el proceso y anular la capacidad de respuesta del servidor temporalmente. - * 3.3.0 - * La respuesta 404 de un intento de alteración temporal de método no soportado era susceptible de ataques de scripts entre sitios. +
    + **Express 3.x YA NO SE MANTIENE** + +Los problemas de rendimiento y seguridad conocidos y desconocidos en 3.x no se han solucionado desde la última actualización (1 de agosto de 2015). Se recomienda especialmente utilizar la última versión de Express. + +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). + +
    + +- 3.19.1 + - Se ha solucionado la vulnerabilidad de divulgación de vía de acceso raíz en `express.static`, `res.sendfile` y `res.sendFile` +- 3.19.0 + - Se ha solucionado la vulnerabilidad de Open Redirect en `express.static` ([anuncio](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 3.16.10 + - Se han solucionado las vulnerabilidades de cruce de directorios en `express.static`. +- 3.16.6 + - Node.js 0.10 puede tener fugas de `fd` en determinadas situaciones que afectan a `express.static` y `res.sendfile`. Las solicitudes maliciosas pueden provocar la fuga de `fd` y, en última instancia, generar errores `EMFILE` y anular la capacidad de respuesta del servidor. +- 3.16.0 + - Las matrices dispersas que tienen índices extremadamente altos en la serie de consulta pueden hacer que el proceso se quede sin memoria y se bloquee el servidor. + - Los objetos de serie de consulta extremadamente anidados pueden hacer que se bloquee el proceso y anular la capacidad de respuesta del servidor temporalmente. +- 3.3.0 + - La respuesta 404 de un intento de alteración temporal de método no soportado era susceptible de ataques de scripts entre sitios. \ No newline at end of file diff --git a/es/api.md b/es/api.md old mode 100755 new mode 100644 index 6464fc36ee..6fe643ea9e --- a/es/api.md +++ b/es/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - Referencia de API -lang: es +layout: api +version: 5x +title: Express 5.x - Referencia de API +description: Acceda a la referencia de la API para Express.js detallando todos los módulos, métodos y propiedades para construir aplicaciones web con esta versión. +menu: api +redirect_from: " " --- -
    - -

    API de 4.x

    - - - {% include api/en/4x/express.md %} +
    +

    5.x API

    + {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
    diff --git a/es/changelog/index.md b/es/changelog/index.md new file mode 100644 index 0000000000..2456265b18 --- /dev/null +++ b/es/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/es/guide/behind-proxies.md b/es/guide/behind-proxies.md old mode 100755 new mode 100644 index ac4b406748..038e1ed139 --- a/es/guide/behind-proxies.md +++ b/es/guide/behind-proxies.md @@ -1,20 +1,23 @@ --- layout: page title: Express detrás de proxies +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: es +redirect_from: " " --- # Express detrás de proxies -Cuando ejecute una aplicación Express detrás de un proxy, establezca (utilizando [app.set()](/{{ page.lang }}/4x/api.html#app.set)) la variable de aplicación `trust proxy` en uno de los valores de la siguiente tabla. +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
    -Aunque la aplicación no dejará de ejecutarse si no se establece la variable de aplicación `trust proxy`, registrará incorrectamente la dirección IP del proxy como la dirección IP del cliente, a menos que se configure `trust proxy`. +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
    +The application setting `trust proxy` may be set to one of the values listed in the following table. + - + @@ -22,51 +25,62 @@ Aunque la aplicación no dejará de ejecutarse si no se establece la variable de Si es `true`, la dirección IP del cliente se entiende como la entrada más a la izquierda en la cabecera `X-Forwarded-*`. Si es `false`, la aplicación se entiende como orientada directamente a Internet, y la dirección IP del cliente se obtiene de `req.connection.remoteAddress`. Este es el valor predeterminado. + +
    +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
    - + - + - +
    TipoValor
    TypeValue
    Booleano
    Direcciones IPIP addresses -Una dirección IP, una subred o una matriz de direcciones IP y subredes de confianza. La siguiente lista muestra los nombres de subred preconfigurados: +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` +- loopback - `127.0.0.1/8`, `::1/128` +- linklocal - `169.254.0.0/16`, `fe80::/10` +- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` Puede establecer direcciones IP de varias formas: -
    -app.set('trust proxy', 'loopback') // specify a single subnet
    +```js
    +app.set('trust proxy', 'loopback') // specify a single subnet
     app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
     app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
    -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
    -
    +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` + +Cuando se especifican, las direcciones IP o las subredes se excluyen del proceso de determinación de direcciones, y la dirección IP no de confianza más próxima al servidor de aplicaciones se establece como la dirección IP del cliente. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. -Cuando se especifican, las direcciones IP o las subredes se excluyen del proceso de determinación de direcciones, y la dirección IP no de confianza más próxima al servidor de aplicaciones se establece como la dirección IP del cliente.
    NúmeroNumber -Confíe en la porción `n` entre el origen y el destino del servidor proxy accesible externamente como el cliente. +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. + +
    +When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
    FunciónFunction -Implementación de confianza personalizada. Utilícela sólo si sabe lo que está haciendo. -
    -app.set('trust proxy', function (ip) {
    -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
    -  else return false;
    -});
    -
    +Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
    -Si establece un valor de `trust proxy` distinto de `false`, se producen tres cambios importantes: +Enabling `trust proxy` will have the following impact:
    • El valor de [req.hostname](/{{ page.lang }}/api.html#req.hostname) se obtiene del valor definido en la cabecera `X-Forwarded-Host`, que puede estar establecido por el cliente o el proxy. @@ -77,4 +91,4 @@ Si establece un valor de `trust proxy` distinto de `false`, se producen tres cam
    -El valor `trust proxy` se implementa utilizando el paquete [proxy-addr](https://www.npmjs.com/package/proxy-addr). Para obtener más información, consulte su documentación. +El valor `trust proxy` se implementa utilizando el paquete [proxy-addr](https://www.npmjs.com/package/proxy-addr). For more information, see its documentation. diff --git a/es/guide/database-integration.md b/es/guide/database-integration.md old mode 100755 new mode 100644 index fc7efdf54e..af5f568f39 --- a/es/guide/database-integration.md +++ b/es/guide/database-integration.md @@ -1,239 +1,288 @@ --- layout: page title: Integración de la base de datos de Express +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: es +redirect_from: " " --- # Integración de la base de datos La adición de la funcionalidad de conectar bases de datos a las aplicaciones Express se consigue simplemente cargando el controlador de Node.js adecuado para la base de datos en la aplicación. En este documento se describe brevemente cómo añadir y utilizar algunos de los módulos de Node.js más conocidos para los sistemas de base de datos en la aplicación Express: -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongo) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgres) +- [Redis](#redis) +- +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
    -Estos son algunos de los muchos controladores de base de datos que hay disponibles. Para ver otras opciones, realice búsquedas en el sitio [npm](https://www.npmjs.com/). +Estos son algunos de los muchos controladores de base de datos que hay disponibles. Para ver otras opciones, realice búsquedas en el sitio [npm](https://www.npmjs.com/).
    - - ## Cassandra **Módulo**: [cassandra-driver](https://github.com/datastax/nodejs-driver) **Instalación** -
    -
    +### 
    +
    +```bash
     $ npm install cassandra-driver
    -
    -
    +``` -**Ejemplo** +### -
    -
    -var cassandra = require('cassandra-driver');
    -var client = new cassandra.Client({ contactPoints: ['localhost']});
    +```js
    +const cassandra = require('cassandra-driver')
    +const client = new cassandra.Client({ contactPoints: ['localhost'] })
    +
    +client.execute('select key from system.local', (err, result) => {
    +  if (err) throw err
    +  console.log(result.rows[0])
    +})
    +```
    +
    +## Couchbase
     
    -client.execute('select key from system.local', function(err, result) {
    -  if (err) throw err;
    -  console.log(result.rows[0]);
    -});
    -
    -
    +**Module**: [couchnode](https://github.com/couchbase/couchnode) - +### + +```bash +$ npm install couchbase +``` + +### + +```js +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') + +// add a document to a bucket +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) + +// get all documents with shoe size 13 +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) +``` ## CouchDB **Módulo**: [nano](https://github.com/dscape/nano) **Instalación** -
    -
    +### 
    +
    +```bash
     $ npm install nano
    -
    -
    +``` -**Ejemplo** +### -
    -
    -var nano = require('nano')('http://localhost:5984');
    -nano.db.create('books');
    -var books = nano.db.use('books');
    -
    -//Insert a book document in the books database
    -books.insert({name: 'The Art of war'}, null, function(err, body) {
    -  if (!err){
    -    console.log(body);
    -  }
    -});
    +```js
    +const nano = require('nano')('http://localhost:5984')
    +nano.db.create('books')
    +const books = nano.db.use('books')
     
    -//Get a list of all books
    -books.list(function(err, body){
    -  console.log(body.rows);
    -});
    -
    -
    +// Insert a book document in the books database +books.insert({ name: 'The Art of war' }, null, (err, body) => { + if (err) { + console.log(err) + } else { + console.log(body) + } +}) - +// Get a list of all books +books.list((err, body) => { + if (err) { + console.log(err) + } else { + console.log(body.rows) + } +}) +``` ## LevelDB **Módulo**: [levelup](https://github.com/rvagg/node-levelup) **Instalación** -
    -
    -$ npm install level levelup leveldown
    -
    -
    +### -**Ejemplo** +```bash +$ npm install level levelup leveldown +``` -
    -
    -var levelup = require('levelup');
    -var db = levelup('./mydb');
    +### 
     
    -db.put('name', 'LevelUP', function (err) {
    +```js
    +const levelup = require('levelup')
    +const db = levelup('./mydb')
     
    -  if (err) return console.log('Ooops!', err);
    -  db.get('name', function (err, value) {
    -    if (err) return console.log('Ooops!', err);
    -    console.log('name=' + value);
    -  });
    +db.put('name', 'LevelUP', (err) => {
    +  if (err) return console.log('Ooops!', err)
     
    -});
    -
    -
    + db.get('name', (err, value) => { + if (err) return console.log('Ooops!', err) - + console.log(`name=${value}`) + }) +}) +``` ## MySQL **Módulo**: [mysql](https://github.com/felixge/node-mysql/) **Instalación** -
    -
    +### 
    +
    +```bash
     $ npm install mysql
    -
    -
    +``` -**Ejemplo** +### -
    -
    -var mysql      = require('mysql');
    -var connection = mysql.createConnection({
    -  host     : 'localhost',
    -  user     : 'dbuser',
    -  password : 's3kreee7'
    -});
    +```js
    +const mysql = require('mysql')
    +const connection = mysql.createConnection({
    +  host: 'localhost',
    +  user: 'dbuser',
    +  password: 's3kreee7',
    +  database: 'my_db'
    +})
     
    -connection.connect();
    +connection.connect()
     
    -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
    -  if (err) throw err;
    -  console.log('The solution is: ', rows[0].solution);
    -});
    +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
    +  if (err) throw err
     
    -connection.end();
    -
    -
    + console.log('The solution is: ', rows[0].solution) +}) - +connection.end() +``` ## MongoDB **Módulo**: [mongodb](https://github.com/mongodb/node-mongodb-native) **Instalación** -
    -
    +### 
    +
    +```bash
     $ npm install mongodb
    -
    -
    +``` -**Ejemplo** +### Example (v2.\*) -
    -
    -var MongoClient = require('mongodb').MongoClient;
    +```js
    +const MongoClient = require('mongodb').MongoClient
     
    -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
    -  if (err) {
    -    throw err;
    -  }
    -  db.collection('mammals').find().toArray(function(err, result) {
    -    if (err) {
    -      throw err;
    -    }
    -    console.log(result);
    -  });
    -});
    -
    -
    +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { + if (err) throw err -Si desea un controlador de modelo de objeto para MongoDB, consulte [Mongoose](https://github.com/LearnBoost/mongoose). + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` - +### -## Neo4j +```js +const MongoClient = require('mongodb').MongoClient -**Módulo**: [apoc](https://github.com/hacksparrow/apoc) -**Instalación** +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { + if (err) throw err -
    -
    -$ npm install apoc
    -
    -
    + const db = client.db('animals') -**Ejemplo** + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +Si desea un controlador de modelo de objeto para MongoDB, consulte [Mongoose](https://github.com/LearnBoost/mongoose). + +## Neo4j -
     
    -var apoc = require('apoc');
    -
    -apoc.query('match (n) return n').exec().then(
    -  function (response) {
    -    console.log(response);
    -  },
    -  function (fail) {
    -    console.log(fail);
    -  }
    -);
    -
    -
    +var apoc = require('apoc');apoc.query('match (n) return n').exec().then( +function (response) { +console.log(response); +}, +function (fail) { +console.log(fail); +} +); + +### + +```bash +$ npm install neo4j-driver +``` + +### + +```js +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) + +const session = driver.session() - +session.readTransaction((tx) => { + return tx.run('MATCH (n) RETURN count(n) AS count') + .then((res) => { + console.log(res.records[0].get('count')) + }) + .catch((error) => { + console.log(error) + }) +}) +``` ## Oracle -**Módulo**: [oracledb](https://github.com/oracle/node-oracledb) +**Module**: [oracledb](https://github.com/oracle/node-oracledb) -### Instalación +### NOTA: [Vea los requisitos previos de instalación](https://github.com/oracle/node-oracledb#-installation). -```sh +```bash $ npm install oracledb ``` -### Ejemplo +### ```js const oracledb = require('oracledb') @@ -267,138 +316,182 @@ async function getEmployee (empId) { getEmployee(101) ``` - - - ## PostgreSQL **Módulo**: [pg-promise](https://github.com/vitaly-t/pg-promise) **Instalación** -
    -
    -$ npm install pg-promise
    -
    -
    - -**Ejemplo** +### -
    -
    -var pgp = require("pg-promise")(/*options*/);
    -var db = pgp("postgres://username:password@host:port/database");
    +```bash
    +$ npm install pg-promise
    +```
     
    -db.one("SELECT $1 AS value", 123)
    -    .then(function (data) {
    -        console.log("DATA:", data.value);
    -    })
    -    .catch(function (error) {
    -        console.log("ERROR:", error);
    -    });
    -
    -
    +### - +```js +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') + +db.one('SELECT $1 AS value', 123) + .then((data) => { + console.log('DATA:', data.value) + }) + .catch((error) => { + console.log('ERROR:', error) + }) +``` ## Redis **Módulo**: [redis](https://github.com/mranney/node_redis) **Instalación** -
    -
    +### 
    +
    +```bash
     $ npm install redis
    -
    -
    +``` -**Ejemplo** +### -
    -
    -var client = require('redis').createClient();
    +```js
    +const redis = require('redis')
    +const client = redis.createClient()
    +
    +client.on('error', (err) => {
    +  console.log(`Error ${err}`)
    +})
     
    -client.on('error', function (err) {
    -  console.log('Error ' + err);
    -});
    +client.set('string key', 'string val', redis.print)
    +client.hset('hash key', 'hashtest 1', 'some value', redis.print)
    +client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
     
    -client.set('string key', 'string val', redis.print);
    -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
    -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
    +client.hkeys('hash key', (err, replies) => {
    +  console.log(`${replies.length} replies:`)
     
    -client.hkeys('hash key', function (err, replies) {
    +  replies.forEach((reply, i) => {
    +    console.log(`    ${i}: ${reply}`)
    +  })
     
    -  console.log(replies.length + ' replies:');
    -  replies.forEach(function (reply, i) {
    -    console.log('    ' + i + ': ' + reply);
    -  });
    +  client.quit()
    +})
    +```
     
    -  client.quit();
    +## SQL Server
     
    -});
    -
    -
    +**Module**: [tedious](https://github.com/tediousjs/tedious) - +### + +```bash +$ npm install tedious +``` + +### + +```js +const Connection = require('tedious').Connection +const Request = require('tedious').Request + +const config = { + server: 'localhost', + authentication: { + type: 'default', + options: { + userName: 'your_username', // update me + password: 'your_password' // update me + } + } +} + +const connection = new Connection(config) + +connection.on('connect', (err) => { + if (err) { + console.log(err) + } else { + executeStatement() + } +}) + +function executeStatement () { + request = new Request("select 123, 'hello world'", (err, rowCount) => { + if (err) { + console.log(err) + } else { + console.log(`${rowCount} rows`) + } + connection.close() + }) + + request.on('row', (columns) => { + columns.forEach((column) => { + if (column.value === null) { + console.log('NULL') + } else { + console.log(column.value) + } + }) + }) + + connection.execSql(request) +} +``` ## SQLite **Módulo**: [sqlite3](https://github.com/mapbox/node-sqlite3) **Instalación** -
    -
    -$ npm install sqlite3
    -
    -
    +### -**Ejemplo** +```bash +$ npm install sqlite3 +``` -
    -
    -var sqlite3 = require('sqlite3').verbose();
    -var db = new sqlite3.Database(':memory:');
    +### 
     
    -db.serialize(function() {
    +```js
    +const sqlite3 = require('sqlite3').verbose()
    +const db = new sqlite3.Database(':memory:')
     
    -  db.run('CREATE TABLE lorem (info TEXT)');
    -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
    +db.serialize(() => {
    +  db.run('CREATE TABLE lorem (info TEXT)')
    +  const stmt = db.prepare('INSERT INTO lorem VALUES (?)')
     
    -  for (var i = 0; i < 10; i++) {
    -    stmt.run('Ipsum ' + i);
    +  for (let i = 0; i < 10; i++) {
    +    stmt.run(`Ipsum ${i}`)
       }
     
    -  stmt.finalize();
    +  stmt.finalize()
     
    -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
    -    console.log(row.id + ': ' + row.info);
    -  });
    -});
    +  db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
    +    console.log(`${row.id}: ${row.info}`)
    +  })
    +})
     
    -db.close();
    -
    -
    - - +db.close() +``` ## ElasticSearch **Módulo**: [elasticsearch](https://github.com/elastic/elasticsearch-js) **Instalación** -
    -
    +### 
    +
    +```bash
     $ npm install elasticsearch
    -
    -
    +``` -**Ejemplo** +### -
    -
    -var elasticsearch = require('elasticsearch');
    -var client = elasticsearch.Client({
    +```js
    +const elasticsearch = require('elasticsearch')
    +const client = elasticsearch.Client({
       host: 'localhost:9200'
    -});
    +})
     
     client.search({
       index: 'books',
    @@ -411,10 +504,9 @@ client.search({
           }
         }
       }
    -}).then(function(response) {
    -  var hits = response.hits.hits;
    -}, function(error) {
    -  console.trace(error.message);
    -});
    -
    -
    +}).then((response) => { + const hits = response.hits.hits +}, (error) => { + console.trace(error.message) +}) +``` diff --git a/es/guide/debugging.md b/es/guide/debugging.md old mode 100755 new mode 100644 index c515fdf415..8011fc0c68 --- a/es/guide/debugging.md +++ b/es/guide/debugging.md @@ -1,38 +1,28 @@ --- layout: page title: Depuración de Express +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: es +redirect_from: " " --- # Depuración de Express -Express utiliza el módulo [debug](https://www.npmjs.com/package/debug) internamente para registrar información sobre las coincidencias de rutas, las funciones de middleware que se están utilizando, la modalidad de aplicación y el flujo del ciclo de solicitud/respuestas. - -
    -`debug` es como una versión aumentada de `console.log`, aunque a diferencia de `console.log`, no tiene que comentar los registros `debug` en el código de producción. El registro está desactivado de forma predeterminada y puede activarse condicionalmente utilizando la variable de entorno `DEBUG`. -
    - Para ver todos los registros internos utilizados en Express, establezca la variable de entorno `DEBUG` en `express:*` cuando inicie la aplicación. -
    -
    +```bash
     $ DEBUG=express:* node index.js
    -
    -
    +``` En Windows, utilice el mandato correspondiente. -
    -
    -> set DEBUG=express:* & node index.js
    -
    -
    +```bash +> $env:DEBUG = "express:*"; node index.js +``` La ejecución de este mandato en la aplicación predeterminada generada por el [generador de Express](/{{ page.lang }}/starter/generator.html) imprime la siguiente salida: -
    -
    +```bash
     $ DEBUG=express:* node ./bin/www
       express:router:route new / +0ms
       express:router:layer new / +1ms
    @@ -68,19 +58,17 @@ $ DEBUG=express:* node ./bin/www
       express:router:layer new / +1ms
       express:router use /users router +0ms
       express:router:layer new /users +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -
    -
    +``` Cuando se realiza una solicitud a la aplicación, verá los registros especificados en el código de Express: -
    -
    +```bash
       express:router dispatching GET / +4h
       express:router query  : / +2ms
       express:router expressInit  : / +0ms
    @@ -96,29 +84,46 @@ Cuando se realiza una solicitud a la aplicación, verá los registros especifica
       express:view lookup "index.pug" +338ms
       express:view stat "/projects/example/views/index.pug" +0ms
       express:view render "/projects/example/views/index.pug" +1ms
    -
    -
    +``` Para ver sólo los registros de la implementación de direccionador, establezca el valor de `DEBUG` en `express:router`. De la misma forma, para ver sólo los registros de la implementación de aplicación, establezca el valor de `DEBUG` en `express:application`, etc. -## Aplicaciones generadas por `express` +## Applications generated by `express` -Una aplicación generada por el mandato `express` también utiliza el módulo `debug`, y el ámbito de su espacio de nombres de depuración se establece en el nombre de la aplicación. +Una aplicación generada por el mandato `express` utiliza el módulo `debug`, y el ámbito de su espacio de nombres de depuración se establece en el nombre de la aplicación. Por ejemplo, si ha generado la aplicación con `$ express sample-app`, puede habilitar las sentencias de depuración con el siguiente mandato: -
    -
    +```bash
     $ DEBUG=sample-app:* node ./bin/www
    -
    -
    +``` Puede especificar más de un espacio de nombres de depuración asignando una lista separada por comas de nombres: -
    -
    +```bash
     $ DEBUG=http,mail,express:* node index.js
    -
    -
    +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -Para obtener más información sobre `debug`, consulte [debug](https://www.npmjs.com/package/debug). +{% include admonitions/note.html content=debug-text %} diff --git a/es/guide/error-handling.md b/es/guide/error-handling.md old mode 100755 new mode 100644 index 01c28397da..1d5c7e72e2 --- a/es/guide/error-handling.md +++ b/es/guide/error-handling.md @@ -1,118 +1,143 @@ --- layout: page title: Manejo de errores de Express +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: es +redirect_from: " " --- -# Manejo de errores +# Error Handling -Defina las funciones de middleware de manejo de errores de la misma forma que otras funciones de middleware, excepto que las funciones de manejo de errores tienen cuatro argumentos en lugar de tres: `(err, req, res, next)`. Por ejemplo: +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +## Catching Errors -El middleware de manejo de errores se define al final, después de otras llamadas de rutas y `app.use()`; por ejemplo: +It's important to ensure that Express catches all errors that occur while +running route handlers and middleware. -
    -
    -var bodyParser = require('body-parser');
    -var methodOverride = require('method-override');
    +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:
     
    -app.use(bodyParser());
    -app.use(methodOverride());
    -app.use(function(err, req, res, next) {
    -  // logic
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + throw new Error('BROKEN') // Express will catch this on its own. +}) +``` -Las respuestas desde una función de middleware pueden estar en el formato que prefiera, por ejemplo, una página de errores HTML, un mensaje simple o una serie JSON. +Defina las funciones de middleware de manejo de errores de la misma forma que otras funciones de middleware, excepto que las funciones de manejo de errores tienen cuatro argumentos en lugar de tres: `(err, req, res, next)`. For example: -A efectos de la organización (y de infraestructura de nivel superior), puede definir varias funciones de middleware de manejo de errores, de la misma forma que con las funciones de middleware normales. Por ejemplo, si desea definir un manejador de errores para las solicitudes realizadas utilizando `XHR`, y las que no lo tienen, puede utilizar los siguientes mandatos: +```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) + } + }) +}) +``` -
    -
    -var bodyParser = require('body-parser');
    -var methodOverride = require('method-override');
    +Si tiene un manejador de rutas con varias funciones de devolución de llamada, puede utilizar el parámetro `route` para omitir el siguiente manejador de rutas.
    +For example:
     
    -app.use(bodyParser());
    -app.use(methodOverride());
    -app.use(logErrors);
    -app.use(clientErrorHandler);
    -app.use(errorHandler);
    -
    -
    +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` -En este ejemplo, los `logErrors` genéricos pueden escribir información de solicitudes y errores en `stderr`, por ejemplo: +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. -
    -
    -function logErrors(err, req, res, next) {
    -  console.error(err.stack);
    -  next(err);
    -}
    -
    -
    +Si pasa cualquier valor a la función `next()` (excepto la serie `'route'`), Express considera que la solicitud actual tiene un error y omitirá las restantes funciones de middleware y direccionamiento que no son de manejo de errores. -También en este ejemplo, `clientErrorHandler` se define de la siguiente manera; en este caso, el error se pasa de forma explícita al siguiente: +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: -
    -
    -function clientErrorHandler(err, req, res, next) {
    -  if (req.xhr) {
    -    res.status(500).send({ error: 'Something failed!' });
    -  } else {
    -    next(err);
    +```js
    +app.get('/', [
    +  function (req, res, next) {
    +    fs.writeFile('/inaccessible-path', 'data', next)
    +  },
    +  function (req, res) {
    +    res.send('OK')
       }
    -}
    -
    -
    +]) +``` -La función que detecta todos los errores de `errorHandler` puede implementarse de la siguiente manera: +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. -
    -
    -function errorHandler(err, req, res, next) {
    -  res.status(500);
    -  res.render('error', { error: err });
    -}
    -
    -
    +You must catch errors that occur in asynchronous code invoked by route handlers or +middleware and pass them to Express for processing. For example: -Si pasa cualquier valor a la función `next()` (excepto la serie `'route'`), Express considera que la solicitud actual tiene un error y omitirá las restantes funciones de middleware y direccionamiento que no son de manejo de errores. Si desea manejar ese error de alguna manera, deberá crear una ruta de manejo de errores como se describe en la siguiente sección. +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN') + } catch (err) { + next(err) + } + }, 100) +}) +``` -Si tiene un manejador de rutas con varias funciones de devolución de llamada, puede utilizar el parámetro `route` para omitir el siguiente manejador de rutas. Por ejemplo: +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. -
    -
    -app.get('/a_route_behind_paywall',
    -  function checkIfPaidSubscriber(req, res, next) {
    -    if(!req.user.hasPaid) {
    +Use promises to avoid the overhead of the `try...catch` block or when using functions
    +that return promises.  For example:
     
    -      // continue handling this request
    -      next('route');
    -    }
    -  }, function getPaidContent(req, res, next) {
    -    PaidContent.find(function(err, doc) {
    -      if(err) return next(err);
    -      res.json(doc);
    -    });
    -  });
    -
    -
    +```js +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { + throw new Error('BROKEN') + }).catch(next) // Errors will be passed to Express. +}) +``` -En este ejemplo, se omitirá el manejador `getPaidContent`, pero los restantes manejadores en `app` para `/a_route_behind_paywall` continuarán ejecutándose. +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. -
    -Las llamadas a `next()` y `next(err)` indican que el manejador actual está completo y en qué estado. `next(err)` omitirá los demás manejadores de la cadena, excepto los que se hayan configurado para manejar errores como se ha descrito anteriormente. -
    +You could also use a chain of handlers to rely on synchronous error +catching, by reducing the asynchronous code to something trivial. For example: + +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +The above example has a couple of trivial statements from 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 +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. + +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. ## El manejador de errores predeterminado @@ -124,18 +149,135 @@ Si pasa un error a `next()` y no lo maneja en el manejador de errores, lo maneja Establezca la variable de entorno `NODE_ENV` en `production`, para ejecutar la aplicación en modalidad de producción.
    +When an error is written, the following information is added to the +response: + +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. + Si invoca `next()` con un error después de haber empezado a escribir la respuesta (por ejemplo, si encuentra un error mientras se envía la respuesta en modalidad continua al cliente), el manejador de errores predeterminado de Express cierra la conexión y falla la solicitud. Por lo tanto, cuando añade un manejador de errores personalizado, se recomienda delegar en los mecanismos de manejo de errores predeterminados de Express, cuando las cabeceras ya se han enviado al cliente: -
    -
    -function errorHandler(err, req, res, next) {
    +```js
    +function errorHandler (err, req, res, next) {
       if (res.headersSent) {
    -    return next(err);
    +    return next(err)
    +  }
    +  res.status(500)
    +  res.render('error', { error: err })
    +}
    +```
    +
    +Note that the default error handler can get triggered if you call `next()` with an error
    +in your code more than once, even if custom error handling middleware is in place.
    +
    +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html).
    +
    +## Writing error handlers
    +
    +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)`. For example:
    +
    +```js
    +app.use((err, req, res, next) => {
    +  console.error(err.stack)
    +  res.status(500).send('Something broke!')
    +})
    +```
    +
    +El middleware de manejo de errores se define al final, después de otras llamadas de rutas y `app.use()`; por ejemplo:
    +
    +```js
    +const bodyParser = require('body-parser')
    +const methodOverride = require('method-override')
    +
    +app.use(bodyParser.urlencoded({
    +  extended: true
    +}))
    +app.use(bodyParser.json())
    +app.use(methodOverride())
    +app.use((err, req, res, next) => {
    +  // logic
    +})
    +```
    +
    +Las respuestas desde una función de middleware pueden estar en el formato que prefiera, por ejemplo, una página de errores HTML, un mensaje simple o una serie JSON.
    +
    +A efectos de la organización (y de infraestructura de nivel superior), puede definir varias funciones de middleware de manejo de errores, de la misma forma que con las funciones de middleware normales. Por ejemplo, si desea definir un manejador de errores para las solicitudes realizadas utilizando `XHR`, y las que no lo tienen, puede utilizar los siguientes mandatos:
    +
    +```js
    +const bodyParser = require('body-parser')
    +const methodOverride = require('method-override')
    +
    +app.use(bodyParser.urlencoded({
    +  extended: true
    +}))
    +app.use(bodyParser.json())
    +app.use(methodOverride())
    +app.use(logErrors)
    +app.use(clientErrorHandler)
    +app.use(errorHandler)
    +```
    +
    +En este ejemplo, los `logErrors` genéricos pueden escribir información de solicitudes y errores en `stderr`, por ejemplo:
    +
    +```js
    +function logErrors (err, req, res, next) {
    +  console.error(err.stack)
    +  next(err)
    +}
    +```
    +
    +También en este ejemplo, `clientErrorHandler` se define de la siguiente manera; en este caso, el error se pasa de forma explícita al siguiente:
    +
    +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.
    +
    +```js
    +function clientErrorHandler (err, req, res, next) {
    +  if (req.xhr) {
    +    res.status(500).send({ error: 'Something failed!' })
    +  } else {
    +    next(err)
       }
    -  res.status(500);
    -  res.render('error', { error: err });
     }
    -
    -
    +``` + +La función que detecta todos los errores de `errorHandler` puede implementarse de la siguiente manera: + +```js +function errorHandler (err, req, res, next) { + res.status(500) + res.render('error', { error: err }) +} +``` + +If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. For example: + +```js +app.get('/a_route_behind_paywall', + (req, res, next) => { + if (!req.user.hasPaid) { + // continue handling this request + next('route') + } else { + next() + } + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` + +En este ejemplo, se omitirá el manejador `getPaidContent`, pero los restantes manejadores en `app` para `/a_route_behind_paywall` continuarán ejecutándose. + +
    +Las llamadas a `next()` y `next(err)` indican que el manejador actual está completo y en qué estado. `next(err)` omitirá los demás manejadores de la cadena, excepto los que se hayan configurado para manejar errores como se ha descrito anteriormente. +
    diff --git a/es/guide/migrating-4.md b/es/guide/migrating-4.md old mode 100755 new mode 100644 index 4800df31cb..437e9c7af8 --- a/es/guide/migrating-4.md +++ b/es/guide/migrating-4.md @@ -1,13 +1,14 @@ --- layout: page title: Migración a Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: es +redirect_from: " " --- # Migración a Express 4 -

    Visión general

    +

    Overview

    Express 4 es un cambio que rompe el código existente de Express 3, etc. Esto implica que una aplicación Express 3 existente no funcionará si actualiza la versión de Express en sus dependencias. @@ -16,7 +17,7 @@ En este artículo se describen:

    Los cambios en Express 4

    @@ -24,7 +25,7 @@ En este artículo se describen: Se han realizado varios cambios importantes en Express 4:
      -
    • Cambios en el sistema principal y de middleware de Express. Las dependencias de Connect y el middleware incorporado se han eliminado, por lo que debe añadir el middleware manualmente. +
    • Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
    • Cambios en el sistema de direccionamiento.
    • Otros cambios.
    • @@ -32,8 +33,8 @@ Se han realizado varios cambios importantes en Express 4: Vea también: -* [Nuevas características en 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migración de 3.x a 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

      Cambios en el sistema principal y de middleware de Express @@ -51,7 +52,7 @@ middleware necesario para ejecutar la aplicación. Sólo tiene que seguir estos En la tabla siguiente se lista el middleware de Express 3 y su contrapartida en Express 4. - + @@ -83,25 +84,24 @@ En la tabla siguiente se lista el middleware de Express 3 y su contrapartida en -
      Express 3Express 4
      Express 3Express 4
      express.bodyParser body-parser + multer
      serve-index
      express.static serve-static
      + Esta es la [lista completa](https://github.com/senchalabs/connect#middleware) de middleware de Express 4. En la mayoría de los casos, sólo tiene que sustituir el middleware de la versión 3 antigua por su contrapartida de Express 4. Para obtener detalles, consulte la documentación del módulo en GitHub. -

      app.use acepta parámetros

      +

      app.use accepts parameters

      En la versión 4, puede utilizar un parámetro de variable para definir la vía de acceso donde se cargan las funciones de middleware y, a continuación, leer el valor del parámetro en el manejador de rutas. -Por ejemplo: - -
      -
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -});
      -
      -
      +For example: + +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` +

      El sistema de direccionamiento

      @@ -111,31 +111,30 @@ Ahora las aplicaciones cargan implícitamente el middleware de direccionamiento, La forma en que define las rutas no varía, pero el sistema de direccionamiento tiene dos nuevas características que permiten organizar las rutas: {: .doclist } -* Un nuevo método, `app.route()`, para crear manejadores de rutas encadenables para una vía de acceso de ruta. -* Una nueva clase, `express.Router`, para crear manejadores de rutas montables modulares. -

      Método app.route()

      +- Un nuevo método, `app.route()`, para crear manejadores de rutas encadenables para una vía de acceso de ruta. +- Una nueva clase, `express.Router`, para crear manejadores de rutas montables modulares. + +

      app.route() method

      El nuevo método `app.route()` permite crear manejadores de rutas encadenables para una vía de acceso de ruta. Como la vía de acceso se especifica en una única ubicación, la creación de rutas modulares es muy útil, al igual que la reducción de redundancia y errores tipográficos. Para obtener más información sobre las rutas, consulte la [`documentación` de Router()](/{{ page.lang }}/4x/api.html#router). A continuación, se muestra un ejemplo de manejadores de rutas encadenados que se definen utilizando la función `app.route()`. -
      -
      +```js
       app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      +  .get((req, res) => {
      +    res.send('Get a random book')
         })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      +  .post((req, res) => {
      +    res.send('Add a book')
         })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      + .put((req, res) => { + res.send('Update the book') + }) +``` -

      Clase express.Router

      +

      express.Router class

      La otra característica que permite organizar las rutas es una nueva clase, `express.Router`, que puede utilizar para crear manejadores de rutas montables modulares. Una instancia `Router` es un sistema de middleware y direccionamiento completo; por este motivo, a menudo se conoce como una "miniaplicación". @@ -143,51 +142,49 @@ El siguiente ejemplo crea un direccionador como un módulo, carga el middleware Por ejemplo, cree un archivo de direccionador denominado `birds.js` en el directorio de la aplicación, con el siguiente contenido: -
      -
      -var express = require('express');
      -var router = express.Router();
      +```js
      +var express = require('express')
      +var router = express.Router()
       
       // middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      +router.use((req, res, next) => {
      +  console.log('Time: ', Date.now())
      +  next()
      +})
       // define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      +router.get('/', (req, res) => {
      +  res.send('Birds home page')
      +})
       // define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      +router.get('/about', (req, res) => {
      +  res.send('About birds')
      +})
       
      -module.exports = router;
      -
      -
      +module.exports = router +``` A continuación, cargue el módulo de direccionador en la aplicación: -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      +```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` La aplicación ahora podrá manejar solicitudes a las vías de acceso `/birds` y `/birds/about`, e invocará el middleware `timeLog` que es específico de la ruta.

      -Otros cambios +Other changes

      En la tabla siguiente se muestran otros cambios pequeños pero importantes en Express 4: - - - + + + @@ -199,7 +196,7 @@ Node.js 0.8.x. `http.createServer()` @@ -292,12 +289,12 @@ Se ha eliminado. La funcionalidad está ahora limitada a establecer el valor de cookie básico. Utilice `res.cookie()` para obtener la funcionalidad adicional. -
      ObjetoDescripción
      ObjectDescription
      Node.js -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 utilizando la función `app.listen()`. +The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). La aplicación puede iniciarse utilizando la función `app.listen()`.
      +

      Migración de aplicación de ejemplo

      A continuación, se muestra un ejemplo de migración de una aplicación Express 3 a Express 4. -Los archivos de interés son `app.js` y `package.json`. +The files of interest are `app.js` and `package.json`.

      Aplicación versión 3 @@ -305,50 +302,47 @@ Aplicación versión 3

      app.js

      -Considere una aplicación Express v.3 con el siguiente archivo `app.js`: +Consider an Express v.3 application with the following `app.js` file: -
      -
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      +```js
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var http = require('http')
      +var path = require('path')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(express.favicon())
      +app.use(express.logger('dev'))
      +app.use(express.methodOverride())
      +app.use(express.session({ secret: 'your secret here' }))
      +app.use(express.bodyParser())
      +app.use(app.router)
      +app.use(express.static(path.join(__dirname, 'public')))
       
       // development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(express.errorHandler())
       }
       
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

      package.json

      El archivo `package.json` de la versión 3 correspondiente será similar al siguiente: -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -361,8 +355,7 @@ El archivo `package.json` de la versión 3 correspondiente será similar al sigu
           "pug": "*"
         }
       }
      -
      -
      +```

      Proceso @@ -370,21 +363,19 @@ Proceso Para empezar el proceso de migración, instale el middleware necesario para la aplicación Express 4 y actualice Express y Pug a su versión respectiva más reciente con el siguiente mandato: -
      -
      +```bash
       $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      -
      +``` Realice los cambios siguientes en `app.js`: 1. Las funciones de middleware de Express incorporadas `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` y - `express.errorHandler` ya no están disponibles en el objeto `express`. Debe instalar sus alternativas manualmente y cargarlas en la aplicación. + `express.logger`, `express.methodOverride`, + `express.session`, `express.bodyParser` y + `express.errorHandler` ya no están disponibles en el objeto `express`. Debe instalar sus alternativas manualmente y cargarlas en la aplicación. 2. Ya no es necesario cargar la función `app.router`. - No es un objeto de aplicación Express 4 válido, por lo que debe eliminar el código `app.use(app.router);`. + No es un objeto de aplicación Express 4 válido, por lo que debe eliminar el código `app.use(app.router);`. 3. Asegúrese de que las funciones de middleware se cargan en el orden correcto: cargue `errorHandler` después de cargar las rutas de aplicación. @@ -394,8 +385,7 @@ Realice los cambios siguientes en `app.js`: La ejecución del mandato `npm` anterior actualizará `package.json` de la siguiente manera: -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -408,87 +398,86 @@ La ejecución del mandato `npm` anterior actualizará `package.json` de la sigui
           "errorhandler": "^1.1.1",
           "express": "^4.8.0",
           "express-session": "^1.7.2",
      -    "pug": "2.0.0-beta6",
      +    "pug": "^2.0.0",
           "method-override": "^2.1.2",
           "morgan": "^1.2.2",
           "multer": "^0.1.3",
           "serve-favicon": "^2.0.1"
         }
       }
      -
      -
      +```

      app.js

      A continuación, elimine el código no válido, cargue el middleware necesario y realice otros cambios según sea necesario. El archivo `app.js` será parecido al siguiente: -
      -
      -var http = require('http');
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      +```js
      +var http = require('http')
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var path = require('path')
       
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      +var favicon = require('serve-favicon')
      +var logger = require('morgan')
      +var methodOverride = require('method-override')
      +var session = require('express-session')
      +var bodyParser = require('body-parser')
      +var multer = require('multer')
      +var errorHandler = require('errorhandler')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
      +app.use(logger('dev'))
      +app.use(methodOverride())
      +app.use(session({
      +  resave: true,
      +  saveUninitialized: true,
      +  secret: 'uwotm8'
      +}))
      +app.use(bodyParser.json())
      +app.use(bodyParser.urlencoded({ extended: true }))
      +app.use(multer())
      +app.use(express.static(path.join(__dirname, 'public')))
      +
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
       // error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(errorHandler())
       }
       
      -var server = http.createServer(app);
      -server.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```
      A menos que necesite trabajar directamente con el módulo `http` (socket.io/SPDY/HTTPS), no es necesario cargarlo y la aplicación puede iniciarse simplemente de la siguiente manera: -
      -app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +
      -

      Ejecutar la aplicación

      +

      Run the app

      El proceso de migración está completo y la aplicación es ahora una aplicación Express 4. Para confirmarlo, inicie la aplicación utilizando el siguiente mandato: -
      -
      +```bash
       $ node .
      -
      -
      +``` Cargue [http://localhost:3000](http://localhost:3000) y vea la página de inicio que representa Express 4. @@ -500,20 +489,17 @@ La herramienta de línea de mandatos para generar una aplicación Express contin Si ya ha instalado el generador de aplicaciones Express 3 en el sistema, debe desinstalarlo: -
      -
      +```bash
       $ npm uninstall -g express
      -
      -
      +``` + Dependiendo de cómo se configuren los privilegios de archivos y directorios, deberá ejecutar este mandato con `sudo`. A continuación, instale el nuevo generador: -
      -
      +```bash
       $ npm install -g express-generator
      -
      -
      +``` Dependiendo de cómo se configuren los privilegios de archivos y directorios, deberá ejecutar este mandato con `sudo`. @@ -524,19 +510,18 @@ Ahora el mandato `express` en el sistema se actualiza al generador de Express 4. Las opciones de mandato y el uso continúan prácticamente iguales, con las siguientes excepciones: {: .doclist } -* Se ha eliminado la opción `--sessions`. -* Se ha eliminado la opción `--jshtml`. -* Se ha añadido la opción `--hogan` para dar soporte a [Hogan.js](http://twitter.github.io/hogan.js/). -

      Ejemplo

      +- Removed the `--sessions` option. +- Removed the `--jshtml` option. +- Se ha añadido la opción `--hogan` para dar soporte a [Hogan.js](http://twitter.github.io/hogan.js/). + +

      Ejecute el siguiente mandato para crear una aplicación Express 4: -
      -
      +```bash
       $ express app4
      -
      -
      +``` Si consulta el contenido del archivo `app4/app.js`, observará que todas las funciones de middleware (excepto `express.static`) que son necesarias para la aplicación se cargan como módulos independientes y que el middleware de `router` ya no se carga de forma explícita en la aplicación. @@ -544,11 +529,9 @@ También observará que el archivo `app.js` es ahora un módulo Node.js, a difer Después de instalar las dependencias, inicie la aplicación utilizando el siguiente mandato: -
      -
      +```bash
       $ npm start
      -
      -
      +``` Si consulta el script de inicio npm en el archivo `package.json`, observará que el mandato que inicia la aplicación es `node ./bin/www`, que antes era `node app.js` en Express 3. @@ -560,24 +543,20 @@ sin extensión son obligatorios para crear una aplicación Express o iniciar la Para eliminar el directorio `www` y dejarlo todo como en "Express 3", suprima la línea `module.exports = app;` al final del archivo `app.js` y pegue el siguiente código en su lugar: -
      -
      -app.set('port', process.env.PORT || 3000);
      +```js
      +app.set('port', process.env.PORT || 3000)
       
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      -
      +var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` Asegúrese de cargar el módulo `debug` encima del archivo `app.js` utilizando el código siguiente: -
      -
      -var debug = require('debug')('app4');
      -
      -
      +```js +var debug = require('debug')('app4') +``` A continuación, cambie `"start": "node ./bin/www"` en el archivo `package.json` por `"start": "node app.js"`. -Ahora ha devuelto la funcionalidad de `./bin/www` a `app.js`. Este cambio no se recomienda, pero el ejercicio permite entender cómo funciona el archivo `./bin/www` y por qué el archivo `app.js` ya no se inicia solo. +Ahora ha devuelto la funcionalidad de `./bin/www` a `app.js`. Este cambio no se recomienda, pero el ejercicio permite entender cómo funciona el archivo `./bin/www` y por qué el archivo `app.js` ya no se inicia solo. diff --git a/es/guide/migrating-5.md b/es/guide/migrating-5.md old mode 100755 new mode 100644 index 653670e76b..570714ec58 --- a/es/guide/migrating-5.md +++ b/es/guide/migrating-5.md @@ -1,32 +1,44 @@ --- layout: page title: Migración a Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: es +redirect_from: " " --- # Migración a Express 5 -

      Visión general

      +

      Overview

      -Express 5.0 continúa en la etapa del release alfa, pero hay una vista previa de los cambios que habrá en el release y cómo migrar la aplicación Express 4 a Express 5. +Express 5 no es muy diferente de Express 4: los cambios en la API no son tan significativos como los de la migración de 3.0 a 4.0. Aunque la API básica permanece igual, continúa habiendo cambios que rompen el código existente; es decir, un programa de Express 4 existente no funcionará si lo actualiza para que utilice Express 5. -Express 5 no es muy diferente de Express 4: los cambios en la API no son tan significativos como los de la migración de 3.0 a 4.0. Aunque la API básica permanece igual, continúa habiendo cambios que rompen el código existente; es decir, un programa de Express 4 existente no funcionará si lo actualiza para que utilice Express 5. +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -Para instalar el release alpha más reciente y obtener una vista previa de Express 5, especifique el siguiente mandato en el directorio raíz de la aplicación: - -
      -
      -$ npm install express@5.0.0-alpha.2 --save
      -
      -
      +```sh +npm install "express@5" +``` A continuación, puede ejecutar las pruebas automatizadas para ver qué falla y solucionar los problemas según las actualizaciones siguientes. Después de solucionar los errores de las pruebas, ejecute la aplicación para ver qué errores se producen. Verá rápidamente si la aplicación utiliza métodos o propiedades que no están soportados. -

      Cambios en Express 5

      +## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` -A continuación, se muestra la lista de cambios (a partir del release alpha 2) que le afectarán como usuario de Express. -Consulte la [Pull request](https://github.com/expressjs/express/pull/2237) para ver una lista de todas las características planificadas. +If you want to run a specific codemod, you can run the following command: + +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). + +

      Changes in Express 5

      **Métodos y propiedades eliminados** @@ -38,96 +50,497 @@ Consulte la [Pull request](https://github.com/expressjs/express/pull/2237) para
    • req.param(name)
    • res.json(obj, status)
    • res.jsonp(obj, status)
    • +
    • res.redirect('back') and res.location('back')
    • +
    • res.redirect(url, status)
    • res.send(body, status)
    • res.send(status)
    • res.sendfile()
    • +
    • router.param(fn)
    • +
    • express.static.mime
    • +
    • express:router debug logs
    -**Modificados** +**Mejoras** -**Mejoras** +**Modificados** -

    Métodos y propiedades eliminados

    +## Removed methods and properties Si utiliza cualquiera de estos métodos o propiedades en la aplicación, se bloqueará. Por lo tanto, deberá cambiar la aplicación después de actualizar a la versión 5. -

    app.del()

    +

    app.del()

    Express 5 ya no da soporte a la función `app.del()`. Si utiliza esta función, se genera un error. Para registrar las rutas HTTP DELETE, utilice la función `app.delete()` en su lugar. -Inicialmente, se utilizaba `del` en lugar de `delete`, porque `delete` es una palabra clave reservada en JavaScript. No obstante, a partir de ECMAScript 6, `delete` y otras palabras clave reservadas pueden utilizarse correctamente como nombres de propiedad. Puede leer aquí la discusión que llevó a descartar la función `app.del`. +Inicialmente, se utilizaba `del` en lugar de `delete`, porque `delete` es una palabra clave reservada en JavaScript. No obstante, a partir de ECMAScript 6, `delete` y otras palabras clave reservadas pueden utilizarse correctamente como nombres de propiedad. + +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-deprecated-signatures %} -

    app.param(fn)

    +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) + +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

    app.param(fn)

    La firma `app.param(fn)` se utilizaba para modificar el comportamiento de la función `app.param(name, fn)`. Está en desuso desde v4.11.0 y Express 5 ya no le da soporte. -

    Nombres de métodos pluralizados

    +

    Pluralized method names

    -Los siguientes nombres de métodos se han pluralizado. En Express 4, el uso de los métodos antiguos daba como resultado un aviso de obsolescencia. Express 5 ya no les da soporte: +Los siguientes nombres de métodos se han pluralizado. En Express 4, el uso de los métodos antiguos daba como resultado un aviso de obsolescencia. Express 5 ya no les da soporte: + +`req.acceptsLanguage()` se ha sustituido por `req.acceptsLanguages()`. `req.acceptsCharset()` se ha sustituido por `req.acceptsCharsets()`. `req.acceptsEncoding()` se ha sustituido por `req.acceptsEncodings()`. -`req.acceptsLanguage()` se ha sustituido por `req.acceptsLanguages()`. +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-pluralized-methods %} -

    Dos puntos (:) delanteros en el nombre de app.param(name, fn)

    +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    Dos puntos (:) delanteros en el nombre de app.param(name, fn)

    El carácter de dos puntos (:) delanteros en el nombre de la función `app.param(name, fn)` es un remanente de Express 3 y, a efectos de retrocompatibilidad, Express 4 le daba soporte con un aviso de obsolescencia. Express 5 lo ignorará de forma silenciosa y utilizará el parámetro de nombre sin añadir el prefijo de dos puntos. Esto no afectará al código si sigue la documentación de Express 4 de [app.param](/{{ page.lang }}/4x/api.html#app.param), ya que no hace ninguna referencia a los dos puntos delanteros. -

    req.param(name)

    +

    req.param(name)

    Este método potencialmente confuso y peligroso de recuperar datos de formulario se ha eliminado. No necesitará buscar específicamente el nombre de parámetro enviado en el objeto `req.params`, `req.body` o `req.query`. -

    res.json(obj, status)

    +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    Express 5 ya no da soporte a la firma `res.json(obj, status)`. En su lugar, establezca el estado y encadénelo al método `res.json()` de la siguiente manera: `res.status(status).json(obj)`. -

    res.jsonp(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    Express 5 ya no da soporte a la firma `res.jsonp(obj, status)`. En su lugar, establezca el estado y encadénelo al método `res.jsonp()` de la siguiente manera: `res.status(status).jsonp(obj)`. -

    res.send(body, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    Express 5 ya no da soporte a la firma `res.send(obj, status)`. En su lugar, establezca el estado y encadénelo al método `res.send()` de la siguiente manera: `res.status(status).send(obj)`. -

    res.send(status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    + +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. -Express 5 ya no da soporte a la firma res.send(status), donde *`status`* es un número. En su lugar, utilice la función `res.sendStatus(statusCode)`, que establece el código de estado de la cabecera de respuesta HTTP y envía la versión de texto del código: "Not Found", "Internal Server Error", etc. +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    + +Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) + +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` + +

    res.send(status)

    + +Express 5 ya no da soporte a la firma res.send(status), donde _`status`_ es un número. En su lugar, utilice la función `res.sendStatus(statusCode)`, que establece el código de estado de la cabecera de respuesta HTTP y envía la versión de texto del código: "Not Found", "Internal Server Error", etc. Si necesita enviar un número utilizando la función `res.send()`, escríbalo entre comillas para convertirlo en una serie, para que Express no lo interprete como un intento de utilizar la firma antigua no soportada. -

    res.sendfile()

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) + +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

    res.sendfile()

    La función `res.sendfile()` se ha sustituido por una versión de la función `res.sendFile()` con cada palabra en mayúscula en Express 5. -

    Modificados

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: -

    app.router

    +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. Está en desuso desde v4.11.0 y Express 5 ya no le da soporte. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## Modificados + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. For example: + +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +For example: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    El objeto `app.router`, que se ha eliminado en Express 4, ha vuelto en Express 5. En la nueva versión, este objeto es sólo una referencia al direccionador de Express base, a diferencia de en Express 3, donde una aplicación debía cargarlo explícitamente. -

    req.host

    +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    + +En Express 4, la función `req.host` fragmentaba incorrectamente el número de puerto si estaba presente. In Express 5, the port number is maintained. -En Express 4, la función `req.host` fragmentaba incorrectamente el número de puerto si estaba presente. En Express 5, el número de puerto se mantiene. +

    req.query

    -

    req.query

    +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -De Express 4.7 y Express 5 en adelante, la opción de analizador de consultas puede aceptar `false` para inhabilitar el análisis de series de consulta si desea utilizar su propia función para la lógica de análisis de series de consulta. +

    res.clearCookie

    -

    Mejoras

    +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. -

    res.render()

    +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## Improvements + +

    res.render()

    Este método ahora impone un comportamiento asíncrono para todos los motores de vistas, lo que evita los errores provocados por los motores de vistas que tenían una implementación síncrona e incumplían la interfaz recomendada. + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/es/guide/overriding-express-api.md b/es/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/es/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/es/guide/routing.md b/es/guide/routing.md old mode 100755 new mode 100644 index 37bf648739..2b476f03e4 --- a/es/guide/routing.md +++ b/es/guide/routing.md @@ -1,269 +1,326 @@ --- layout: page title: Direccionamiento de Express +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: es +redirect_from: " " --- # Direccionamiento -*Direccionamiento* hace referencia a la definición de puntos finales de aplicación (URI) y cómo responden a las solicitudes de cliente. +_Direccionamiento_ hace referencia a la definición de puntos finales de aplicación (URI) y cómo responden a las solicitudes de cliente. Para ver una introducción al direccionamiento, consulte [Direccionamiento básico](/{{ page.lang }}/starter/basic-routing.html). -El siguiente código es un ejemplo de una ruta muy básica. +You define routing using methods of the Express `app` object that correspond to HTTP methods; +for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). -
    -
    -var express = require('express');
    -var app = express();
    +These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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 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
    +to the next callback.
    +
    +The following code is an example of a very basic route.
    +
    +```js
    +const express = require('express')
    +const app = express()
     
     // respond with "hello world" when a GET request is made to the homepage
    -app.get('/', function(req, res) {
    -  res.send('hello world');
    -});
    -
    -
    +app.get('/', (req, res) => { + res.send('hello world') +}) +``` -

    Métodos de ruta

    +

    Route methods

    -Un método de ruta se deriva de uno de los métodos HTTP y se adjunta a una instancia de la clase `express`. +A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class. El siguiente código es un ejemplo de las rutas que se definen para los métodos GET y POST a la raíz de la aplicación. -
    -
    +```js
     // GET method route
    -app.get('/', function (req, res) {
    -  res.send('GET request to the homepage');
    -});
    +app.get('/', (req, res) => {
    +  res.send('GET request to the homepage')
    +})
     
     // POST method route
    -app.post('/', function (req, res) {
    -  res.send('POST request to the homepage');
    -});
    -
    -
    +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` -Express da soporte a los siguientes métodos de direccionamiento que se corresponden con los métodos HTTP: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search` y `connect`. +Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). -
    -Para direccionar los métodos que se convierten en nombres de variable JavaScript no válidos, utilice la notación entre corchetes. Por ejemplo, `app['m-search']('/', function ...` -
    +Hay un método de direccionamiento especial, `app.all()`, que no se deriva de ningún método HTTP. Este método se utiliza para cargar funciones de middleware en una vía de acceso para todos los métodos de solicitud. En el siguiente ejemplo, el manejador se ejecutará para las solicitudes a "/secret", tanto si utiliza GET, POST, PUT, DELETE, como cualquier otro método de solicitud HTTP soportado en el [módulo http](https://nodejs.org/api/http.html#http_http_methods). -Hay un método de direccionamiento especial, `app.all()`, que no se deriva de ningún método HTTP. Este método se utiliza para cargar funciones de middleware en una vía de acceso para todos los métodos de solicitud. - -En el siguiente ejemplo, el manejador se ejecutará para las solicitudes a "/secret", tanto si utiliza GET, POST, PUT, DELETE, como cualquier otro método de solicitud HTTP soportado en el [módulo http](https://nodejs.org/api/http.html#http_http_methods). - -
    -
    -app.all('/secret', function (req, res, next) {
    -  console.log('Accessing the secret section ...');
    -  next(); // pass control to the next handler
    -});
    -
    -
    +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +```

    Vías de acceso de ruta

    Las vías de acceso de ruta, en combinación con un método de solicitud, definen los puntos finales en los que pueden realizarse las solicitudes. Las vías de acceso de ruta pueden ser series, patrones de serie o expresiones regulares. -
    - Express utiliza [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) para correlacionar las vías de acceso de ruta; consulte la documentación de path-to-regexp para ver todas las posibilidades para definir vías de acceso de ruta. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) es una herramienta muy útil para probar rutas básicas de Express, aunque no da soporte a la coincidencia de patrones. -
    +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
    -Las series de consulta no forman parte de la vía de acceso de ruta. -
    +{% include admonitions/caution.html content=caution-character %} + +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} + +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) es una herramienta muy útil para probar rutas básicas de Express, aunque no da soporte a la coincidencia de patrones. + +{% endcapture %} + +{% include admonitions/note.html content=note-path-to-regexp %} -Estos son algunos ejemplos de vías de acceso de ruta basadas en series. +{% capture query-string-note %} + +Query strings are not part of the route path. + +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### Route paths based on strings Esta vía de acceso de ruta coincidirá con las solicitudes a la ruta raíz, `/`. -
    -
    -app.get('/', function (req, res) {
    -  res.send('root');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` Esta vía de acceso de ruta coincidirá con las solicitudes a `/about`. -
    -
    -app.get('/about', function (req, res) {
    -  res.send('about');
    -});
    -
    -
    +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` Esta vía de acceso de ruta coincidirá con las solicitudes a `/random.text`. -
    -
    -app.get('/random.text', function (req, res) {
    -  res.send('random.text');
    -});
    -
    -
    +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` -Estos son algunos ejemplos de vías de acceso de ruta basadas en patrones de serie. +### Route paths based on string patterns + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} + +{% include admonitions/caution.html content=caution-string-patterns %} Esta vía de acceso de ruta coincidirá con `acd` y `abcd`. -
    -
    -app.get('/ab?cd', function(req, res) {
    -  res.send('ab?cd');
    -});
    -
    -
    +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` Esta vía de acceso de ruta coincidirá con `abcd`, `abbcd`, `abbbcd`, etc. -
    -
    -app.get('/ab+cd', function(req, res) {
    -  res.send('ab+cd');
    -});
    -
    -
    +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` Esta vía de acceso de ruta coincidirá con `abcd`, `abxcd`, `abRABDOMcd`, `ab123cd`, etc. -
    -
    -app.get('/ab*cd', function(req, res) {
    -  res.send('ab*cd');
    -});
    -
    -
    +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` Esta vía de acceso de ruta coincidirá con `/abe` y `/abcde`. -
    -
    -app.get('/ab(cd)?e', function(req, res) {
    - res.send('ab(cd)?e');
    -});
    -
    -
    - -
    -Los caracteres ?, +, * y () son subconjuntos de sus contrapartidas de expresiones regulares. El guión (-) y el punto (.) se interpretan literalmente en las vías de acceso basadas en series. -
    +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` -Ejemplos de vías de acceso de ruta basadas en expresiones regulares: +### Ejemplos de vías de acceso de ruta basadas en expresiones regulares: Esta vía de acceso de ruta coincidirá con cualquier valor con una "a" en el nombre de la ruta. -
    -
    -app.get(/a/, function(req, res) {
    -  res.send('/a/');
    -});
    -
    -
    +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` Esta vía de acceso de ruta coincidirá con `butterfly` y `dragonfly`, pero no con `butterflyman`, `dragonfly man`, etc. -
    -
    -app.get(/.*fly$/, function(req, res) {
    -  res.send('/.*fly$/');
    -});
    -
    -
    +```js +app.get(/.*fly$/, (req, res) => { + res.send('/.*fly$/') +}) +``` + +

    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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
    +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +
    + +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. + +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` + +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` + +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): + +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` + +{% capture escape-advisory %} + +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. -

    Manejadores de rutas

    +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %} + +

    Route handlers

    Puede proporcionar varias funciones de devolución de llamada que se comportan como [middleware](/{{ page.lang }}/guide/using-middleware.html) para manejar una solicitud. La única excepción es que estas devoluciones de llamada pueden invocar `next('route')` para omitir el resto de las devoluciones de llamada de ruta. Puede utilizar este mecanismo para imponer condiciones previas en una ruta y, a continuación, pasar el control a las rutas posteriores si no hay motivo para continuar con la ruta actual. Los manejadores de rutas pueden tener la forma de una función, una matriz de funciones o combinaciones de ambas, como se muestra en los siguientes ejemplos. -Una función de devolución de llamada individual puede manejar una ruta. Por ejemplo: - -
    -
    -app.get('/example/a', function (req, res) {
    -  res.send('Hello from A!');
    -});
    -
    -
    - -Más de una función de devolución de llamada puede manejar una ruta (asegúrese de especificar el objeto `next`). Por ejemplo: - -
    -
    -app.get('/example/b', function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from B!');
    -});
    -
    -
    - -Una matriz de funciones de devolución de llamada puede manejar una ruta. Por ejemplo: - -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +Una función de devolución de llamada individual puede manejar una ruta. For example:
    +
    +```js
    +app.get('/example/a', (req, res) => {
    +  res.send('Hello from A!')
    +})
    +```
    +
    +Más de una función de devolución de llamada puede manejar una ruta (asegúrese de especificar el objeto `next`). For example:
    +
    +```js
    +app.get('/example/b', (req, res, next) => {
    +  console.log('the response will be sent by the next function ...')
    +  next()
    +}, (req, res) => {
    +  res.send('Hello from B!')
    +})
    +```
    +
    +Una matriz de funciones de devolución de llamada puede manejar una ruta. For example:
    +
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -var cb2 = function (req, res) {
    -  res.send('Hello from C!');
    +const cb2 = function (req, res) {
    +  res.send('Hello from C!')
     }
     
    -app.get('/example/c', [cb0, cb1, cb2]);
    -
    -
    +app.get('/example/c', [cb0, cb1, cb2]) +``` -Una combinación de funciones independientes y matrices de funciones puede manejar una ruta. Por ejemplo: +Una combinación de funciones independientes y matrices de funciones puede manejar una ruta. For example: -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/d', [cb0, cb1], function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from D!');
    -});
    -
    -
    +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +``` -

    Métodos de respuesta

    +

    Response methods

    Los métodos en el objeto de respuesta (`res`) de la tabla siguiente pueden enviar una respuesta al cliente y terminar el ciclo de solicitud/respuestas. Si ninguno de estos métodos se invoca desde un manejador de rutas, la solicitud de cliente se dejará colgada. -| Método | Descripción -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Solicita un archivo para descargarlo. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Finaliza el proceso de respuesta. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Envía una respuesta JSON. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Envía una respuesta JSON con soporte JSONP. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirecciona una solicitud. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Representa una plantilla de vista. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Envía una respuesta de varios tipos. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Envía un archivo como una secuencia de octetos. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Establece el código de estado de la respuesta y envía su representación de serie como el cuerpo de respuesta. +| Method | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Solicita un archivo para descargarlo. | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Finaliza el proceso de respuesta. | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Envía una respuesta JSON. | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Send a JSON response with JSONP support. | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirecciona una solicitud. | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Representa una plantilla de vista. | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Envía una respuesta de varios tipos. | +| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Envía un archivo como una secuencia de octetos. | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Establece el código de estado de la respuesta y envía su representación de serie como el cuerpo de respuesta. |

    app.route()

    @@ -272,20 +329,18 @@ Como la vía de acceso se especifica en una única ubicación, la creación de r A continuación, se muestra un ejemplo de manejadores de rutas encadenados que se definen utilizando `app.route()`. -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    + .put((req, res) => { + res.send('Update the book') + }) +```

    express.Router

    @@ -295,37 +350,43 @@ El siguiente ejemplo crea un direccionador como un módulo, carga una función d Cree un archivo de direccionador denominado `birds.js` en el directorio de la aplicación, con el siguiente contenido: -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const router = express.Router()
     
     // middleware that is specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +const timeLog = (req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +}
    +router.use(timeLog)
    +
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` A continuación, cargue el módulo de direccionador en la aplicación: -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +const birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` La aplicación ahora podrá manejar solicitudes a `/birds` y `/birds/about`, así como invocar 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 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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/es/guide/using-middleware.md b/es/guide/using-middleware.md old mode 100755 new mode 100644 index 14e131cd1b..dda450f2c6 --- a/es/guide/using-middleware.md +++ b/es/guide/using-middleware.md @@ -1,263 +1,257 @@ --- layout: page title: Utilización del middleware de Express +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: es +redirect_from: " " --- # Utilización del middleware Express es una infraestructura web de direccionamiento y middleware que tiene una funcionalidad mínima propia: una aplicación Express es fundamentalmente una serie de llamadas a funciones de middleware. -Las funciones de *middleware* son funciones que tienen acceso al [objeto de solicitud](/{{ page.lang }}/4x/api.html#req) (`req`), al [objeto de respuesta](/{{ page.lang }}/4x/api.html#res) (`res`) y a la siguiente función de middleware en el ciclo de solicitud/respuestas de la aplicación. La siguiente función de middleware se denota normalmente con una variable denominada `next`. +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the next middleware function in the application's request-response cycle. La siguiente función de middleware se denota normalmente con una variable denominada `next`. Las funciones de middleware pueden realizar las siguientes tareas: -* Ejecutar cualquier código. -* Realizar cambios en la solicitud y los objetos de respuesta. -* Finalizar el ciclo de solicitud/respuestas. -* Invocar la siguiente función de middleware en la pila. +- Execute any code. +- Realizar cambios en la solicitud y los objetos de respuesta. +- Finalizar el ciclo de solicitud/respuestas. +- Invocar la siguiente función de middleware en la pila. -Si la función de middleware actual no finaliza el ciclo de solicitud/respuestas, debe invocar `next()` para pasar el control a la siguiente función de middleware. De lo contrario, la solicitud quedará colgada. +Si la función de middleware actual no finaliza el ciclo de solicitud/respuestas, debe invocar `next()` para pasar el control a la siguiente función de middleware. Otherwise, the request will be left hanging. -Una aplicación Express puede utilizar los siguientes tipos de middleware: +An Express application can use the following types of middleware: - - [Middleware de nivel de aplicación](#middleware.application) - - [Middleware de nivel de direccionador](#middleware.router) - - [Middleware de manejo de errores](#middleware.error-handling) - - [Middleware incorporado](#middleware.built-in) - - [Middleware de terceros](#middleware.third-party) +- [Application-level middleware](#middleware.application) +- [Middleware de nivel de direccionador](#middleware.router) +- [Error-handling middleware](#middleware.error-handling) +- [Built-in middleware](#middleware.built-in) +- [Third-party middleware](#middleware.third-party) Puede cargar middleware de nivel de aplicación y de nivel de direccionador con una vía de acceso de montaje opcional. También puede cargar una serie de funciones de middleware a la vez, lo que crea una subpila del sistema de middleware en un punto de montaje. -

    Middleware de nivel de aplicación

    +

    Application-level middleware

    -Enlace el middleware de nivel de aplicación a una instancia del [objeto de aplicación](/{{ page.lang }}/4x/api.html#app) utilizando las funciones `app.use()` y `app.METHOD()`, donde `METHOD` es el método HTTP de la solicitud que maneja la función de middleware (por ejemplo, GET, PUT o POST) en minúsculas. +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. -Este ejemplo muestra una función de middleware sin ninguna vía de acceso de montaje. La función se ejecuta cada vez que la aplicación recibe una solicitud. +Este ejemplo muestra una función de middleware sin ninguna vía de acceso de montaje. The function is executed every time the app receives a request. -
    -
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    -
    -
    +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` Este ejemplo muestra una función de middleware montada en la vía de acceso `/user/:id`. La función se ejecuta para cualquier tipo de solicitud HTTP en la vía de acceso `/user/:id`. -
    -
    -app.use('/user/:id', function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Este ejemplo muestra una ruta y su función de manejador (sistema de middleware). La función maneja las solicitudes GET a la vía de acceso `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  res.send('USER');
    -});
    -
    -
    +```js +app.get('/user/:id', (req, res, next) => { + res.send('USER') +}) +``` A continuación, se muestra un ejemplo de carga de una serie de funciones de middleware en un punto de montaje, con una vía de acceso de montaje. Ilustra una subpila de middleware que imprime información de solicitud para cualquier tipo de solicitud HTTP en la vía de acceso `/user/:id`. -
    -
    -app.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Los manejadores de rutas permiten definir varias rutas para una vía de acceso. El ejemplo siguiente define dos rutas para las solicitudes GET a la vía de acceso `/user/:id`. La segunda ruta no dará ningún problema, pero nunca se invocará, ya que la primera ruta finaliza el ciclo de solicitud/respuestas. Este ejemplo muestra una subpila de middleware que maneja solicitudes GET a la vía de acceso `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -}, function (req, res, next) {
    -  res.send('User Info');
    -});
    +```js
    +app.get('/user/:id', (req, res, next) => {
    +  console.log('ID:', req.params.id)
    +  next()
    +}, (req, res, next) => {
    +  res.send('User Info')
    +})
     
     // handler for the /user/:id path, which prints the user ID
    -app.get('/user/:id', function (req, res, next) {
    -  res.end(req.params.id);
    -});
    -
    -
    +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) +}) +``` Para omitir el resto de las funciones de middleware de una pila de middleware de direccionador, invoque `next('route')` para pasar el control a la siguiente ruta. -**NOTA**: `next('route')` sólo funcionará en las funciones de middleware que se hayan cargado utilizando las funciones `app.METHOD()` o `router.METHOD()`. + +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} Este ejemplo muestra una subpila de middleware que maneja solicitudes GET a la vía de acceso `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    +```js
    +app.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next route
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass the control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    -  // render a regular page
    -  res.render('regular');
    -});
    +  else next()
    +}, (req, res, next) => {
    +  // send a regular response
    +  res.send('regular')
    +})
     
    -// handler for the /user/:id path, which renders a special page
    -app.get('/user/:id', function (req, res, next) {
    -  res.render('special');
    -});
    -
    -
    +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +A continuación, se muestra un ejemplo de uso de la función de middleware `express.static` con un objeto de opciones elaboradas: + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

    Middleware de nivel de direccionador

    El middleware de nivel de direccionador funciona de la misma manera que el middleware de nivel de aplicación, excepto que está enlazado a una instancia de `express.Router()`. -
    -
    -var router = express.Router();
    -
    -
    +```js +const router = express.Router() +``` + Cargue el middleware de nivel de direccionador utilizando las funciones `router.use()` y `router.METHOD()`. El siguiente código de ejemplo replica el sistema de middleware que se ha mostrado anteriormente para el middleware de nivel de aplicación, utilizando el middleware de nivel de direccionador: -
    -
    -var app = express();
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const app = express()
    +const router = express.Router()
     
     // a middleware function with no mount path. This code is executed for every request to the router
    -router.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time:', Date.now())
    +  next()
    +})
     
     // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    -router.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    +router.use('/user/:id', (req, res, next) => {
    +  console.log('Request URL:', req.originalUrl)
    +  next()
    +}, (req, res, next) => {
    +  console.log('Request Type:', req.method)
    +  next()
    +})
     
     // a middleware sub-stack that handles GET requests to the /user/:id path
    -router.get('/user/:id', function (req, res, next) {
    +router.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next router
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    +  else next()
    +}, (req, res, next) => {
       // render a regular page
    -  res.render('regular');
    -});
    +  res.render('regular')
    +})
     
     // handler for the /user/:id path, which renders a special page
    -router.get('/user/:id', function (req, res, next) {
    -  console.log(req.params.id);
    -  res.render('special');
    -});
    +router.get('/user/:id', (req, res, next) => {
    +  console.log(req.params.id)
    +  res.render('special')
    +})
     
     // mount the router on the app
    -app.use('/', router);
    -
    -
    +app.use('/', router) +``` -

    Middleware de manejo de errores

    - -
    -El middleware de manejo de errores siempre utiliza *cuatro* argumentos. Debe proporcionar cuatro argumentos para identificarlo como una función de middleware de manejo de errores. Aunque no necesite utilizar el objeto `next`, debe especificarlo para mantener la firma. De lo contrario, el objeto `next` se interpretará como middleware normal y no podrá manejar errores. -
    - -Defina las funciones de middleware de manejo de errores de la misma forma que otras funciones de middleware, excepto con cuatro argumentos en lugar de tres, específicamente con la firma `(err, req, res, next)`: - -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +Para obtener más detalles sobre la función `serve-static` y sus opciones, consulte la documentación de [serve-static](https://github.com/expressjs/serve-static). -Para obtener detalles sobre el middleware de manejo de errores, consulte: [Manejo de errores](/{{ page.lang }}/guide/error-handling.html). +Este ejemplo muestra una subpila de middleware que maneja solicitudes GET a la vía de acceso `/user/:id`. -

    Middleware incorporado

    +```js +const express = require('express') +const app = express() +const router = express.Router() -Desde la versión 4.x, Express ya no depende de [Connect](https://github.com/senchalabs/connect). Excepto `express.static`, todas las funciones de middleware que se incluían previamente con Express están ahora en módulos diferentes. Consulte [la lista de funciones de middleware](https://github.com/senchalabs/connect#middleware). +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) -

    express.static(root, [options])

    +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) -La única función de middleware incorporado en Express es `express.static`. Esta función se basa en [serve-static](https://github.com/expressjs/serve-static) y es responsable del servicio de activos estáticos de una aplicación Express. +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +``` -El argumento `root` especifica el directorio raíz desde el que se realiza el servicio de activos estáticos. +

    Error-handling middleware

    -El objeto `options` opcional puede tener las siguientes propiedades: +
    +El middleware de manejo de errores siempre utiliza *cuatro* argumentos. Debe proporcionar cuatro argumentos para identificarlo como una función de middleware de manejo de errores. Aunque no necesite utilizar el objeto `next`, debe especificarlo para mantener la firma. De lo contrario, el objeto `next` se interpretará como middleware normal y no podrá manejar errores. +
    -| Propiedad | Descripción | Tipo | Valor predeterminado | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | Opción para el servicio de dotfiles. Los valores posibles son "allow", "deny" e "ignore" | Serie | "ignore" | -| `etag` | Habilitar o inhabilitar la generación de etag | Booleano | `true` | -| `extensions` | Establece las reservas de extensiones de archivos. | Matriz | `[]` | -| `index` | Envía el archivo de índices de directorios. Establézcalo en `false` para inhabilitar la indexación de directorios. | Mixto | "index.html" | - `lastModified` | Establezca la cabecera `Last-Modified` en la última fecha de modificación del archivo en el sistema operativo. Los valores posibles son `true` o `false`. | Booleano | `true` | -| `maxAge` | Establezca la propiedad max-age de la cabecera Cache-Control en milisegundos o una serie en [formato ms](https://www.npmjs.org/package/ms) | Número | 0 | -| `redirect` | Redireccionar a la "/" final cuando el nombre de vía de acceso es un directorio. | Booleano | `true` | -| `setHeaders` | Función para establecer las cabeceras HTTP que se sirven con el archivo. | Función | | +Defina las funciones de middleware de manejo de errores de la misma forma que otras funciones de middleware, excepto con cuatro argumentos en lugar de tres, específicamente con la firma `(err, req, res, next)`: -A continuación, se muestra un ejemplo de uso de la función de middleware `express.static` con un objeto de opciones elaboradas: +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` -
    -
    -var options = {
    -  dotfiles: 'ignore',
    -  etag: false,
    -  extensions: ['htm', 'html'],
    -  index: false,
    -  maxAge: '1d',
    -  redirect: false,
    -  setHeaders: function (res, path, stat) {
    -    res.set('x-timestamp', Date.now());
    -  }
    -}
    +Para obtener detalles sobre el middleware de manejo de errores, consulte: [Manejo de errores](/{{ page.lang }}/guide/error-handling.html).
     
    -app.use(express.static('public', options));
    -
    -
    +

    Built-in middleware

    -Puede tener más de un directorio estático para cada aplicación: +Desde la versión 4.x, Express ya no depende de [Connect](https://github.com/senchalabs/connect). Excepto `express.static`, todas las funciones de middleware que se incluían previamente con Express están ahora en módulos diferentes. Consulte [la lista de funciones de middleware](https://github.com/senchalabs/connect#middleware). -
    -
    -app.use(express.static('public'));
    -app.use(express.static('uploads'));
    -app.use(express.static('files'));
    -
    -
    +La única función de middleware incorporado en Express es `express.static`. -Para obtener más detalles sobre la función `serve-static` y sus opciones, consulte la documentación de [serve-static](https://github.com/expressjs/serve-static). +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** -

    Middleware de terceros

    +

    Third-party middleware

    Utilice el middleware de terceros para añadir funcionalidad a las aplicaciones Express. @@ -265,21 +259,17 @@ Instale el módulo Node.js para la funcionalidad necesaria y cárguelo en la apl El siguiente ejemplo ilustra la instalación y carga de la función de middleware de análisis de cookies `cookie-parser`. -
    -
    +```bash
     $ npm install cookie-parser
    -
    -
    +``` -
    -
    -var express = require('express');
    -var app = express();
    -var cookieParser = require('cookie-parser');
    +```js
    +const express = require('express')
    +const app = express()
    +const cookieParser = require('cookie-parser')
     
     // load the cookie-parsing middleware
    -app.use(cookieParser());
    -
    -
    +app.use(cookieParser()) +``` Para ver una lista parcial de las funciones de middleware de terceros que más se utilizan con Express, consulte: [Middleware de terceros](../resources/middleware.html). diff --git a/es/guide/using-template-engines.md b/es/guide/using-template-engines.md old mode 100755 new mode 100644 index 25ee957d1d..795f89fa08 --- a/es/guide/using-template-engines.md +++ b/es/guide/using-template-engines.md @@ -1,61 +1,65 @@ --- layout: page title: Utilización de motores de plantilla con Express +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: es +redirect_from: " " --- # Utilización de motores de plantilla con Express -Para que Express pueda representar archivos de plantilla, deben establecerse los siguientes valores de aplicación: +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +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. -* `views`, el directorio donde se encuentran los archivos de plantilla. Ejemplo: `app.set('views', './views')` -* `view engine`, el motor de plantilla que se utiliza. Ejemplo: `app.set('view engine', 'pug')` +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. + +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: + +- `views`, el directorio donde se encuentran los archivos de plantilla. Ejemplo: `app.set('views', './views')` + This defaults to the `views` directory in the application root directory. +- `view engine`, el motor de plantilla que se utiliza. Ejemplo: `app.set('view engine', 'pug')` A continuación, instale el paquete npm de motor de plantilla correspondiente: -
    -
    +```bash
     $ npm install pug --save
    -
    -
    +```
    -Los motores de plantilla compatibles con Express como, por ejemplo, Pug exportan una función denominada `__express(filePath, options, callback)`, que es invocada por la función `res.render()` para representar el código de plantilla. +Express-compliant template engines such as Pug export a function named `__express(filePath, options, callback)`, +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. -Algunos motores de plantilla no siguen esta convención. La biblioteca [Consolidate.js](https://www.npmjs.org/package/consolidate) sigue esta convención correlacionando todos los motores de plantilla de Node.js más conocidos, por lo que funciona de forma ininterrumpida en Express.
    -Una vez establecida la propiedad view engine, no tiene que especificar el motor ni cargar el módulo de motor de plantilla en la aplicación; Express carga el módulo internamente, como se muestra a continuación (para el ejemplo anterior). +After the view engine is set, you don't have to specify the engine or load the template engine module in your app; +Express loads the module internally, for example: -
    -
    -app.set('view engine', 'pug');
    -
    -
    +```js +app.set('view engine', 'pug') +``` Cree un archivo de plantilla Pug denominado `index.pug` en el directorio `views`, con el siguiente contenido: -
    -
    +```pug
     html
       head
         title= title
       body
         h1= message
    -
    -
    +``` A continuación, cree una ruta para representar el archivo `index.pug`. Si la propiedad `view engine` no se establece, debe especificar la extensión del archivo `view`. De lo contrario, puede omitirla. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` Cuando realice una solicitud a la página de inicio, el archivo `index.pug` se representará como HTML. -Para obtener más información sobre cómo funcionan los motores de plantilla en Express, consulte: ["Desarrollo de motores de plantilla para Express"](/{{ page.lang }}/advanced/developing-template-engines.html). +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/es/guide/writing-middleware.md b/es/guide/writing-middleware.md old mode 100755 new mode 100644 index ab354305ae..2c5a6aa1af --- a/es/guide/writing-middleware.md +++ b/es/guide/writing-middleware.md @@ -1,33 +1,35 @@ --- layout: page title: Escritura de middleware para su uso en aplicaciones Express +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: es +redirect_from: " " --- # Escritura de middleware para su uso en aplicaciones Express -

    Visión general

    +

    Overview

    -Las funciones de *middleware* son funciones que tienen acceso al [objeto de solicitud](/{{ page.lang }}/4x/api.html#req) (`req`), al [objeto de respuesta](/{{ page.lang }}/4x/api.html#res) (`res`) y a la siguiente función de middleware en el ciclo de solicitud/respuestas de la aplicación. La siguiente función de middleware se denota normalmente con una variable denominada `next`. +Las funciones de _middleware_ son funciones que tienen acceso al [objeto de solicitud](/{{ page.lang }}/4x/api.html#req) (`req`), al [objeto de respuesta](/{{ page.lang }}/4x/api.html#res) (`res`) y a la siguiente función de middleware en el ciclo de solicitud/respuestas de la aplicación. La siguiente función de middleware se denota normalmente con una variable denominada `next`. Las funciones de middleware pueden realizar las siguientes tareas: -* Ejecutar cualquier código. -* Realizar cambios en la solicitud y los objetos de respuesta. -* Finalizar el ciclo de solicitud/respuestas. -* Invocar el siguiente middleware en la pila. +- Execute any code. +- Realizar cambios en la solicitud y los objetos de respuesta. +- Finalizar el ciclo de solicitud/respuestas. +- Invocar el siguiente middleware en la pila. -Si la función de middleware actual no finaliza el ciclo de solicitud/respuestas, debe invocar `next()` para pasar el control a la siguiente función de middleware. De lo contrario, la solicitud quedará colgada. +Si la función de middleware actual no finaliza el ciclo de solicitud/respuestas, debe invocar `next()` para pasar el control a la siguiente función de middleware. Otherwise, the request will be left hanging. El siguiente ejemplo muestra los elementos de una llamada a función de middleware: +
    -
    Vía de acceso (ruta) para la que se aplica la función de middleware.
    @@ -39,65 +41,67 @@ El siguiente ejemplo muestra los elementos de una llamada a función de middlewa
    Argumento de solicitud HTTP a la función de middleware, denominado "req" por convención.
    -
    - +
    +Elements of a middleware function call -
    Método HTTP para el que se aplica la función de middleware.
    +
    Método HTTP para el que se aplica la función de middleware.
    + +
    -A continuación, se muestra un ejemplo de una aplicación Express simple, "Hello World", para la que definirá dos funciones de middleware: +Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error. -
    -
    -var express = require('express');
    -var app = express();
    +

    + +A continuación, se muestra un ejemplo de una aplicación Express simple, "Hello World", para la que definirá dos funciones de middleware: +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. -app.get('/', function (req, res) { - res.send('Hello World!'); -}); +```js +const express = require('express') +const app = express() -app.listen(3000); -
    -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -

    Desarrollo

    +app.listen(3000) +``` +

    Middleware function myLogger

    Este es un ejemplo simple de una función de middleware denominada "myLogger". Esta función simplemente imprime "LOGGED" cuando una solicitud de la aplicación pasa por ella. La función de middleware se asigna a una variable denominada `myLogger`. -
    -
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    -
    -
    +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
    -Observe la llamada anterior a `next()`. La llamada a esta función invoca la siguiente función de middleware en la aplicación. -La función `next()` no forma parte de la API de Express o Node.js, pero es el tercer argumento que se pasa a la función de middleware. La función `next()` puede tener cualquier nombre, pero por convención siempre se denomina "next". Para evitar confusiones, utilice siempre esta convención. +Observe la llamada anterior a `next()`. La llamada a esta función invoca la siguiente función de middleware en la aplicación. +La función `next()` no forma parte de la API de Express o Node.js, pero es el tercer argumento que se pasa a la función de middleware. La función `next()` puede tener cualquier nombre, pero por convención siempre se denomina "next". +Para evitar confusiones, utilice siempre esta convención.
    Para cargar la función de middleware, llame a `app.use()`, especificando la función de middleware. Por ejemplo, el siguiente código carga la función de middleware `myLogger` antes de la ruta a la vía de acceso raíz (/). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    +const myLogger = function (req, res, next) {
    +  console.log('LOGGED')
    +  next()
    +}
     
    -app.use(myLogger);
    +app.use(myLogger)
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    +app.listen(3000) +``` -Cada vez que la aplicación recibe una solicitud, imprime el mensaje "LOGGED" en el terminal. +Every time the app receives a request, it prints the message "LOGGED" to the terminal. El orden de carga del middleware es importante: las funciones de middleware que se cargan primero también se ejecutan primero. @@ -105,43 +109,112 @@ Si `myLogger` se carga después de la ruta a la vía de acceso raíz, la solicit La función de middleware `myLogger` simplemente imprime un mensaje y, a continuación, pasa la solicitud a la siguiente función de middleware de la pila llamando a la función `next()`. +

    Middleware function requestTime

    + El siguiente ejemplo añade una propiedad denominada `requestTime` al objeto de solicitud. Llamaremos a esta función de middleware "requestTime". -
    -
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    -
    -
    +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` -La aplicación ahora utiliza la función de middleware `requestTime`. Asimismo, la función de devolución de llamada de la ruta de vía de acceso raíz utiliza la propiedad que la función de middleware añade a `req` (el objeto de solicitud). +The app now uses the `requestTime` middleware function. Asimismo, la función de devolución de llamada de la ruta de vía de acceso raíz utiliza la propiedad que la función de middleware añade a `req` (el objeto de solicitud). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    +const requestTime = function (req, res, next) {
    +  req.requestTime = Date.now()
    +  next()
    +}
     
    -app.use(requestTime);
    +app.use(requestTime)
     
    -app.get('/', function (req, res) {
    -  var responseText = 'Hello World!
    '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) -app.listen(3000); -
    -
    +app.listen(3000) +``` Cuando realiza una solicitud a la raíz de la aplicación, la aplicación ahora muestra la indicación de fecha y hora de la solicitud en el navegador. +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    + Como tiene acceso al objeto de solicitud, el objeto de respuesta, la siguiente función de middleware de la pila y toda la API de Node.js, las posibilidades con las funciones de middleware son ilimitadas. Para obtener más información sobre el middleware de Express, consulte: [Utilización del middleware de Express](/{{ page.lang }}/guide/using-middleware.html). + +

    Configurable middleware

    + +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. + +File: `my-middleware.js` + +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` + +The middleware can now be used as shown below. + +```js +const mw = require('./my-middleware.js') + +app.use(mw({ option1: '1', option2: '2' })) +``` + +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/es/index.md b/es/index.md index dfc8d53b42..a5ed8a6700 100644 --- a/es/index.md +++ b/es/index.md @@ -1,52 +1,59 @@ --- layout: home -title: Express - Infraestructura de aplicaciones web Node.js +title: Express - Node.js Marco de aplicación web +description: "Express es un marco web rápido, sin opinión y minimalista para Node.js, que proporciona un robusto conjunto de características para aplicaciones web y móviles." menu: home -lang: es +redirect_from: " " --- +
    - {% include header/header-{{ page.lang }}.html %} -
    - - Infraestructura web rápida, minimalista y flexible para Node.js + +

    Marco web rápido, sin opinión y minimalista para Node.js

    -
    $ npm install express --save
    -
    -
    - +
    $ npm install express --save
    -
    - +
    -
    - -
    -
    -

    Aplicaciones web

    Express es una infraestructura de aplicaciones web Node.js mínima y flexible que proporciona un conjunto sólido de características para las aplicaciones web y móviles. -
    +```javascript +const express = require('express') +const app = express() +const port = 3000 -
    -

    API

    Con miles de métodos de programa de utilidad HTTP y middleware a su disposición, la creación de una API sólida es rápida y sencilla. -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -
    -

    Rendimiento

    Express proporciona una delgada capa de características de aplicación web básicas, que no ocultan las características de Node.js que tanto ama y conoce. -
    +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` -
    -
    - diff --git a/es/resources/community.md b/es/resources/community.md old mode 100755 new mode 100644 index a861674376..6229f75f82 --- a/es/resources/community.md +++ b/es/resources/community.md @@ -1,34 +1,85 @@ --- layout: page title: Comunidad de Express +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: es +redirect_from: " " --- # Comunidad -## Lista de envío de correos +## Technical committee -Únase a más de 2000 usuarios de Express o explore más de 5000 discusiones en [Google Group](https://groups.google.com/group/express-js). +El comité técnico de Express se reúne en línea cada dos semanas (según sea necesario) para discutir el desarrollo y el mantenimiento de Express, entre otros problemas relevantes para el proyecto Express. Cada reunión se anuncia normalmente en un [problema de expressjs/discussions](https://github.com/expressjs/discussions/issues) con un enlace para unirse o ver la reunión, que está abierta a todos los observadores. -## Gitter +Las reuniones son grabadas; para ver la lista de las grabaciones, consulte el [canal de YouTube de Express.js](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -La [sala de conversación expressjs/express](https://gitter.im/expressjs/express) es un excelente recurso para los desarrolladores interesados en las discusiones diarias relacionadas con Express. +Los miembros del comité técnico de Express son: -## Canal de IRC +**Activos:** -Cientos de desarrolladores añaden comentarios en #express en Freenode cada día. -Si tiene preguntas sobre la infraestructura, entre para realizar consultas rápidas. +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida -## Ejemplos +**Inactivos:** -Vea docenas de [ejemplos](https://github.com/expressjs/express/tree/master/examples) de aplicaciones Express en el repositorio, que van desde la autenticación y el diseño de API hasta la integración del motor de plantillas. +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode -## Problemas +## Express is made of many modules -Si se encuentra con lo que cree es un error o simplemente desea realizar una solicitud de característica, abra un ticket en la [cola de problemas](https://github.com/expressjs/express/issues). +Nuestra vibrante comunidad ha creado una larga variedad de extensiones, [módulos intermedios](/{{ page.lang }}/resources/middleware.html) y frameworks de nivel superior. -## Terceros +Además, la comunidad de Express mantiene módulos en estas dos organizaciones de GitHub: -Nuestra vibrante comunidad ha creado una gran variedad de extensiones, [módulos de middleware](/{{ page.lang }}/resources/middleware.html) e infraestructuras de nivel superior. Investíguelos en la [wiki](https://github.com/expressjs/express/wiki). +- [jshttp](https://jshttp.github.io/): módulos que proporcionan funciones utilitarias útiles; consulte [Módulos de utilidad](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): módulos de bajo nivel que Express utiliza internamente. +Para mantenerse al tanto de lo que está sucediendo en toda la comunidad, consulte [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). + +## Issues + +Si ha encontrado lo que cree que es un error, o simplemente quiere hacer una solicitud de función, abre un ticket en la [cola de problemas](https://github.com/expressjs/express/issues). + +## Examples + +Mire docenas de [ejemplos](https://github.com/expressjs/express/tree/master/examples) de aplicaciones Express en el repositorio que cubren todo, desde el diseño y la autenticación de API hasta la integración del motor de plantillas. + +## Discusiones de Github + +La sección de [Discusiones de GitHub](https://github.com/expressjs/discussions) es un excelente espacio para participar en conversaciones sobre el desarrollo y mantenimiento de Express, así como para compartir ideas y debatir temas relacionados con su uso. + +# Branding of Express.js + +## Logo de Express.js + +Express is a project of the OpenJS Foundation. Por favor, revise la [política de marcas registradas](https://trademark-policy.openjsf.org/) para obtener información sobre el uso permitido de los logotipos y marcas de Express.js. + +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logo de Marca

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/es/resources/contributing.md b/es/resources/contributing.md new file mode 100644 index 0000000000..f0e9f55836 --- /dev/null +++ b/es/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contribuir a Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contribuir a Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/es/resources/glossary.md b/es/resources/glossary.md old mode 100755 new mode 100644 index 829b81758d..28a33ad4a9 --- a/es/resources/glossary.md +++ b/es/resources/glossary.md @@ -1,31 +1,24 @@ --- layout: page title: Glosario de Express +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: es +redirect_from: " " --- # Glosario -### API - -Interfaz de programación de aplicaciones. Explique la abreviatura la primera vez que la utilice. - -### aplicación +### application En general, uno o varios programas diseñados para realizar operaciones para un determinado propósito. En el contexto de Express, un programa que utiliza la API de Express que se ejecuta en la plataforma Node.js. También puede hacer referencia a un [objeto de aplicación](/{{ page.lang }}/api.html#express). -### código abierto - -Consulte [Open source software en la Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). - -### direccionador +### API -Consulte [direccionador](/{{ page.lang }}/4x/api.html#router) en la referencia de API. +Application programming interface. Explique la abreviatura la primera vez que la utilice. ### Express -Una infraestructura web rápida, minimalista y flexible para las aplicaciones Node.js. En general, se prefiere "Express" a "Express.js", aunque esta también se acepta. +Una infraestructura web rápida, minimalista y flexible para las aplicaciones Node.js. En general, se prefiere "Express" a "Express.js", aunque esta también se acepta. ### libuv @@ -33,24 +26,40 @@ Una biblioteca de soporte multiplataforma que se centra en la E/S asíncrona, de ### middleware -Una función invocada por la capa de direccionamiento de Express antes del manejador de la última solicitud, por lo que se sitúa en medio de una solicitud sin formato y la última ruta prevista. Algunos puntos delicados de terminología relacionados con el middleware: +Una función invocada por la capa de direccionamiento de Express antes del manejador de la última solicitud, por lo que se sitúa en medio de una solicitud sin formato y la última ruta prevista. Algunos puntos delicados de terminología relacionados con el middleware: - * `var foo = require('middleware')` significa que *requiere* o *utiliza* un módulo Node.js. A continuación, la sentencia `var mw = foo()` normalmente devuelve el middleware. - * `app.use(mw)` significa que *se añade el middleware a la pila de procesos global*. - * `app.get('/foo', mw, function (req, res) { ... })` significa que *se añade el middleware a la pila de procesos "GET /foo"*. +- `var foo = require('middleware')` significa que _requiere_ o _utiliza_ un módulo Node.js. A continuación, la sentencia `var mw = foo()` normalmente devuelve el middleware. +- `app.use(mw)` significa que _se añade el middleware a la pila de procesos global_. +- `app.get('/foo', mw, function (req, res) { ... })` significa que _se añade el middleware a la pila de procesos "GET /foo"_. ### Node.js -Una plataforma de software que se utiliza para crear aplicaciones de red escalables. Node.js utiliza JavaScript como lenguaje de script y consigue un elevado rendimiento mediante E/S sin bloqueo y un bucle de sucesos de una sola hebra. Consulte [nodejs.org](http://nodejs.org/). **Nota de uso**: inicialmente, "Node.js", posteriormente "Node". +Una plataforma de software que se utiliza para crear aplicaciones de red escalables. Node.js utiliza JavaScript como lenguaje de script y consigue un elevado rendimiento mediante E/S sin bloqueo y un bucle de sucesos de una sola hebra. Consulte [nodejs.org](http://nodejs.org/). **Nota de uso**: inicialmente, "Node.js", posteriormente "Node". + +### Consulte [Open source software en la Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). -### respuesta +When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). -Una respuesta HTTP. Un servidor devuelve un mensaje de respuesta HTTP al cliente. La respuesta contiene información de estado de finalización sobre la solicitud y también puede contener contenido de la solicitud en el cuerpo del mensaje. +{% capture english-rules %} -### ruta +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. -Parte de un URL que identifica un recurso. Por ejemplo, en `http://foo.com/products/id`, "/products/id" es la ruta. +{% endcapture %} -### solicitud +{% include admonitions/note.html content=english-rules %} -Una solicitud HTTP. Un cliente envía un mensaje de solicitud HTTP a un servidor, que devuelve una respuesta. La solicitud debe utilizar uno de los [métodos de solicitud](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) como, por ejemplo, GET, POST, etc. +### request + +Una solicitud HTTP. Un cliente envía un mensaje de solicitud HTTP a un servidor, que devuelve una respuesta. La solicitud debe utilizar uno de los [métodos de solicitud](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) como, por ejemplo, GET, POST, etc. + +### response + +An HTTP response. A server returns an HTTP response message to the client. La respuesta contiene información de estado de finalización sobre la solicitud y también puede contener contenido de la solicitud en el cuerpo del mensaje. + +### route + +Parte de un URL que identifica un recurso. For example, in `http://foo.com/products/id`, "/products/id" is the route. + +### router + +Consulte [direccionador](/{{ page.lang }}/4x/api.html#router) en la referencia de API. diff --git a/es/resources/learning.md b/es/resources/learning.md deleted file mode 100755 index df8b5952d8..0000000000 --- a/es/resources/learning.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: Aprendizaje adicional -menu: resources -lang: es ---- - -# Aprendizaje adicional - -
    Disclaimer: Unendorsed community content.
    - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/es/resources/middleware.md b/es/resources/middleware.md old mode 100755 new mode 100644 index 746f0d5fb8..7a3516311b --- a/es/resources/middleware.md +++ b/es/resources/middleware.md @@ -1,64 +1,43 @@ --- -layout: page +layout: middleware title: Middleware de Express +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: es +redirect_from: " " +module: mw-home --- -# Middleware de terceros +## Middleware de Express Estos son algunos módulos de middleware de Express: - - [body-parser](https://github.com/expressjs/body-parser): anteriormente `express.bodyParser`, `json` y `urlencoded`. - Vea también: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): anteriormente `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): módulos de middleware de Connect/Express para el servicio óptimo de imágenes. Cambia las imágenes a `.webp` o `.jxr`, si es posible. - - [connect-timeout](https://github.com/expressjs/timeout): anteriormente `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): anteriormente `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): anteriormente `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): anteriormente `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): anteriormente `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): herramienta de desarrollo discreta que añade a la aplicación un separador con información sobre las variables de plantilla (locals), la sesión actual, datos de solicitud útiles, etc. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): módulo de middleware de Express middleware para filtrar partes de las respuestas JSON basándose en la serie de consulta `fields`; utiliza la respuesta parcial de la API de Google. - - [express-session](https://github.com/expressjs/session): anteriormente `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): módulo de middleware de Express para utilizar una CDN (Red de entrega de contenido) para los activos estáticos, con soporte de varios hosts (por ejemplo, cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): módulo de middleware de Express para aquellos que son estrictos sobre las barras inclinadas finales. - - [express-stormpath](https://github.com/stormpath/stormpath-express): módulo de middleware de Express para el almacenamiento de usuario, la autenticación, la autorización, SSO y la seguridad de datos. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): módulo de middleware para redirigir las solicitudes que contienen mayúsculas a un formato en minúsculas canónico. - - [helmet](https://github.com/helmetjs/helmet): módulo para ayudar a proteger las aplicaciones estableciendo varias cabeceras HTTP. - - [join-io](https://github.com/coderaiser/join-io "join-io"): módulo para unir archivos sobre la marcha para reducir el recuento de solicitudes. - - [method-override](https://github.com/expressjs/method-override): anteriormente `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): anteriormente `logger` - - [passport](https://github.com/jaredhanson/passport): módulo de middleware de Express para la autenticación. - - [response-time](https://github.com/expressjs/response-time): anteriormente `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): anteriormente `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): anteriormente `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): módulo para el servicio de contenido estático. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): cabeceras de almacenamiento en memoria caché o URL de firma digital para activos estáticos, incluido el soporte para uno o varios dominios externos. - - [vhost](https://github.com/expressjs/vhost): anteriormente `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): módulo de middleware de Express que proporciona métodos de ayudante comunes a las vistas. - - [sriracha-admin](https://github.com/hdngr/siracha): módulo de middleware de Express que genera dinámicamente un sitio de administración para Mongoose. +| [express-slash](https://github.com/ericf/express-slash): módulo de middleware de Express para aquellos que son estrictos sobre las barras inclinadas finales. | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | -Algunos módulos de middleware incluidos previamente con Connect ya no están soportados por el equipo de Connect/Express. Estos módulos se han sustituido por un módulo alternativo o deben reemplazarse por un módulo mejor. Utilice una de las siguientes alternativas: +## Para ver más módulo de middleware, consulte: - - express.cookieParser - - [cookies](https://github.com/jed/cookies) y [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) +These are some additional popular middleware modules. -Para ver más módulo de middleware, consulte: +{% include community-caveat.html %} - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| [express-slash](https://github.com/ericf/express-slash): módulo de middleware de Express para aquellos que son estrictos sobre las barras inclinadas finales. | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet): módulo para ayudar a proteger las aplicaciones estableciendo varias cabeceras HTTP. | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport): módulo de middleware de Express para la autenticación. | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/es/resources/middleware/body-parser.md b/es/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/es/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/es/resources/middleware/compression.md b/es/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/es/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/es/resources/middleware/connect-rid.md b/es/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/es/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/es/resources/middleware/cookie-parser.md b/es/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/es/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/es/resources/middleware/cookie-session.md b/es/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/es/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/es/resources/middleware/cors.md b/es/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/es/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/es/resources/middleware/errorhandler.md b/es/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/es/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/es/resources/middleware/method-override.md b/es/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/es/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/es/resources/middleware/morgan.md b/es/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/es/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/es/resources/middleware/multer.md b/es/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/es/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/es/resources/middleware/response-time.md b/es/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/es/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/es/resources/middleware/serve-favicon.md b/es/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/es/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/es/resources/middleware/serve-index.md b/es/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/es/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/es/resources/middleware/serve-static.md b/es/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/es/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/es/resources/middleware/session.md b/es/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/es/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/es/resources/middleware/timeout.md b/es/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/es/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/es/resources/middleware/vhost.md b/es/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/es/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/es/resources/utils.md b/es/resources/utils.md new file mode 100644 index 0000000000..f58beb26e1 --- /dev/null +++ b/es/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/es/starter/basic-routing.md b/es/starter/basic-routing.md old mode 100755 new mode 100644 index 168b6b410d..121a304189 --- a/es/starter/basic-routing.md +++ b/es/starter/basic-routing.md @@ -1,26 +1,26 @@ --- layout: page title: Direccionamiento básico de Express +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: es +redirect_from: " " --- # Direccionamiento básico -El *direccionamiento* hace referencia a la determinación de cómo responde una aplicación a una solicitud de cliente en un determinado punto final, que es un URI (o una vía de acceso) y un método de solicitud HTTP específico (GET, POST, etc.). +El _direccionamiento_ hace referencia a la determinación de cómo responde una aplicación a una solicitud de cliente en un determinado punto final, que es un URI (o una vía de acceso) y un método de solicitud HTTP específico (GET, POST, etc.). Cada ruta puede tener una o varias funciones de manejador, que se excluyen cuando se correlaciona la ruta. -La definición de ruta tiene la siguiente estructura: -
    -
    +Route definition takes the following structure:
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` -Donde: +Where: -- `app` es una instancia de `express`. +- `app` is an instance of `express`. - `METHOD` es un [método de solicitud HTTP](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol). - `PATH` es una vía de acceso en el servidor. - `HANDLER` es la función que se ejecuta cuando se correlaciona la ruta. @@ -33,42 +33,36 @@ El siguiente ejemplo ilustra la definición de rutas simples. Responda con `Hello World!` en la página inicial: -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -Responda a la solicitud POST en la ruta raíz (`/`), la página de inicio de la aplicación: +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` Responda a una solicitud PUT en la ruta `/user`: -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` Responda a una solicitud DELETE en la ruta `/user`: -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` Para obtener más detalles sobre el direccionamiento, consulte la [guía de direccionamiento](/{{ page.lang }}/guide/routing.html). + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/es/starter/examples.md b/es/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/es/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/es/starter/faq.md b/es/starter/faq.md old mode 100755 new mode 100644 index c794f1cc71..2bfbfc4b40 --- a/es/starter/faq.md +++ b/es/starter/faq.md @@ -1,25 +1,26 @@ --- layout: page title: Preguntas más frecuentes sobre Express +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: es +redirect_from: " " --- # Preguntas más frecuentes -## ¿Cómo debo estructurar mi aplicación? +## How should I structure my application? -No hay una respuesta definitiva a esta pregunta. La respuesta depende de la escala de la aplicación y del equipo implicado. Para ser lo más flexible posible, Express no realiza suposiciones en cuanto a la estructura. +There is no definitive answer to this question. La respuesta depende de la escala de la aplicación y del equipo implicado. Para ser lo más flexible posible, Express no realiza suposiciones en cuanto a la estructura. Las rutas y otra lógica específica de la aplicación puede residir en tantos archivos como desee, con la estructura de directorios que prefiera. Vea los siguientes ejemplos como inspiración: -* [Listas de rutas](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Correlación de rutas](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [Controladores de estilo MVC](https://github.com/expressjs/express/tree/master/examples/mvc) +- [Listas de rutas](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [Correlación de rutas](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [Controladores de estilo MVC](https://github.com/expressjs/express/tree/master/examples/mvc) Asimismo, hay extensiones de terceros para Express, que simplifican algunos de estos patrones: -* [express-resource](https://github.com/expressjs/express-resource) +- [express-resource](https://github.com/expressjs/express-resource) ## ¿Cómo debo definir los modelos? @@ -29,39 +30,39 @@ Consulte [LoopBack](http://loopback.io) para ver una infraestructura basada en E ## ¿Cómo puedo autenticar los usuarios? -La autenticación es otra área rígida en la que no entra Express. Puede utilizar el esquema de autenticación que desee. +La autenticación es otra área rígida en la que no entra Express. Puede utilizar el esquema de autenticación que desee. Para ver un esquema simple de nombre de usuario/contraseña, consulte [este ejemplo](https://github.com/expressjs/express/tree/master/examples/auth). - ## ¿A qué motor de plantilla da soporte Express? Express da soporte a cualquier motor de plantilla que cumpla la firma `(path, locals, callback)`. Para normalizar las interfaces de motor de plantilla y el almacenamiento en memoria caché, consulte el proyecto [consolidate.js](https://github.com/visionmedia/consolidate.js) para ver el soporte. Otros motores de plantilla que no aparezcan en la lista también pueden dar soporte a la firma de Express. -## ¿Cómo puedo manejar las respuestas 404? +For more information, see [Using template engines with Express](/{{page.lang}}/guide/using-template-engines.html). + +## How do I handle 404 responses? En Express, las respuestas 404 no son el resultado de un error, por lo que el middleware de manejador de errores no las capturará. Este comportamiento se debe a que una respuesta 404 simplemente indica la ausencia de trabajo adicional pendiente; es decir, Express ha ejecutado todas las rutas y funciones de middleware, y ha comprobado que ninguna de ellas responde. Lo único que debe hacer es añadir una función de middleware al final de la pila (debajo de las demás funciones) para manejar una respuesta 404: -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` + +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## ¿Cómo configuro un manejador de errores? El middleware de manejo de errores se define de la misma forma que otro middleware, excepto con cuatro argumentos en lugar de tres; específicamente con la firma `(err, req, res, next)`: -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Para obtener más información, consulte [Manejo de errores](/{{ page.lang }}/guide/error-handling.html). @@ -70,3 +71,10 @@ Para obtener más información, consulte [Manejo de errores](/{{ page.lang }}/gu De ninguna manera. No es necesario "representar" HTML con la función `res.render()`. Si tiene un archivo específico, utilice la función `res.sendFile()`. Para el servicio de muchos activos desde un directorio, utilice la función de middleware `express.static()`. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/es/starter/generator.md b/es/starter/generator.md old mode 100755 new mode 100644 index 1e1677eccb..51f17576ca --- a/es/starter/generator.md +++ b/es/starter/generator.md @@ -1,29 +1,34 @@ --- layout: page title: Generador de aplicaciones Express +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: es +redirect_from: " " --- # Generador de aplicaciones Express Utilice la herramienta de generador de aplicaciones, `express`, para crear rápidamente un esqueleto de aplicación. -Instale `express` con el siguiente mandato: +You can run the application generator with the `npx` command (available in Node.js 8.2.0). -
    -
    -$ npm install express-generator -g
    -
    -
    +```bash +$ npx express-generator +``` + +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` Muestre las opciones de mandato con la opción `-h`: -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -34,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` Por ejemplo, el código siguiente crea una aplicación Express denominada _myapp_. La aplicación será creada en una carpeta llamada _myapp_ en el directorio de trabajo actual y el motor de vistas será asignado a Pug: -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -64,40 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` A continuación, instale las dependencias: -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` En MacOS o Linux, ejecute la aplicación con este mandato: -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` En Windows, utilice este mandato: -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` + +On Windows PowerShell, use this command: + +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` A continuación, cargue `http://localhost:3000/` en el navegador para acceder a la aplicación. -La aplicación generada tiene la siguiente estructura de directorios: +The generated app has the following directory structure: -
    -
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -117,9 +118,10 @@ La aplicación generada tiene la siguiente estructura de directorios:
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    La estructura de la aplicación creada por el generador es sólo una de las muchas formas de estructurar las aplicaciones Express. Puede utilizar esta estructura o modificarla según sus necesidades.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/es/starter/hello-world.md b/es/starter/hello-world.md old mode 100755 new mode 100644 index 59ed037967..0e4959c30e --- a/es/starter/hello-world.md +++ b/es/starter/hello-world.md @@ -1,8 +1,9 @@ --- layout: page title: Ejemplo "Hello World" de Express +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: es +redirect_from: " " --- # Ejemplo Hello world @@ -11,12 +12,7 @@ lang: es Esta es básicamente la aplicación Express más sencilla que puede crear. Es una aplicación de archivo simple — *no* lo que obtendrá si utiliza el [generador de Express](/{{ page.lang }}/starter/generator.html), que crea el andamiaje para una aplicación completa con varios archivos JavaScript, plantillas Jade y subdirectorios para distintos propósitos.
    -En primer lugar, cree un directorio denominado `myapp`, cámbielo y ejecute `npm init`. A continuación, instale `express` como una dependencia, según se describe en la [guía de instalación](/{{ page.lang }}/starter/installing.html). - -En el directorio `myapp`, cree un archivo denominado `app.js` y añada el código siguiente: - -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -26,12 +22,17 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    -
    +``` + +La aplicación inicia un servidor y escucha las conexiones en el puerto 3000. La aplicación responde con "Hello World!" para las solicitudes al URL raíz (`/`) o a la _ruta_ raíz. Para cada vía de acceso diferente, responderá con un error **404 Not Found**. -La aplicación inicia un servidor y escucha las conexiones en el puerto 3000. La aplicación responde con "Hello World!" para las solicitudes al URL raíz (`/`) o a la *ruta* raíz. Para cada vía de acceso diferente, responderá con un error **404 Not Found**. +### Ejecutando localmente + +En primer lugar, cree un directorio denominado `myapp`, cámbielo y ejecute `npm init`. A continuación, instale `express` como una dependencia, según se describe en la [guía de instalación](/{{ page.lang }}/starter/installing.html). + +En el directorio `myapp`, cree un archivo denominado `app.js` y añada el código siguiente:
    `req` (solicitud) y `res` (respuesta) son exactamente los mismos objetos que proporciona Node, por lo que puede invocar `req.pipe()`, `req.on('data', callback)` y cualquier otro objeto que invocaría sin estar Express implicado. @@ -39,11 +40,10 @@ La aplicación inicia un servidor y escucha las conexiones en el puerto 3000. La Ejecute la aplicación con el siguiente mandato: -
    -
    +```bash
     $ node app.js
    -
    -
    +``` A continuación, cargue [http://localhost:3000/](http://localhost:3000/) en un navegador para ver la salida. +### [Previous: Installing ](/{{ page.lang }}/starter/installing.html)    [Next: Express Generator ](/{{ page.lang }}/starter/generator.html) diff --git a/es/starter/installing.md b/es/starter/installing.md old mode 100755 new mode 100644 index d6eff3a43e..bdb23dcd26 --- a/es/starter/installing.md +++ b/es/starter/installing.md @@ -1,58 +1,53 @@ --- layout: page title: Instalación de Express +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: es +redirect_from: " " --- # Instalación Suponiendo que ya ha instalado [Node.js](https://nodejs.org/), cree un directorio para que contenga la aplicación y conviértalo en el directorio de trabajo. -
    -
    +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher.
    +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher.
    +
    +```bash
     $ mkdir myapp
     $ cd myapp
    -
    -
    +``` Utilice el mandato `npm init` para crear un archivo `package.json` para la aplicación. Para obtener más información sobre cómo funciona `package.json`, consulte [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). -
    -
    +```bash
     $ npm init
    -
    -
    +``` Este mandato solicita varios elementos como, por ejemplo, el nombre y la versión de la aplicación. Por ahora, sólo tiene que pulsar INTRO para aceptar los valores predeterminados para la mayoría de ellos, con la siguiente excepción: -
    -
    +```
     entry point: (index.js)
    -
    -
    +``` Especifique `app.js` o el nombre que desee para el archivo principal. Si desea que sea `index.js`, pulse INTRO para aceptar el nombre de archivo predeterminado recomendado. -A continuación, instale Express en el directorio `myapp` y guárdelo en la lista de dependencias. Por ejemplo: +A continuación, instale Express en el directorio `myapp` y guárdelo en la lista de dependencias. For example: -
    -
    -$ npm install express --save
    -
    -
    +```bash +$ npm install express +``` Para instalar Express temporalmente y no añadirlo a la lista de dependencias, omita la opción `--save`: -
    -
    -$ npm install express
    -
    -
    +```bash +$ npm install express --no-save +```
    -Los módulos de Node que se instalan con la opción `--save` se añaden a la lista `dependencies` en el archivo `package.json`. -Posteriormente, si ejecuta `npm install` en el directorio `app`, los módulos se instalarán automáticamente en la lista de dependencias. +Los módulos de Node que se instalan con la opción `--save` se añaden a la lista `dependencies` en el archivo `package.json`. Posteriormente, si ejecuta `npm install` en el directorio `app`, los módulos se instalarán automáticamente en la lista de dependencias.
    + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/es/starter/static-files.md b/es/starter/static-files.md old mode 100755 new mode 100644 index 5ed90da9c9..52274ad4a9 --- a/es/starter/static-files.md +++ b/es/starter/static-files.md @@ -1,33 +1,39 @@ --- layout: page title: Servicio de archivos estáticos en Express +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: es +redirect_from: " " --- # Servicio de archivos estáticos en Express Para el servicio de archivos estáticos como, por ejemplo, imágenes, archivos CSS y archivos JavaScript, utilice la función de middleware incorporado `express.static` de Express. -Pase el nombre del directorio que contiene los activos estáticos a la función de middleware `express.static` para empezar directamente el servicio de los archivos. Por ejemplo, utilice el siguiente código para el servicio de imágenes, archivos CSS y archivos JavaScript en un directorio denominado `public`: +The function signature is: -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +Por ejemplo, utilice el siguiente código para el servicio de imágenes, archivos CSS y archivos JavaScript en un directorio denominado `public`: + +```js +app.use(express.static('public')) +``` Ahora, puede cargar los archivos que hay en el directorio `public`: -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +```
    Express busca los archivos relativos al directorio estático, por lo que el nombre del directorio estático no forma parte del URL. @@ -35,39 +41,41 @@ Express busca los archivos relativos al directorio estático, por lo que el nomb Para utilizar varios directorios de activos estáticos, invoque la función de middleware `express.static` varias veces: -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` Express busca los archivos en el orden en el que se definen los directorios estáticos con la función de middleware `express.static`. -Para crear un prefijo de vía de acceso virtual (donde la vía de acceso no existe realmente en el sistema de archivos) para los archivos a los que da servicio la función `express.static`, [especifique una vía de acceso de montaje](/{{ page.lang }}/4x/api.html#app.use) para el directorio estático, como se muestra a continuación: +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` Ahora, puede cargar los archivos que hay en el directorio `public` desde el prefijo de vía de acceso `/static`. -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` No obstante, la vía de acceso que proporciona a la función `express.static` es relativa al directorio desde donde inicia el proceso `node`. Si ejecuta la aplicación Express desde cualquier otro directorio, es más seguro utilizar la vía de acceso absoluta del directorio al que desea dar servicio: -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +```js +const path = require('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.html). + +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/es/support/index.md b/es/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/es/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/feed.xml b/feed.xml new file mode 100644 index 0000000000..d5d8b9fcea --- /dev/null +++ b/feed.xml @@ -0,0 +1,10 @@ +--- +layout: feed +sitemap: false +title: Express Blog +html_url: /en/blog/posts.html +--- +{% assign posts = site.posts | sort: "date" | reverse %} +{% for post in posts %} +{% include feed-entry.xml entry=post %} +{% endfor %} diff --git a/fonts/FontAwesome.otf b/fonts/FontAwesome.otf deleted file mode 100644 index 81c9ad949b..0000000000 Binary files a/fonts/FontAwesome.otf and /dev/null differ diff --git a/fonts/fontawesome-webfont.eot b/fonts/fontawesome-webfont.eot deleted file mode 100644 index 84677bc0c5..0000000000 Binary files a/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/fonts/fontawesome-webfont.svg b/fonts/fontawesome-webfont.svg deleted file mode 100644 index d907b25ae6..0000000000 --- a/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,520 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fonts/fontawesome-webfont.ttf b/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 96a3639cdd..0000000000 Binary files a/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/fonts/fontawesome-webfont.woff b/fonts/fontawesome-webfont.woff deleted file mode 100644 index 628b6a52a8..0000000000 Binary files a/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/fonts/ko/pretendard.css b/fonts/ko/pretendard.css new file mode 100644 index 0000000000..962feab7b2 --- /dev/null +++ b/fonts/ko/pretendard.css @@ -0,0 +1,71 @@ +/* +Copyright (c) 2021 Kil Hyung-jin, with Reserved Font Name Pretendard. +https://github.com/orioncactus/pretendard + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL +*/ + +@font-face { + font-family: 'Pretendard'; + font-weight: 900; + font-display: swap; + src: local('Pretendard Black'), url(./woff2/Pretendard-Black.woff2) format('woff2'), url(./woff/Pretendard-Black.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 800; + font-display: swap; + src: local('Pretendard ExtraBold'), url(./woff2/Pretendard-ExtraBold.woff2) format('woff2'), url(./woff/Pretendard-ExtraBold.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 700; + font-display: swap; + src: local('Pretendard Bold'), url(./woff2/Pretendard-Bold.woff2) format('woff2'), url(./woff/Pretendard-Bold.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 600; + font-display: swap; + src: local('Pretendard SemiBold'), url(./woff2/Pretendard-SemiBold.woff2) format('woff2'), url(./woff/Pretendard-SemiBold.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 500; + font-display: swap; + src: local('Pretendard Medium'), url(./woff2/Pretendard-Medium.woff2) format('woff2'), url(./woff/Pretendard-Medium.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 400; + font-display: swap; + src: local('Pretendard Regular'), url(./woff2/Pretendard-Regular.woff2) format('woff2'), url(./woff/Pretendard-Regular.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 300; + font-display: swap; + src: local('Pretendard Light'), url(./woff2/Pretendard-Light.woff2) format('woff2'), url(./woff/Pretendard-Light.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 200; + font-display: swap; + src: local('Pretendard ExtraLight'), url(./woff2/Pretendard-ExtraLight.woff2) format('woff2'), url(./woff/Pretendard-ExtraLight.woff) format('woff'); +} + +@font-face { + font-family: 'Pretendard'; + font-weight: 100; + font-display: swap; + src: local('Pretendard Thin'), url(./woff2/Pretendard-Thin.woff2) format('woff2'), url(./woff/Pretendard-Thin.woff) format('woff'); +} diff --git a/fonts/ko/woff/Pretendard-Black.woff b/fonts/ko/woff/Pretendard-Black.woff new file mode 100644 index 0000000000..d07848c81b Binary files /dev/null and b/fonts/ko/woff/Pretendard-Black.woff differ diff --git a/fonts/ko/woff/Pretendard-Bold.woff b/fonts/ko/woff/Pretendard-Bold.woff new file mode 100644 index 0000000000..7837ae52d8 Binary files /dev/null and b/fonts/ko/woff/Pretendard-Bold.woff differ diff --git a/fonts/ko/woff/Pretendard-ExtraBold.woff b/fonts/ko/woff/Pretendard-ExtraBold.woff new file mode 100644 index 0000000000..8058b76104 Binary files /dev/null and b/fonts/ko/woff/Pretendard-ExtraBold.woff differ diff --git a/fonts/ko/woff/Pretendard-ExtraLight.woff b/fonts/ko/woff/Pretendard-ExtraLight.woff new file mode 100644 index 0000000000..f9498d85aa Binary files /dev/null and b/fonts/ko/woff/Pretendard-ExtraLight.woff differ diff --git a/fonts/ko/woff/Pretendard-Light.woff b/fonts/ko/woff/Pretendard-Light.woff new file mode 100644 index 0000000000..2cad608276 Binary files /dev/null and b/fonts/ko/woff/Pretendard-Light.woff differ diff --git a/fonts/ko/woff/Pretendard-Medium.woff b/fonts/ko/woff/Pretendard-Medium.woff new file mode 100644 index 0000000000..537040914f Binary files /dev/null and b/fonts/ko/woff/Pretendard-Medium.woff differ diff --git a/fonts/ko/woff/Pretendard-Regular.woff b/fonts/ko/woff/Pretendard-Regular.woff new file mode 100644 index 0000000000..e3b3a3580b Binary files /dev/null and b/fonts/ko/woff/Pretendard-Regular.woff differ diff --git a/fonts/ko/woff/Pretendard-SemiBold.woff b/fonts/ko/woff/Pretendard-SemiBold.woff new file mode 100644 index 0000000000..682e7a4533 Binary files /dev/null and b/fonts/ko/woff/Pretendard-SemiBold.woff differ diff --git a/fonts/ko/woff/Pretendard-Thin.woff b/fonts/ko/woff/Pretendard-Thin.woff new file mode 100644 index 0000000000..d28e4486c7 Binary files /dev/null and b/fonts/ko/woff/Pretendard-Thin.woff differ diff --git a/fonts/ko/woff2/Pretendard-Black.woff2 b/fonts/ko/woff2/Pretendard-Black.woff2 new file mode 100644 index 0000000000..eafe683536 Binary files /dev/null and b/fonts/ko/woff2/Pretendard-Black.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-Bold.woff2 b/fonts/ko/woff2/Pretendard-Bold.woff2 new file mode 100644 index 0000000000..4d40a1ab89 Binary files /dev/null and b/fonts/ko/woff2/Pretendard-Bold.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-ExtraBold.woff2 b/fonts/ko/woff2/Pretendard-ExtraBold.woff2 new file mode 100644 index 0000000000..dcd57e757d Binary files /dev/null and b/fonts/ko/woff2/Pretendard-ExtraBold.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-ExtraLight.woff2 b/fonts/ko/woff2/Pretendard-ExtraLight.woff2 new file mode 100644 index 0000000000..e5104022b4 Binary files /dev/null and b/fonts/ko/woff2/Pretendard-ExtraLight.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-Light.woff2 b/fonts/ko/woff2/Pretendard-Light.woff2 new file mode 100644 index 0000000000..7f82fe8478 Binary files /dev/null and b/fonts/ko/woff2/Pretendard-Light.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-Medium.woff2 b/fonts/ko/woff2/Pretendard-Medium.woff2 new file mode 100644 index 0000000000..f8c743d603 Binary files /dev/null and b/fonts/ko/woff2/Pretendard-Medium.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-Regular.woff2 b/fonts/ko/woff2/Pretendard-Regular.woff2 new file mode 100644 index 0000000000..a9f62319b7 Binary files /dev/null and b/fonts/ko/woff2/Pretendard-Regular.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-SemiBold.woff2 b/fonts/ko/woff2/Pretendard-SemiBold.woff2 new file mode 100644 index 0000000000..4c6a32de1a Binary files /dev/null and b/fonts/ko/woff2/Pretendard-SemiBold.woff2 differ diff --git a/fonts/ko/woff2/Pretendard-Thin.woff2 b/fonts/ko/woff2/Pretendard-Thin.woff2 new file mode 100644 index 0000000000..6c9bc96040 Binary files /dev/null and b/fonts/ko/woff2/Pretendard-Thin.woff2 differ diff --git a/fonts/open-sans/fonts.css b/fonts/open-sans/fonts.css new file mode 100644 index 0000000000..b9f165eae3 --- /dev/null +++ b/fonts/open-sans/fonts.css @@ -0,0 +1,21 @@ +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 300 800; + font-display: swap; + src: local("Open Sans"), + url("./woff2/open-sans-latin-wght-normal.woff2") format("woff2-variations"), + url("./woff/OpenSans.woff") format("woff"); + unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; +} + +@font-face { + font-family: "Open Sans"; + font-style: italic; + font-weight: 300 800; + font-display: swap; + src: local("Open Sans"), + url("./woff2/open-sans-latin-wght-italic.woff2") format("woff2-variations"), + url("./woff/OpenSans-Italic.woff") format("woff"); + unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; +} diff --git a/fonts/open-sans/woff/OpenSans-Italic.woff b/fonts/open-sans/woff/OpenSans-Italic.woff new file mode 100644 index 0000000000..ba548c33fd Binary files /dev/null and b/fonts/open-sans/woff/OpenSans-Italic.woff differ diff --git a/fonts/open-sans/woff/OpenSans.woff b/fonts/open-sans/woff/OpenSans.woff new file mode 100644 index 0000000000..f03b4add70 Binary files /dev/null and b/fonts/open-sans/woff/OpenSans.woff differ diff --git a/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 b/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 new file mode 100644 index 0000000000..5d9194cd18 Binary files /dev/null and b/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 differ diff --git a/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 b/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 new file mode 100644 index 0000000000..4e8b905cec Binary files /dev/null and b/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 differ diff --git a/fonts/th/THSarabunNew.woff b/fonts/th/THSarabunNew.woff deleted file mode 100644 index 4cb4614088..0000000000 Binary files a/fonts/th/THSarabunNew.woff and /dev/null differ diff --git a/fr/3x/api.md b/fr/3x/api.md old mode 100755 new mode 100644 index a6f19389a8..f9232fe731 --- a/fr/3x/api.md +++ b/fr/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - Référence de l'API +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: fr +redirect_from: " " --- +
    **Express 3.x N'EST PLUS PRIS EN CHARGE** - Les problèmes de performances et de sécurité connus et inconnus n'ont pas été traités depuis la dernière mise à jour (1er août 2015). Il est fortement recommandé d'utiliser la dernière version d'Express. -
    - -

    API 3.x

    +Les problèmes de performances et de sécurité connus et inconnus n'ont pas été traités depuis la dernière mise à jour (1er août 2015). Il est fortement recommandé d'utiliser la dernière version d'Express. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
    - - {% include api/en/3x/res.md %} +

    API 3.x

    - - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %}
    diff --git a/fr/4x/api.md b/fr/4x/api.md old mode 100755 new mode 100644 index 42ed0c5ca6..e00fcb0a74 --- a/fr/4x/api.md +++ b/fr/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - Référence de l'API +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: fr +redirect_from: " " --- +

    API 4.x

    - - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
    diff --git a/fr/5x/api.md b/fr/5x/api.md new file mode 100644 index 0000000000..6790a048ed --- /dev/null +++ b/fr/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - Référence de l'API +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
    + +

    5.x API

    + +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
    diff --git a/fr/advanced/best-practice-performance.md b/fr/advanced/best-practice-performance.md old mode 100755 new mode 100644 index 9acbd99367..c02e5c9a73 --- a/fr/advanced/best-practice-performance.md +++ b/fr/advanced/best-practice-performance.md @@ -1,41 +1,48 @@ --- layout: page title: Meilleures pratiques en termes de performances pour l'utilisation d'Express en production +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: fr +redirect_from: " " --- # Meilleures pratiques en production : performances et fiabilité -## Présentation - Cet article traite des meilleures pratiques en termes de performances et de fiabilité pour les applications Express déployées en production. La présente rubrique s'inscrit clairement dans le concept "devops", qui couvre à la fois le développement traditionnel et l'exploitation. Ainsi, les informations se divisent en deux parties : -* [A faire dans votre code](#code) (partie développement, "dev"). -* [A faire dans votre environnement/configuration](#env) (partie exploitation, "ops"). - - +- Things to do in your code (the dev part): + - Utiliser le middleware pour exploiter les fichiers statiques + - [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://web.archive.org/web/20240000000000/https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) + - [Do logging correctly](#do-logging-correctly) + - Traiter correctement les exceptions +- [A faire dans votre environnement/configuration](#env) (partie exploitation, "ops"). + - Définir NODE_ENV sur "production" + - Vérifier que votre application redémarre automatiquement + - Exécuter votre application dans un cluster + - [Cache request results](#cache-request-results) + - Utilisation de StrongLoop PM avec un équilibreur de charge Nginx + - Encore mieux, utilisez un proxy inverse pour exploiter les fichiers statiques ; pour plus d'informations, voir [Utiliser un proxy inverse](#proxy). ## A faire dans votre code Les actions suivantes peuvent être réalisées dans votre code afin d'améliorer les performances de votre application : -* Utiliser la compression gzip -* Ne pas utiliser les fonctions synchrones -* Utiliser le middleware pour exploiter les fichiers statiques -* Procéder à une journalisation correcte -* Traiter correctement les exceptions +- Utiliser le middleware pour exploiter les fichiers statiques +- [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://web.archive.org/web/20240000000000/https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) +- [Do logging correctly](#do-logging-correctly) +- Traiter correctement les exceptions ### Utiliser la compression gzip La compression Gzip peut considérablement réduire la taille du corps de réponse et ainsi augmenter la vitesse d'une application Web. Utilisez le middleware [compression](https://www.npmjs.com/package/compression) pour la compression gzip dans votre application Express. Par exemple : ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` @@ -47,19 +54,11 @@ Les fonctions et les méthodes synchrones ralentissent le processus d'exécution Bien que Node et plusieurs modules mettent à disposition les versions synchrone et asynchrone de leurs fonctions, utilisez toujours la version asynchrone en production. L'utilisation d'une fonction synchrone n'est justifiée que lors du démarrage initial. -Si vous utilisez Node.js 4.0+ ou io.js 2.1.0+, vous pouvez utiliser l'option de ligne de commande `--trace-sync-io` pour imprimer un avertissement et une trace de pile chaque fois que votre application utilise une API synchrone. Bien entendu vous n'utiliserez pas réellement cette option en production, mais plutôt pour vérifier que votre code est prêt pour la phase production. Pour plus d'informations, voir [Weekly update for io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0). - -### Utiliser le middleware pour exploiter les fichiers statiques - -En développement, vous pouvez utiliser [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) pour exploiter les fichiers statiques. Ne l'utilisez toutefois pas en production, car cette fonction doit lire le système de fichiers pour chaque demande de fichier ; elle se heurterait à des temps d'attente importants qui affecteraient les performances globales de l'application. Notez que `res.sendFile()` n'est *pas* implémentée avec l'appel système [sendfile](http://linux.die.net/man/2/sendfile), qui la rendrait beaucoup plus efficace. - -Utilisez plutôt le middleware [serve-static](https://www.npmjs.com/package/serve-static) (ou tout middleware équivalent), qui est optimisé pour l'utilisation des fichiers dans les applications Express. - -Encore mieux, utilisez un proxy inverse pour exploiter les fichiers statiques ; pour plus d'informations, voir [Utiliser un proxy inverse](#proxy). +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. Bien entendu vous n'utiliserez pas réellement cette option en production, mais plutôt pour vérifier que votre code est prêt pour la phase production. Pour plus d'informations, voir [Weekly update for io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0). ### Procéder à une journalisation correcte -En règle générale, vous utilisez la journalisation à partir de votre application à deux fins : le débogage et la journalisation de l'activité de votre application (principalement tout le reste). L'utilisation de `console.log()` ou de `console.err()` pour imprimer des messages de journal sur le terminal est une pratique courante en développement. Cependant, [ces fonctions sont synchrones](https://nodejs.org/api/console.html#console_console_1) lorsque la destination est un terminal ou un fichier ; elles ne conviennent donc pas en production, à moins que vous ne dirigiez la sortie vers un autre programme. +En règle générale, vous utilisez la journalisation à partir de votre application à deux fins : le débogage et la journalisation de l'activité de votre application (principalement tout le reste). L'utilisation de `console.log()` ou de `console.err()` pour imprimer des messages de journal sur le terminal est une pratique courante en développement. 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. #### Pour le débogage @@ -67,9 +66,7 @@ Si vous utilisez la journalisation à des fins de débogage, utilisez un module #### Pour journaliser l'activité de votre application -Si vous journalisez l'activité de votre application (par exemple, pour suivre le trafic ou les appels API), utilisez une bibliothèque de journalisation telle que [Winston](https://www.npmjs.com/package/winston) ou [Bunyan](https://www.npmjs.com/package/bunyan) plutôt que d'utiliser `console.log()`. Pour obtenir une comparaison détaillée de ces deux bibliothèques, consultez l'article StrongLoop intitulé [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - - +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. ### Traiter correctement les exceptions @@ -77,32 +74,19 @@ Les applications Node plantent lorsqu'elles tombent sur une exception non interc Pour vérifier que vous traitez toutes les exceptions, procédez comme suit : -* [Utiliser try-catch](#try-catch) -* [Utiliser des promesses](#promises) +- [Utiliser try-catch](#try-catch) +- [Utiliser des promesses](#promises) Avant de s'immerger dans les rubriques qui suivent, il est conseillé de posséder des connaissances de base concernant le traitement des erreurs Node/Express, à savoir l'utilisation des rappels "error-first" et la propagation des erreurs dans le middleware. Node utilise la convention de "rappel error-first" pour renvoyer les erreurs issues des fonctions asynchrones, dans laquelle le premier paramètre de la fonction callback est l'objet error, suivi par les données de résultat dans les paramètres suivants. Pour n'indiquer aucune erreur, indiquez null comme premier paramètre. La fonction de rappel doit suivre la convention de rappel "error-first" de sorte à traiter l'erreur de manière significative. Dans Express, la meilleure pratique consiste à utiliser la fonction next() pour propager les erreurs via la chaîne du middleware. Pour plus d'informations sur les bases du traitement des erreurs, voir : -* [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (blogue StrongLoop) - -#### A ne pas faire - -Vous ne devriez *pas* écouter l'événement `uncaughtException`, émis lorsqu'une exception remonte vers la boucle d'événements. L'ajout d'un programme d'écoute d'événement pour `uncaughtException` va modifier le comportement par défaut du processus qui rencontre une exception ; le processus va continuer à s'exécuter malgré l'exception. Cela pourrait être un bon moyen d'empêcher votre application de planter, mais continuer à exécuter l'application après une exception non interceptée est une pratique dangereuse qui n'est pas recommandée, étant donné que l'état du processus devient peu fiable et imprévisible. - -De plus, l'utilisation d'`uncaughtException` est officiellement reconnue comme étant [rudimentaire](https://nodejs.org/api/process.html#process_event_uncaughtexception) et il a été [proposé](https://github.com/nodejs/node-v0.x-archive/issues/2582) de le supprimer. Ecouter `uncaughtException` n'est qu'une mauvaise idée. Voilà pourquoi nous recommandons d'utiliser plusieurs processus et superviseurs à la place : faire planter son application et la redémarrer est souvent plus sûr que de la restaurer après une erreur. - -L'utilisation de [domain](https://nodejs.org/api/domain.html) n'est également pas recommandée. Ce module obsolète ne résout globalement pas le problème. - - +- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### Utiliser try-catch Try-catch est un élément de langage JavaScript que vous pouvez utiliser pour intercepter les exceptions dans le code synchrone. Utilisez try-catch pour traiter les erreurs d'analyse JSON, comme indiqué ci-dessous, par exemple. -Utilisez un outil tel que [JSHint](http://jshint.com/) ou [JSLint](http://www.jslint.com/) pour vous aider à identifier les exceptions implicites comme les [erreurs de référence dans les variables non définies](http://www.jshint.com/docs/options/#undef). - Voici un exemple d'utilisation de try-catch pour traiter une exception potentielle de plantage de processus. Cette fonction middleware accepte un paramètre de zone de requête nommé "params" qui est un objet JSON. @@ -110,9 +94,9 @@ Cette fonction middleware accepte un paramètre de zone de requête nommé "para app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -123,107 +107,84 @@ app.get('/search', (req, res) => { Toutefois, try-catch ne fonctionne que dans le code synchrone. Etant donné que la plateforme Node est principalement asynchrone (en particulier dans un environnement de production), try-catch n'interceptera pas beaucoup d'exceptions. - - #### Utiliser des promesses -Les promesses vont traiter n'importe quelle exception (explicite et implicite) dans les blocs de code asynchrone qui utilisent `then()`. Contentez-vous d'ajouter `.catch(next)` à la fin des chaînes de promesse. Par exemple : +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -Toutes les erreurs asynchrones et synchrones sont à présent propagées vers le middleware de traitement des erreurs. - -Observez toutefois les deux avertissements suivants : - -1. L'intégralité de votre code asynchrone doit renvoyer des promesses (à l'exception des émetteurs). Si une bibliothèque spécifique ne renvoie pas de promesses, convertissez l'objet de base à l'aide d'une fonction d'aide telle que [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Les émetteurs d'événements (comme les flux) peuvent toujours générer des exceptions non interceptées. Veillez donc à traiter l'événement d'erreur de manière appropriée ; par exemple : +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -Pour plus d'informations sur le traitement des erreurs à l'aide de promesses, voir : +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. + +#### A ne pas faire + +Vous ne devriez _pas_ écouter l'événement `uncaughtException`, émis lorsqu'une exception remonte vers la boucle d'événements. L'ajout d'un programme d'écoute d'événement pour `uncaughtException` va modifier le comportement par défaut du processus qui rencontre une exception ; le processus va continuer à s'exécuter malgré l'exception. Cela pourrait être un bon moyen d'empêcher votre application de planter, mais continuer à exécuter l'application après une exception non interceptée est une pratique dangereuse qui n'est pas recommandée, étant donné que l'état du processus devient peu fiable et imprévisible. -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +De plus, l'utilisation d'`uncaughtException` est officiellement reconnue comme étant [rudimentaire](https://nodejs.org/api/process.html#process_event_uncaughtexception) et il a été [proposé](https://github.com/nodejs/node-v0.x-archive/issues/2582) de le supprimer. Ecouter `uncaughtException` n'est qu'une mauvaise idée. Voilà pourquoi nous recommandons d'utiliser plusieurs processus et superviseurs à la place : faire planter son application et la redémarrer est souvent plus sûr que de la restaurer après une erreur. - +L'utilisation de [domain](https://nodejs.org/api/domain.html) n'est également pas recommandée. Ce module obsolète ne résout globalement pas le problème. ## A faire dans votre environnement/configuration Les actions suivantes peuvent être réalisées dans votre environnement système afin d'améliorer les performances de votre application : -* Définir NODE_ENV sur "production" -* Vérifier que votre application redémarre automatiquement -* Exécuter votre application dans un cluster -* Mettre en cache les résultats d'une demande -* Utiliser un équilibreur de charge -* Utiliser un proxy inverse +- Définir NODE_ENV sur "production" +- Vérifier que votre application redémarre automatiquement +- Exécuter votre application dans un cluster +- [Cache request results](#cache-request-results) +- Utilisation de StrongLoop PM avec un équilibreur de charge Nginx +- Encore mieux, utilisez un proxy inverse pour exploiter les fichiers statiques ; pour plus d'informations, voir [Utiliser un proxy inverse](#proxy). ### Définir NODE_ENV sur "production" -La variable d'environnement NODE_ENV spécifie l'environnement dans lequel une application s'exécute (en règle générale, développement ou production). Le moyen le plus simple d'améliorer vos performances consiste à définir NODE_ENV sur "production." +La variable d'environnement NODE_ENV spécifie l'environnement dans lequel une application s'exécute (en règle générale, développement ou production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. En définissant NODE_ENV sur "production", Express : -* Met en cache les modèles d'affichage. -* Met en cache les fichiers CSS générés à partir d'extensions CSS. -* Génère moins de messages d'erreur prolixes. +- Met en cache les modèles d'affichage. +- Met en cache les fichiers CSS générés à partir d'extensions CSS. +- Génère moins de messages d'erreur prolixes. -[Les tests indiquent](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) que ce simple paramétrage peut multiplier les performances d'application par trois ! +[Tests indicate](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! Si vous avez besoin d'écrire du code spécifique à un environnement, vous pouvez vérifier la valeur de NODE_ENV avec `process.env.NODE_ENV`. Sachez que la vérification de la valeur de n'importe quelle variable d'environnement pénalise les performances et devrait donc être effectuée avec modération. -En développement, vous définissez généralement les variables d'environnement dans votre shell interactif, à l'aide de `export` ou de votre fichier `.bash_profile` par exemple. Il n'est toutefois pas conseillé de le faire sur un serveur de production ; utilisez plutôt le système init de votre système d'exploitation (systemd ou Upstart). La section qui suit fournit des détails sur l'utilisation de votre système init en général, mais la définition de NODE_ENV est tellement importante pour les performances (et facile à réaliser), qu'elle est mise en évidence ici. - -Avec Upstart, utilisez le mot clé `env` dans votre fichier de travail. Par exemple : - -
    -
    -# /etc/init/env.conf
    - env NODE_ENV=production
    -
    -
    - -Pour plus d'informations, voir [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). +En développement, vous définissez généralement les variables d'environnement dans votre shell interactif, à l'aide de `export` ou de votre fichier `.bash_profile` par exemple. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). La section qui suit fournit des détails sur l'utilisation de votre système init en général, mais la définition de NODE_ENV est tellement importante pour les performances (et facile à réaliser), qu'elle est mise en évidence ici. Avec systemd, utilisez la directive `Environment` dans votre fichier d'unité. Par exemple : -
    -
    +```sh
     # /etc/systemd/system/myservice.service
     Environment=NODE_ENV=production
    -
    -
    - -Pour plus d'informations, voir [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). +``` -Si vous utilisez StrongLoop Process Manager, vous pouvez également [définir la variable d'environnement lorsque vous installez StrongLoop PM en tant que service](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### Vérifier que votre application redémarre automatiquement En production, vous ne souhaitez jamais que votre application soit déconnectée. Vous devez donc veiller à ce qu'elle redémarre si elle plante et si le serveur plante. Même si vous espérez que cela n'arrive pas, vous devez en réalité considérer ces deux éventualités en : -* Utilisant un gestionnaire de processus pour redémarrer l'application (et Node) lorsqu'elle plante. -* Utilisant le système init fourni par votre système d'exploitation pour redémarrer le gestionnaire de processus lorsque le système d'exploitation plante. Vous pouvez également utiliser le système init sans gestionnaire de processus. +- Utilisant un gestionnaire de processus pour redémarrer l'application (et Node) lorsqu'elle plante. +- Utilisant le système init fourni par votre système d'exploitation pour redémarrer le gestionnaire de processus lorsque le système d'exploitation plante. Vous pouvez également utiliser le système init sans gestionnaire de processus. Les applications Node plantent si elles tombent sur une exception non interceptée. Avant toute chose, vérifiez que votre application est correctement testée et qu'elle traite toutes les exceptions (voir [Traiter correctement les exceptions](#exceptions) pour plus de détails). En cas d'échec, mettez en place un mécanisme qui garantit que si et lorsque votre application plante, elle redémarre automatiquement. @@ -233,55 +194,35 @@ En développement, vous avez simplement démarré votre application à partir de En plus de redémarrer votre application lorsqu'elle plante, un gestionnaire de processus peut vous permettre : -* De vous informer sur les performances d'exécution et la consommation des ressources. -* De modifier les paramètres de manière dynamique afin d'améliorer les performances. -* De contrôler la mise en cluster (StrongLoop PM et pm2). - -Les gestionnaires de processus les plus populaires pour Node sont les suivants : - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -Pour obtenir une comparaison détaillée de ces trois gestionnaires de processus, voir [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Pour obtenir une présentation détaillée, voir [Gestionnaires de processus pour les applications Express](/{{ page.lang }}/advanced/pm.html). +- De vous informer sur les performances d'exécution et la consommation des ressources. +- De modifier les paramètres de manière dynamique afin d'améliorer les performances. +- Control clustering (pm2). -L'utilisation de l'un de ces trois gestionnaires de processus suffira à garder votre application active, même si elle plantera de temps en temps. - -StrongLoop PM possède un grand nombre de fonctionnalités qui ciblent en particulier le déploiement en production. Vous pouvez l'utiliser avec les outils StrongLoop associés pour : - -* Générer et mettre en package votre application en local, puis la déployer en toute sécurité sur votre système de production. -* Redémarrer automatiquement votre application si elle plante pour une raison quelconque. -* Gérer vos clusters à distance. -* Afficher les profils d'UC et les instantanés de segment de mémoire pour optimiser les performances et diagnostiquer les fuites de mémoire. -* Afficher les mesures de performance de votre application. -* Evoluer facilement vers plusieurs hôtes avec un contrôlé intégré de l'équilibreur de charge Nginx. - -Comme décrit ci-dessous, lorsque vous installez StrongLoop PM en tant que service de système d'exploitation à l'aide de votre système init, il redémarre automatiquement au redémarrage du système. Ainsi, vos processus applicatifs et vos clusters resteront toujours actifs. +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. #### Utiliser un système init -Le niveau de fiabilité suivant consiste à garantir que votre application redémarre lorsque le serveur redémarre. Les systèmes peuvent toujours tomber en panne pour divers motifs. Pour garantir que votre application redémarre si le serveur plante, utilisez le système init intégré à votre système d'exploitation. Les deux principaux systèmes init actuellement utilisés sont [systemd](https://wiki.debian.org/systemd) et [Upstart](http://upstart.ubuntu.com/). +Le niveau de fiabilité suivant consiste à garantir que votre application redémarre lorsque le serveur redémarre. Les systèmes peuvent toujours tomber en panne pour divers motifs. Pour garantir que votre application redémarre si le serveur plante, utilisez le système init intégré à votre système d'exploitation. The main init system in use today is [systemd](https://wiki.debian.org/systemd). Vous pouvez utiliser les systèmes init de deux manières dans votre application Express : -* Exécutez votre application dans un gestionnaire de processus, puis installez le gestionnaire de processus en tant que service avec le système init. Le gestionnaire de processus va redémarrer votre application lorsqu'elle plantera et le système init va redémarrer le gestionnaire de processus lorsque le système d'exploitation redémarrera. Il s'agit de la méthode recommandée. -* Exécutez votre application (et Node) directement avec le système init. Cette méthode est plus simple, mais vous ne profitez pas des avantages d'un gestionnaire de processus. +- Exécutez votre application dans un gestionnaire de processus, puis installez le gestionnaire de processus en tant que service avec le système init. Le gestionnaire de processus va redémarrer votre application lorsqu'elle plantera et le système init va redémarrer le gestionnaire de processus lorsque le système d'exploitation redémarrera. Il s'agit de la méthode recommandée. +- Exécutez votre application (et Node) directement avec le système init. Cette méthode est plus simple, mais vous ne profitez pas des avantages d'un gestionnaire de processus. ##### Systemd Systemd est un système Linux et un gestionnaire de services. La plupart des distributions Linux principales ont adopté systemd comme leur système init par défaut. -Un fichier de configuration de service systemd est appelé *fichier d'unité* et porte l'extension .service. Voici un exemple de fichier d'unité permettant de gérer une application Node directement (remplacez le texte en gras par les valeurs appropriées à votre système et votre application) : +Un fichier de configuration de service systemd est appelé _fichier d'unité_ et porte l'extension .service. Voici un exemple de fichier d'unité permettant de gérer une application Node directement (remplacez le texte en gras par les valeurs appropriées à votre système et votre application) : Replace the values enclosed in `` for your system and app: -
    -
    +```sh
     [Unit]
    -Description=Awesome Express App
    +Description=
     
     [Service]
     Type=simple
    -ExecStart=/usr/local/bin/node /projects/myapp/index.js
    -WorkingDirectory=/projects/myapp
    +ExecStart=/usr/local/bin/node 
    +WorkingDirectory=
     
     User=nobody
     Group=nogroup
    @@ -302,111 +243,15 @@ Restart=always
     
     [Install]
     WantedBy=multi-user.target
    -
    -
    -Pour plus d'informations sur systemd, voir la [page d'aide de systemd](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM en tant que service systemd - -Vous pouvez facilement installer StrongLoop Process Manager en tant que service systemd. Une fois que c'est fait, lorsque le serveur redémarre, il redémarre automatiquement StrongLoop PM, qui redémarre ensuite toutes les applications qu'il gère. - -Pour installer StrongLoop PM en tant que service systemd : - -
    -
    -$ sudo sl-pm-install --systemd
    -
    -
    - -Démarrez ensuite le service comme suit : - -
    -
    -$ sudo /usr/bin/systemctl start strong-pm
    -
    -
    - -Pour plus d'informations, voir [Setting up a production host](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10) dans la documentation StrongLoop. - -##### Upstart - -Upstart est un outil système disponible sur un grand nombre de distributions Linux et qui permet de démarrer des tâches et des services pendant le démarrage du système, de les arrêter pendant l'arrêt du système et de les superviser. Vous pouvez configurer votre application Express ou votre gestionnaire de processus en tant que service, puis Upstart le redémarrera automatiquement lorsqu'il plantera. - -Un service Upstart est défini dans un fichier de configuration de travail (également appelé "travail") portant l'extension `.conf`. L'exemple qui suit décrit comment créer un travail appelé "myapp" pour une application nommée "myapp" avec le fichier principal situé dans `/projects/myapp/index.js`. - -Créez un fichier nommé `myapp.conf` dans `/etc/init/` avec le contenu suivant (remplacez le texte en gras par les valeurs appropriées à votre système et votre application) : - -
    -
    -# When to start the process
    -start on runlevel [2345]
    -
    -# When to stop the process
    -stop on runlevel [016]
    -
    -# Increase file descriptor limit to be able to handle more requests
    -limit nofile 50000 50000
    -
    -# Use production mode
    -env NODE_ENV=production
    -
    -# Run as www-data
    -setuid www-data
    -setgid www-data
    -
    -# Run from inside the app dir
    -chdir /projects/myapp
    -
    -# The process to start
    -exec /usr/local/bin/node /projects/myapp/index.js
    -
    -# Restart the process if it is down
    -respawn
    -
    -# Limit restart attempt to 10 times within 10 seconds
    -respawn limit 10 10
    -
    -
    - -REMARQUE : ce script nécessite Upstart 1.4 ou ultérieur, pris en charge sur Ubuntu 12.04-14.10. - -Etant donné que le travail est configuré pour s'exécuter au démarrage du système, votre application sera démarrée avec le système d'exploitation et sera redémarrée automatiquement si l'application plante ou si le système tombe en panne. - -En plus de redémarrer automatiquement l'application, Upstart vous permet d'utiliser les commandes suivantes : - -* `start myapp` – Démarre l'application -* `restart myapp` – Redémarre l'application -* `stop myapp` – Arrête l'application - -Pour plus d'informations sur Upstart, voir [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM en tant que service Upstart - -Vous pouvez facilement installer StrongLoop Process Manager en tant que service Upstart. Une fois que c'est fait, lorsque le serveur redémarre, il redémarre automatiquement StrongLoop PM, qui redémarre ensuite toutes les applications qu'il gère. - -Pour installer StrongLoop PM en tant que service Upstart 1.4 : - -
    -
    -$ sudo sl-pm-install
    -
    -
    - -Exécutez ensuite le service comme suit : - -
    -
    -$ sudo /sbin/initctl start strong-pm
    -
    -
    +``` -REMARQUE : sur les systèmes qui ne prennent pas en charge Upstart 1.4, les commandes sont légèrement différentes. Pour plus d'informations, voir [Setting up a production host](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) dans la documentation StrongLoop. +Pour plus d'informations sur systemd, voir la [page d'aide de systemd](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). ### Exécuter votre application dans un cluster Dans un système multicoeur, vous pouvez augmenter les performances d'une application Node en lançant un cluster de processus. Un cluster exécute plusieurs instances de l'application, idéalement une instance sur chaque coeur d'UC, répartissant ainsi la charge et les tâches entre les instances. - +![Balancing between application instances using the cluster API](/images/clustering.png) IMPORTANT : étant donné que les instances d'application s'exécutent en tant que processus distincts, elles ne partagent pas le même espace mémoire. Autrement dit, les objets sont en local sur chaque instance de l'application. Par conséquent, vous ne pouvez pas conserver l'état dans le code de l'application. Vous pouvez toutefois utiliser un magasin de données en mémoire tel que [Redis](http://redis.io/) pour stocker les données de session et l'état. Cette fonctionnalité s'applique essentiellement à toutes les formes de mise à l'échelle horizontale, que la mise en cluster soit effectuée avec plusieurs processus ou avec plusieurs serveurs physiques. @@ -414,45 +259,52 @@ Dans les applications mises en cluster, les processus de traitement peuvent plan #### Utilisation du module cluster de Node -La mise en cluster peut être réalisée avec le [module cluster](https://nodejs.org/docs/latest/api/cluster.html) de Node. Ce module permet à un processus maître de générer des processus de traitement et de répartir les connexions entrantes parmi ces processus. Toutefois, plutôt que d'utiliser ce module directement, utilisez l'un des nombreux outils qui le font pour vous, à savoir [node-pm](https://www.npmjs.com/package/node-pm) ou [cluster-service](https://www.npmjs.com/package/cluster-service) par exemple. +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). Ce module permet à un processus maître de générer des processus de traitement et de répartir les connexions entrantes parmi ces processus. -#### Utilisation de StrongLoop PM +#### Using PM2 -Si vous déployez votre application dans StrongLoop Process Manager (PM), vous pouvez alors utiliser la mise en cluster *sans* modifier votre code d'application. +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). -Lorsque StrongLoop Process Manager (PM) exécute une application, il l'exécute automatiquement dans un cluster avec un nombre de processus de traitement égal au nombre de coeurs d'UC sur le système. Vous pouvez modifier manuellement le nombre de processus de traitement dans le cluster à l'aide de l'outil de ligne de commande slc sans arrêter l'application. +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. -Par exemple, en supposant que vous avez déployé votre application sur prod.foo.com et que StrongLoop PM est en mode écoute sur le port 8701 (par défaut), pour définir la taille du cluster sur 8 à l'aide de slc : +To enable cluster mode, start your application like so: -
    -
    -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
    -
    -
    +```bash +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ pm2 start npm --name my-app -i max -- start +``` -Pour plus d'informations sur la mise en cluster avec StrongLoop PM, voir [Clustering](https://docs.strongloop.com/display/SLC/Clustering) dans la documentation StrongLoop. +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 +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ 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. ### Mettre en cache les résultats d'une demande Pour améliorer les performances en production, vous pouvez également mettre en cache le résultat des demandes, de telle sorte que votre application ne répète pas l'opération de traitement de la même demande plusieurs fois. -Utilisez un serveur de mise en cache tel que [Varnish](https://www.varnish-cache.org/) ou [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (voir aussi [Nginx Caching](https://serversforhackers.com/nginx-caching/)) pour améliorer considérablement la vitesse et les performances de votre application. +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### Utiliser un équilibreur de charge Quel que soit le niveau d'optimisation d'une application, une instance unique ne peut traiter qu'un volume limité de charge et de trafic. Pour faire évoluer une application, vous pouvez exécuter plusieurs instances de cette application et répartir le trafic en utilisant un équilibreur de charge. La configuration d'un équilibreur de charge peut améliorer les performances et la vitesse de votre application et lui permettre d'évoluer plus largement qu'avec une seule instance. -Un équilibreur de charge est généralement un proxy inverse qui orchestre le trafic entrant et sortant de plusieurs instances d'application et serveurs. Vous pouvez facilement configurer un équilibreur de charge pour votre application à l'aide de [Nginx](http://nginx.org/en/docs/http/load_balancing.html) ou de [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). - -Avec l'équilibrage de charge, vous devrez peut-être vérifier que les demandes associées à un ID de session spécifique sont connectées au processus dont elles sont issues. Ce procédé est appelé *affinité de session* (ou *sessions persistantes*) et peut être effectué en utilisant un magasin de données tel que Redis pour les données de session (en fonction de votre application), comme décrit ci-dessus. Pour en savoir plus, voir [Using multiple nodes](http://socket.io/docs/using-multiple-nodes/). - -#### Utilisation de StrongLoop PM avec un équilibreur de charge Nginx +Un équilibreur de charge est généralement un proxy inverse qui orchestre le trafic entrant et sortant de plusieurs instances d'application et serveurs. 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). -[StrongLoop Process Manager](http://strong-pm.io/) est intégré à un contrôleur Nginx, ce qui permet de paramétrer facilement les configurations d'environnement de production à plusieurs hôtes. Pour plus d'informations, voir [Scaling to multiple servers](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (documentation StrongLoop). - +Avec l'équilibrage de charge, vous devrez peut-être vérifier que les demandes associées à un ID de session spécifique sont connectées au processus dont elles sont issues. Ce procédé est appelé _affinité de session_ (ou _sessions persistantes_) et peut être effectué en utilisant un magasin de données tel que Redis pour les données de session (en fonction de votre application), comme décrit ci-dessus. Pour en savoir plus, voir [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). ### Utiliser un proxy inverse Un proxy inverse accompagne une application Web et exécute des opérations de prise en charge sur les demandes, en plus de diriger les demandes vers l'application. Il peut gérer les pages d'erreur, la compression, la mise en cache, le dépôt de fichiers et l'équilibrage de charge entre autres. -La transmission de tâches qui ne requièrent aucune connaissance de l'état d'application à un proxy inverse permet à Express de réaliser des tâches d'application spécialisées. C'est pour cette raison qu'il est recommandé d'exécuter Express derrière un proxy inverse tel que [Nginx](https://www.nginx.com/) ou [HAProxy](http://www.haproxy.org/) en production. +La transmission de tâches qui ne requièrent aucune connaissance de l'état d'application à un proxy inverse permet à Express de réaliser des tâches d'application spécialisées. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/fr/advanced/best-practice-security.md b/fr/advanced/best-practice-security.md old mode 100755 new mode 100644 index 394b65143f..5be8ad6105 --- a/fr/advanced/best-practice-security.md +++ b/fr/advanced/best-practice-security.md @@ -1,20 +1,46 @@ --- layout: page title: Meilleures pratiques de sécurité pour Express en production +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: fr +redirect_from: " " --- # Meilleures pratiques en production : Sécurité ## Présentation -Le terme *"production"* fait référence à la phase du cycle de vie du logiciel au cours de laquelle une application ou une API est généralement disponible pour ses consommateurs ou utilisateurs finaux. En revanche, en phase de *"développement"*, l'écriture et le test de code se poursuivent activement et l'application n'est pas ouverte pour un accès externe. Les environnements système correspondants sont respectivement appelés environnement de *production* et environnement de *développement*. +Le terme _"production"_ fait référence à la phase du cycle de vie du logiciel au cours de laquelle une application ou une API est généralement disponible pour ses consommateurs ou utilisateurs finaux. En revanche, en phase de _"développement"_, l'écriture et le test de code se poursuivent activement et l'application n'est pas ouverte pour un accès externe. Les environnements système correspondants sont respectivement appelés environnement de _production_ et environnement de _développement_. Les environnements de développement et de production sont généralement configurés différemment et leurs exigences divergent grandement. Ce qui convient parfaitement en développement peut être inacceptable en production. Par exemple, dans un environnement de développement, vous pouvez souhaiter une consignation prolixe des erreurs en vue du débogage, alors que ce type de comportement présente des risques au niveau de sécurité en environnement de production. De plus, en environnement de développement, vous n'avez pas à vous soucier de l'extensibilité, de la fiabilité et des performances, tandis que ces éléments sont essentiels en environnement de production. +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} + Cet article traite des meilleures pratiques en terme de sécurité pour les applications Express déployées en production. +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [hsts](https://github.com/helmetjs/hsts) définit l'en-tête `Strict-Transport-Security` qui impose des connexions (HTTP sur SSL/TLS) sécurisées au serveur. + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) supprime l'en-tête `X-Powered-By`. + - [Reduce fingerprinting](#reduce-fingerprinting) + - [xssFilter](https://github.com/helmetjs/x-xss-protection) définit `X-XSS-Protection` afin d'activer le filtre de script intersites (XSS) dans les navigateurs Web les plus récents. + - [noCache](https://github.com/helmetjs/nocache) définit des en-têtes `Cache-Control` et Pragma pour désactiver la mise en cache côté client. + - [ieNoOpen](https://github.com/helmetjs/ienoopen) définit `X-Download-Options` pour IE8+. + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) + - Désactivez au minimum l'en-tête X-Powered-By + - [Additional considerations](#additional-considerations) + ## N'utilisez pas de versions obsolètes ou vulnérables d'Express Les versions 2.x et 3.x d'Express ne sont plus prises en charge. Les problèmes liés à la sécurité et aux performances dans ces versions ne seront pas corrigés. Ne les utilisez pas ! Si vous êtes passé à la version 4, suivez le [guide de migration](/{{ page.lang }}/guide/migrating-4.html). @@ -25,57 +51,122 @@ Vérifiez également que vous n'utilisez aucune des versions vulnérables d'Expr Si votre application traite ou transmet des données sensibles, utilisez [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) (Transport Layer Security) afin de sécuriser la connexion et les données. Cette technologie de l'information chiffre les données avant de les envoyer du client au serveur, ce qui vous préserve des risques d'hameçonnage les plus communs (et faciles). Même si les requêtes Ajax et POST ne sont pas clairement visibles et semblent "masquées" dans les navigateurs, leur trafic réseau n'est pas à l'abri d'une [détection de paquet](https://en.wikipedia.org/wiki/Packet_analyzer) ni des [attaques d’intercepteur](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -Vous connaissez sans doute le chiffrement SSL (Secure Socket Layer). [TLS est simplement une évolution de SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). En d'autres termes, si vous utilisiez SSL auparavant, envisagez de passer à TLS. Nous recommandons généralement Nginx pour gérer TLS. Pour des informations de référence fiables concernant la configuration de TLS sur Nginx (et d'autres serveurs), voir [Configurations de serveur recommandées (wiki Mozilla)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). +Vous connaissez sans doute le chiffrement SSL (Secure Socket Layer). [TLS est simplement une évolution de SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx). En d'autres termes, si vous utilisiez SSL auparavant, envisagez de passer à TLS. Nous recommandons généralement Nginx pour gérer TLS. Pour des informations de référence fiables concernant la configuration de TLS sur Nginx (et d'autres serveurs), voir [Configurations de serveur recommandées (wiki Mozilla)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). Par ailleurs, un outil très pratique, [Let's Encrypt](https://letsencrypt.org/about/), autorité de certification gratuite, automatisée et ouverte fournie par le groupe de recherche sur la sécurité sur Internet, [ISRG (Internet Security Research Group)](https://letsencrypt.org/isrg/), vous permet de vous procurer gratuitement un certificat TLS. +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## Utilisez Helmet [Helmet](https://www.npmjs.com/package/helmet) vous aide à protéger votre application de certaines des vulnérabilités bien connues du Web en configurant de manière appropriée des en-têtes HTTP. -Helmet n'est actuellement qu'une collection de neuf fonctions middleware plus petites qui définissent des en-têtes HTTP liés à la sécurité : +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* [csp](https://github.com/helmetjs/csp) définit l'en-tête `Content-Security-Policy` pour la protection contre les attaques de type cross-site scripting et autres injections intersites. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) supprime l'en-tête `X-Powered-By`. -* [hsts](https://github.com/helmetjs/hsts) définit l'en-tête `Strict-Transport-Security` qui impose des connexions (HTTP sur SSL/TLS) sécurisées au serveur. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) définit `X-Download-Options` pour IE8+. -* [noCache](https://github.com/helmetjs/nocache) définit des en-têtes `Cache-Control` et Pragma pour désactiver la mise en cache côté client. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) définit `X-Content-Type-Options` pour protéger les navigateurs du reniflage du code MIME d'une réponse à partir du type de contenu déclaré. -* [frameguard](https://github.com/helmetjs/frameguard) définit l'en-tête `X-Frame-Options` pour fournir une protection [clickjacking](https://www.owasp.org/index.php/Clickjacking). -* [xssFilter](https://github.com/helmetjs/x-xss-protection) définit `X-XSS-Protection` afin d'activer le filtre de script intersites (XSS) dans les navigateurs Web les plus récents. +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. Installez Helmet comme n'importe quel autre module : -
    -
    -$ npm install --save helmet
    -
    -
    +```bash +$ npm install helmet +``` Puis, pour l'utiliser dans votre code : -
    -
    -...
    -var helmet = require('helmet');
    -app.use(helmet());
    -...
    -
    -
    +```js +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... +``` + +## Reduce fingerprinting + +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. + +By default, Express sends the `X-Powered-By` response header that you can +disable using the `app.disable()` method: + +```js +app.disable('x-powered-by') +``` + +{% capture powered-advisory %} -### Désactivez au minimum l'en-tête X-Powered-By +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. -Si vous ne voulez pas utiliser Helmet, désactivez au minimum l'en-tête `X-Powered-By`. Les intrus peuvent utiliser cet en-tête (activé par défaut) afin de détecter les applications qui exécutent Express et lancer ensuite des attaques spécifiquement ciblées. +{% endcapture %} -Il est donc conseillé de neutraliser l'en-tête à l'aide de la méthode `app.disable()` comme suit : +{% include admonitions/note.html content=powered-advisory %} -
    -
    -app.disable('x-powered-by');
    -
    -
    +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): -Si vous utilisez `helmet.js`, cette opération s'effectue automatiquement. +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## Utilisez les cookies de manière sécurisée @@ -83,12 +174,12 @@ Pour garantir que les cookies n'ouvrent pas votre application aux attaques, n'ut Il existe deux modules principaux de session de cookie de middleware : -* [express-session](https://www.npmjs.com/package/express-session) qui remplace le middleware `express.session` intégré à Express 3.x. -* [cookie-session](https://www.npmjs.com/package/cookie-session) qui remplace le middleware `express.cookieSession` intégré à Express 3.x. +- [express-session](https://www.npmjs.com/package/express-session) qui remplace le middleware `express.session` intégré à Express 3.x. +- [cookie-session](https://www.npmjs.com/package/cookie-session) qui remplace le middleware `express.cookieSession` intégré à Express 3.x. -La principale différence entre ces deux modules tient à la manière dont ils sauvegardent les données de session des cookies. Le middleware [express-session](https://www.npmjs.com/package/express-session) stocke les données de session sur le serveur ; il ne sauvegarde que l'ID session dans le cookie lui-même, mais pas les données de session. Par défaut, il utilise le stockage en mémoire et n'est pas conçu pour un environnement de production. En production, vous devrez configurer un magasin de sessions évolutif (voir la liste des [magasins de sessions compatibles](https://github.com/expressjs/session#compatible-session-stores)). +La principale différence entre ces deux modules tient à la manière dont ils sauvegardent les données de session des cookies. Le middleware [express-session](https://www.npmjs.com/package/express-session) stocke les données de session sur le serveur ; il ne sauvegarde que l'ID session dans le cookie lui-même, mais pas les données de session. Par défaut, il utilise le stockage en mémoire et n'est pas conçu pour un environnement de production. En production, vous devrez configurer un magasin de sessions évolutif (voir la liste des [magasins de sessions compatibles](https://github.com/expressjs/session#compatible-session-stores)). -En revanche, le middleware [cookie-session](https://www.npmjs.com/package/cookie-session) implémente un stockage sur cookie, c'est-à-dire qu'il sérialise l'intégralité de la session sur le cookie, et non simplement une clé de session. Utilisez-le uniquement lorsque les données de session sont relativement peu nombreuses et faciles à coder sous forme de valeurs primitives (au lieu d'objets). Même si les navigateurs sont censés prendre en charge au moins 4096 octets par cookie, pour ne pas risquer de dépasser cette limite, limitez-vous à 4093 octets par domaine. De plus, n'oubliez pas que les données de cookie seront visibles du client et que s'il n'est pas nécessaire qu'elles soient sécurisées ou illisibles, express-session est probablement la meilleure solution. +En revanche, le middleware [cookie-session](https://www.npmjs.com/package/cookie-session) implémente un stockage sur cookie, c'est-à-dire qu'il sérialise l'intégralité de la session sur le cookie, et non simplement une clé de session. Utilisez-le uniquement lorsque les données de session sont relativement peu nombreuses et faciles à coder sous forme de valeurs primitives (au lieu d'objets). Même si les navigateurs sont censés prendre en charge au moins 4096 octets par cookie, pour ne pas risquer de dépasser cette limite, limitez-vous à 4093 octets par domaine. De plus, n'oubliez pas que les données de cookie seront visibles du client et que s'il n'est pas nécessaire qu'elles soient sécurisées ou illisibles, express-session est probablement la meilleure solution. ### N'utilisez pas de nom de cookie de session par défaut @@ -96,65 +187,96 @@ L'utilisation d'un nom de cookie de session par défaut risque d'ouvrir votre ap Pour éviter ce problème, utilisez des noms de cookie génériques, par exemple à l'aide du middleware [express-session](https://www.npmjs.com/package/express-session) : -
    -
    -var session = require('express-session');
    +```js
    +const session = require('express-session')
     app.set('trust proxy', 1) // trust first proxy
    -app.use( session({
    -   secret : 's3Cur3',
    -   name : 'sessionId',
    -  })
    -);
    -
    -
    +app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) +``` ### Définissez des options de sécurité de cookie Définissez les options de cookie suivantes pour accroître la sécurité : -* `secure` - Garantit que le navigateur n'envoie le cookie que sur HTTPS. -* `httpOnly` - Garantit que le cookie n'est envoyé que sur HTTP(S), pas au JavaScript du client, ce qui renforce la protection contre les attaques de type cross-site scripting. -* `domain` - Indique le domaine du cookie ; utilisez cette option pour une comparaison avec le domaine du serveur dans lequel l'URL est demandée. S'ils correspondent, vérifiez ensuite l'attribut de chemin. -* `path` - Indique le chemin du cookie ; utilisez cette option pour une comparaison avec le chemin demandé. Si le chemin et le domaine correspondent, envoyez le cookie dans la demande. -* `expires` - Utilisez cette option pour définir la date d'expiration des cookies persistants. +- `secure` - Garantit que le navigateur n'envoie le cookie que sur HTTPS. +- `httpOnly` - Garantit que le cookie n'est envoyé que sur HTTP(S), pas au JavaScript du client, ce qui renforce la protection contre les attaques de type cross-site scripting. +- `domain` - Indique le domaine du cookie ; utilisez cette option pour une comparaison avec le domaine du serveur dans lequel l'URL est demandée. S'ils correspondent, vérifiez ensuite l'attribut de chemin. +- `path` - Indique le chemin du cookie ; utilisez cette option pour une comparaison avec le chemin demandé. Si le chemin et le domaine correspondent, envoyez le cookie dans la demande. +- `expires` - Utilisez cette option pour définir la date d'expiration des cookies persistants. Exemple d'utilisation du middleware [cookie-session](https://www.npmjs.com/package/cookie-session) : -
    -
    -var session = require('cookie-session');
    -var express = require('express');
    -var app = express();
    +```js
    +const session = require('cookie-session')
    +const express = require('express')
    +const app = express()
     
    -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
    +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
     app.use(session({
       name: 'session',
       keys: ['key1', 'key2'],
    -  cookie: { secure: true,
    -            httpOnly: true,
    -            domain: 'example.com',
    -            path: 'foo/bar',
    -            expires: expiryDate
    -          }
    -  })
    -);
    -
    -
    + cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) +``` -## Autres considérations +## Implémentez la limitation de débit pour empêcher les attaques de force brute liées à l'authentification. + +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +1. The number of consecutive failed attempts by the same user name and IP address. +2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) + +## Ensure your dependencies are secure + +Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. -Voici d'autres recommandations issues de l'excellente [liste de contrôle de sécurité Node.js](https://blog.risingstack.com/node-js-security-checklist/). Pour tous les détails sur ces recommandations, reportez-vous à cet article de blogue : +Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. -* Implémentez la limitation de débit pour empêcher les attaques de force brute liées à l'authentification. Une façon de faire consiste à utiliser [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) pour mettre en place une règle de limitation de débit. Sinon, vous pouvez utiliser des middleware tels que [express-limiter](https://www.npmjs.com/package/express-limiter), mais vous devrez alors modifier quelque peu votre code. -* Utilisez le middleware [csurf](https://www.npmjs.com/package/csurf) pour vous protéger contre les CSRF (Cross-Site Request Forgery). -* Filtrez et nettoyez toujours les entrées utilisateur pour vous protéger contre les attaques de cross-site scripting (XSS) et d'injection de commande. -* Défendez-vous contre les attaques par injection SQL en utilisant des requêtes paramétrées ou des instructions préparées. -* Utilisez l'outil [sqlmap](http://sqlmap.org/) à code source ouvert pour détecter les vulnérabilités par 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 chiffrements, clés et renégociations SSL, ainsi que la validité de votre certificat. -* Utilisez [safe-regex](https://www.npmjs.com/package/safe-regex) pour s'assurer que vos expressions régulières ne sont pas exposées à des attaques ReDoS ([regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)). +```bash +$ npm audit +``` -## Eviter les autres vulnérabilités connues +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: + +```bash +$ npm install -g snyk +$ cd your-app +``` + +Use this command to test your application for vulnerabilities: + +```bash +$ snyk test +``` + +### Eviter les autres vulnérabilités connues Gardez un oeil sur les recommandations [Node Security Project](https://npmjs.com/advisories) qui peuvent concerner Express ou d'autres modules utilisés par votre application. En règle générale, Node Security Project est une excellente ressource de connaissances et d'outils sur la sécurité de Node. -Pour finir, les applications Express - comme toutes les autres applications Web - peuvent être vulnérables à une variété d'attaques Web. Familiarisez vous avec les [vulnérabilités Web](https://www.owasp.org/index.php/Top_10_2013-Top_10) connues et prenez des précautions pour les éviter. +Pour finir, les applications Express - comme toutes les autres applications Web - peuvent être vulnérables à une variété d'attaques Web. Familiarisez vous avec les [vulnérabilités Web](https://www.owasp.org/www-project-top-ten/) connues et prenez des précautions pour les éviter. + +## Autres considérations + +Voici d'autres recommandations issues de l'excellente [liste de contrôle de sécurité Node.js](https://blog.risingstack.com/node-js-security-checklist/). Pour tous les détails sur ces recommandations, reportez-vous à cet article de blogue : + +- Filtrez et nettoyez toujours les entrées utilisateur pour vous protéger contre les attaques de cross-site scripting (XSS) et d'injection de commande. +- Défendez-vous contre les attaques par injection SQL en utilisant des requêtes paramétrées ou des instructions préparées. +- Utilisez l'outil [sqlmap](http://sqlmap.org/) à code source ouvert pour détecter les vulnérabilités par 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 chiffrements, clés et renégociations SSL, ainsi que la validité de votre certificat. +- Utilisez [safe-regex](https://www.npmjs.com/package/safe-regex) pour s'assurer que vos expressions régulières ne sont pas exposées à des attaques ReDoS ([regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)). + +[helmet]: \ No newline at end of file diff --git a/fr/advanced/developing-template-engines.md b/fr/advanced/developing-template-engines.md old mode 100755 new mode 100644 index b6c463aa98..531bc250f8 --- a/fr/advanced/developing-template-engines.md +++ b/fr/advanced/developing-template-engines.md @@ -1,8 +1,9 @@ --- layout: page title: Développement de moteurs de modèles pour Express +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: fr +redirect_from: " " --- # Développement de moteurs de modèles pour Express @@ -11,38 +12,35 @@ Utilisez la méthode `app.engine(ext, callback)` pour créer votre propre moteur Le code suivant est un exemple d'implémentation d'un moteur de modèle très simple qui permet d'afficher le rendu des fichiers `.ntl`. -
    -
    -var fs = require('fs'); // this engine requires the fs module
    -app.engine('ntl', function (filePath, options, callback) { // define the template engine
    -  fs.readFile(filePath, function (err, content) {
    -    if (err) return callback(new Error(err));
    +```js
    +const fs = require('fs') // this engine requires the fs module
    +app.engine('ntl', (filePath, options, callback) => { // define the template engine
    +  fs.readFile(filePath, (err, content) => {
    +    if (err) return callback(err)
         // this is an extremely simple template engine
    -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
    -    .replace('#message#', '

    '+ options.message +'

    '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
    -
    + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

    ${options.message}

    `) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine +``` Votre application est désormais en mesure d'afficher le rendu des fichiers `.ntl`. Créez un fichier nommé `index.ntl` dans le répertoire `views` avec le contenu suivant. -
    -
    +```pug
     #title#
     #message#
    -
    -
    +``` + ENsuite, créez la route suivante dans votre application. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    -Lorsque vous effectuerez une demande à la page d'accueil, `index.ntl` sera rendu au format HTML. +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` + +Lorsque vous effectuerez une demande à la page d'accueil, `index.ntl` sera rendu au format HTML. \ No newline at end of file diff --git a/fr/advanced/healthcheck-graceful-shutdown.md b/fr/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..fe41569237 --- /dev/null +++ b/fr/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/fr/advanced/pm.md b/fr/advanced/pm.md deleted file mode 100755 index 771156c5a9..0000000000 --- a/fr/advanced/pm.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -layout: page -title: Gestionnaires de processus pour les applications Express -menu: advanced -lang: fr ---- - -# Gestionnaires de processus pour les applications Express - -Quand vous exécutez l'application Express pour la -production, utilisez un *gestionnaire de -processus* car celui-ci peut vous permettre : - -- De redémarrer l'application manuellement si elle subit une panne. -- De vous informer sur les performances d'exécution et la consommation des ressources. -- De modifier les paramètres de manière dynamique afin d'améliorer les performances. -- De contrôler la mise en cluster. - -Un gestionnaire de processus est quelque sorte un "conteneur" d'applications qui facilite le déploiement, offre une haute disponibilité et vous permet de gérer l'application lors de son exécution. - -Les gestionnaires de processus les plus populaires pour Express et d'autres applications Node.js sont les suivants : - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -L'utilisation d'un de ces trois outils peut être très utile, cependant le gestionnaire de processus StrongLoop est le seul qui fournisse un délai d'exécution exhaustif ainsi qu'une solution de déploiement qui s'adresse à l'intégralité du cycle de vie de l'application, avec des outils pour chaque étape avant et après la production, le tout dans une interface unifiée. - -Voici un bref aperçu de chacun de ces outils. -Pour une comparaison détaillée, voir [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -Le gestionnaire de processus StrongLoop (StrongLoop PM) est un gestionnaire de processus de production pour les applications Node.js. StrongLoop PM possède un équilibrage de charge, une surveillance et un déploiement multi-hôte, ainsi qu'une console graphique intégrés. -Vous pouvez utiliser StrongLoop PM pour les tâches suivantes : - -- Construire, combiner et déployer votre application Node.js à un système local ou distant. -- Afficher les profils d'UC et les instantanés de segment de mémoire pour optimiser les performances et diagnostiquer les fuites de mémoire. -- Conserver des processus et des clusters avec une durée de vie illimitée. -- Afficher les indicateurs de performance dans votre application. -- Gérer facilement les déploiements multi-hôtes avec l'intégration Nginx. -- Unifier plusieurs StrongLoop PM avec un délai d'exécution des microservices réparti et qui est géré par Arc. - -Vous pouvez utiliser StrongLoop PM en passant par un puissant outil d'interface de ligne de commande appelé `slc`, ou un outil graphique appelé Arc. Arc est un code source ouvert, avec une prise en charge professionnelle fournie par StrongLoop. - -Pour plus d'informations, voir [http://strong-pm.io/](http://strong-pm.io/). - -Documentation complète : - -- [Utilisation des applications Node (documentation StrongLoop)](http://docs.strongloop.com/display/SLC) -- [Utilisation du gestionnaire de processus StrongLoop](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Installation -
    -
    -$ [sudo] npm install -g strongloop
    -
    -
    - -### Utilisation de base -
    -
    -$ cd my-app
    -$ slc start
    -
    -
    - -Afficher le statut du gestionnaire de processus ainsi que de toutes les applications déployées : - -
    -
    -$ slc ctl
    -Service ID: 1
    -Service Name: my-app
    -Environment variables:
    -  No environment variables defined
    -Instances:
    -    Version  Agent version  Cluster size
    -     4.1.13      1.5.14           4
    -Processes:
    -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
    -    1.1.57692  57692   0
    -    1.1.57693  57693   1     0.0.0.0:3001
    -    1.1.57694  57694   2     0.0.0.0:3001
    -    1.1.57695  57695   3     0.0.0.0:3001
    -    1.1.57696  57696   4     0.0.0.0:3001
    -
    -
    - -Lister toutes les applications (services) sous gestion : - -
    -
    -$ slc ctl ls
    -Id          Name         Scale
    - 1          my-app       1
    -
    -
    - -Arrêter une application : - -
    -
    -$ slc ctl stop my-app
    -
    -
    - -Redémarrer une application : - -
    -
    -$ slc ctl restart my-app
    -
    -
    - -Vous pouvez également "redémarrer en douceur", ce qui donne aux -processus de traitement un délai supplémentaire afin de fermer les -connexions existantes, et permet un redémarrage des applications en -cours : - -
    -
    -$ slc ctl soft-restart my-app
    -
    -
    - -Supprimer une application de la gestion : - -
    -
    -$ slc ctl remove my-app
    -
    -
    - -## PM2 - -PM2 est un gestionnaire de processus de production pour les -applications Node.js, qui possède un équilibreur de charge intégré. PM2 -vous permet de conserver des applications avec une durée de vie -illimitée et de les recharger sans temps d'arrêt, ce qui facilite -les tâches de l'administrateur système commun. PM2 vous permet -également de gérer la journalisation, la surveillance et le -regroupement de l'application. - -Pour plus d'informations, voir [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Installation - -
    -
    -$ [sudo] npm install pm2 -g
    -
    -
    - -### Utilisation de base - -Quand vous démarrez une application en utilisant la commande `pm2` vous devez indiquer le chemin d'accès de -l'application. Cependant, quand vous arrêtez, redémarrez ou supprimez -une application, vous pouvez n'indiquer que le nom ou l'ID de -l'application. - -
    -
    -$ pm2 start npm --name my-app -- start
    -[PM2] restartProcessId process id 0
    -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
    -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
    -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
    -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
    -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
    - Use the `pm2 show ` command to get more details about an app.
    -
    -
    - -Quand vous démarrez une application à l'aide de la -commande `pm2`, l'application est immédiatement -envoyée en arrière-plan. Vous pouvez contrôler l'application -en arrière-plan à partir de la ligne de commande en utilisant diverses -commandes `pm2`. - -Après qu'une application a été démarrée en utilisant la -commande `pm2`, elle est enregistrée dans la liste -de processus de PM2 avec un ID. Vous pouvez donc gérer les -applications avec le même nom à partir de répertoires différents -dans le système, en utilisant leurs ID. - -Notez que si plusieurs application avec le même nom sont en -cours d'exécution, les commandes `pm2` les -affecteront toutes. Il vaut donc mieux utiliser les ID plutôt que les -noms pour gérer les applications individuelles. - -Lister tous les processus en cours : - -
    -
    -$ pm2 list
    -
    -
    - -Arrêter une application : - -
    -
    -$ pm2 stop 0
    -
    -
    - -Redémarrer une application : - -
    -
    -$ pm2 restart 0
    -
    -
    - -Pour afficher les informations détaillées d'une application : - -
    -
    -$ pm2 show 0
    -
    -
    - -Pour supprimer une application du registre PM2 : - -
    -
    -$ pm2 delete 0
    -
    -
    - - -## Forever - -Forever est un simple outil d'interface de ligne de commande qui permet de s'assurer qu'un script donné est exécuté de façon continue (forever). L'interface simple de Forever en fait un -outil idéal pour exécuter des déploiements plus petits des applications et des scripts de Node.jps. - -Pour plus d'informations, voir [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Installation - -
    -
    -$ [sudo] npm install forever -g
    -
    -
    - -### Utilisation de base - -Pour démarrer un script, utilisez la commande `forever start` et indiquez le chemin d'accès du script : - -
    -
    -$ forever start script.js
    -
    -
    - -Cette commande exécutera le script en mode démon (à l'arrière-plan). - -Pour exécuter le script de façon à ce qu'il soit joint au terminal, il ne faut pas prendre en compte `start` : - -
    -
    -$ forever script.js
    -
    -
    - -C'est une bonne idée de consigner votre sortie du script et de -l'outil Forever en utilisant les options de consignation `-l`, `-o` et `-e`, comme illustré dans l'exemple suivant : - -
    -
    -$ forever start -l forever.log -o out.log -e err.log script.js
    -
    -
    - -Pour visualiser la liste des scripts qui ont été démarrés par Forever : - -
    -
    -$ forever list
    -
    -
    - -Pour arrêter un script qui a été démarré par Forever, utilisez -la commande `forever stop` et indiquez l'index de -processus (tel qu'il est listé par la commande `forever list`). - -
    -
    -$ forever stop 1
    -
    -
    - -Sinon, indiquez le chemin d'accès du fichier : - -
    -
    -$ forever stop script.js
    -
    -
    - -Pour arrêter tous les scripts qui ont été démarrés par Forever : - -
    -
    -$ forever stopall
    -
    -
    - -Forever possède beaucoup d'autres options, et il fournit également une API programmable. diff --git a/fr/advanced/security-updates.md b/fr/advanced/security-updates.md old mode 100755 new mode 100644 index 57b8a0009b..251d8092a6 --- a/fr/advanced/security-updates.md +++ b/fr/advanced/security-updates.md @@ -1,44 +1,87 @@ --- layout: page title: Express security updates +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: fr +redirect_from: " " --- # Mises à jour de sécurité
    -Les vulnérabilités Node.js affectent directement Express. Cependant, [gardez un oeil sur les vulnérabilités Node.js](http://blog.nodejs.org/vulnerability/) et assurez-vous d'utiliser la dernière version stable de Node.js. +Les vulnérabilités Node.js affectent directement Express. Cependant, [gardez un oeil sur les vulnérabilités Node.js](https://nodejs.org +/en/blog/vulnerability/) et assurez-vous d'utiliser la dernière version stable de Node.js.
    La liste ci-dessous répertorie les vulnérabilités Express qui ont été corrigées dans la mise à jour de la version spécifiée. +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} + ## 4.x - * 4.11.1 - * Correction de la vulnérabilité de divulgation de racine dans `express.static`, `res.sendfile` et `res.sendFile` - * 4.10.7 - * Correction de la vulnérabilité de redirection ouverte dans `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 4.8.8 - * Correction des vulnérabilités de traversée de répertoire dans `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 peut divulguer des `fd` dans certaines situations qui affectent `express.static` et `res.sendfile`. Des demandes malveillantes pouvaient entraîner la divulgation de `fd`, ainsi que des erreurs `EMFILE` et une absence de réponse du serveur. - * 4.8.0 - * Les tableaux creux qui possèdent des index très élevés dans la chaîne de requête pouvaient entraîner la saturation de mémoire et la panne du serveur. - * Les objets contenant des chaînes de requête extrêmement imbriquées pouvaient entraîner le blocage du processus et figer temporairement le serveur. +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. + - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. +- 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +- 4.15.2 + - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - Correction de la vulnérabilité de divulgation de racine dans `express.static`, `res.sendfile` et `res.sendFile` +- 4.10.7 + - Correction de la vulnérabilité de redirection ouverte dans `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 4.8.8 + - Correction des vulnérabilités de traversée de répertoire dans `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 peut divulguer des `fd` dans certaines situations qui affectent `express.static` et `res.sendfile`. Des demandes malveillantes pouvaient entraîner la divulgation de `fd`, ainsi que des erreurs `EMFILE` et une absence de réponse du serveur. +- 4.8.0 + - Les tableaux creux qui possèdent des index très élevés dans la chaîne de requête pouvaient entraîner la saturation de mémoire et la panne du serveur. + - Les objets contenant des chaînes de requête extrêmement imbriquées pouvaient entraîner le blocage du processus et figer temporairement le serveur. ## 3.x - * 3.19.1 - * Correction de la vulnérabilité de divulgation de racine dans `express.static`, `res.sendfile` et `res.sendFile` - * 3.19.0 - * Correction de la vulnérabilité de redirection ouverte dans `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Correction des vulnérabilités de traversée de répertoire dans `express.static`. - * 3.16.6 - * Node.js 0.10 peut divulguer des `fd` dans certaines situations qui affectent `express.static` et `res.sendfile`. Des demandes malveillantes pouvaient entraîner la divulgation de `fd`, ainsi que des erreurs `EMFILE` et une absence de réponse du serveur. - * 3.16.0 - * Les tableaux creux qui possèdent des index très élevés dans la chaîne de requête pouvaient entraîner la saturation de mémoire et la panne du serveur. - * Les objets contenant des chaînes de requête extrêmement imbriquées pouvaient entraîner le blocage du processus et figer temporairement le serveur. - * 3.3.0 - * La réponse 404 à une tentative de substitution de méthode non prise en charge était susceptible d'entraîner des attaques de type cross-site scripting. +
    + **Express 3.x N'EST PLUS PRIS EN CHARGE** + +Les problèmes de performances et de sécurité connus et inconnus n'ont pas été traités depuis la dernière mise à jour (1er août 2015). Il est fortement recommandé d'utiliser la dernière version d'Express. + +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). + +
    + +- 3.19.1 + - Correction de la vulnérabilité de divulgation de racine dans `express.static`, `res.sendfile` et `res.sendFile` +- 3.19.0 + - Correction de la vulnérabilité de redirection ouverte dans `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 3.16.10 + - Correction des vulnérabilités de traversée de répertoire dans `express.static`. +- 3.16.6 + - Node.js 0.10 peut divulguer des `fd` dans certaines situations qui affectent `express.static` et `res.sendfile`. Des demandes malveillantes pouvaient entraîner la divulgation de `fd`, ainsi que des erreurs `EMFILE` et une absence de réponse du serveur. +- 3.16.0 + - Les tableaux creux qui possèdent des index très élevés dans la chaîne de requête pouvaient entraîner la saturation de mémoire et la panne du serveur. + - Les objets contenant des chaînes de requête extrêmement imbriquées pouvaient entraîner le blocage du processus et figer temporairement le serveur. +- 3.3.0 + - La réponse 404 à une tentative de substitution de méthode non prise en charge était susceptible d'entraîner des attaques de type cross-site scripting. \ No newline at end of file diff --git a/fr/api.md b/fr/api.md old mode 100755 new mode 100644 index fec7001812..a49068f28f --- a/fr/api.md +++ b/fr/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - Référence de l'API -lang: fr +layout: api +version: 5x +title: Express 5.x - Référence de l'API +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api +redirect_from: " " --- -
    - -

    API 4.x

    - - - {% include api/en/4x/express.md %} +
    +

    5.x API

    + {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
    diff --git a/fr/changelog/index.md b/fr/changelog/index.md new file mode 100644 index 0000000000..2456265b18 --- /dev/null +++ b/fr/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/fr/guide/behind-proxies.md b/fr/guide/behind-proxies.md old mode 100755 new mode 100644 index 594f7e7d5b..914fd6ebbf --- a/fr/guide/behind-proxies.md +++ b/fr/guide/behind-proxies.md @@ -1,70 +1,85 @@ --- layout: page title: Serveurs proxy derrière Express +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: fr +redirect_from: " " --- -# Express derrière proxys +# Serveurs proxy derrière Express -Lorsque vous exécutez une application Express derrière un proxy, affectez à la variable d'application `trust proxy` l'une des valeurs indiquées dans le tableau suivant, en utilisant [app.set()](/{{ page.lang }}/4x/api.html#app.set). +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
    -L'exécution de l'application n'échouera pas si la variable d'application `trust proxy` n'est pas définie, mais l'adresse IP du proxy sera enregistrée de manière incorrecte en tant qu'adresse IP du client.`` +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
    +The application setting `trust proxy` may be set to one of the values listed in the following table. + - - + - +
    TypeValeur
    Booléen -Si la valeur est `true`, l'adresse IP du client est interprétée comme étant l'entrée la plus à gauche dans l'en-tête `X-Forwarded-*`. +Si la valeur est `true`, l'adresse IP du client est interprétée comme étant l'entrée la plus à gauche dans l'en-tête `X-Forwarded-*`. + Si la valeur est `false`, l'application est interprétée comme étant directement accessible sur Internet et l'adresse IP du client est dérivée de `req.connection.remoteAddress`. Il s'agit du paramètre par défaut. + +
    +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
    Adresses IPIP addresses -Adresse IP, sous-réseau ou tableau d'adresses IP et de sous-réseaux auxquels faire confiance. La liste suivante montre les noms de sous-réseau préconfigurés : -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: + +- loopback - `127.0.0.1/8`, `::1/128` +- linklocal - `169.254.0.0/16`, `fe80::/10` +- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` Vous pouvez définir les adresses IP de l'une des manières suivantes : -
    -app.set('trust proxy', 'loopback') // specify a single subnet
    +```js
    +app.set('trust proxy', 'loopback') // specify a single subnet
     app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
     app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
    -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
    -
    +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` + +S'ils sont spécifiés, les sous-réseaux ou les adresses IP sont exclus du processus d'identification d'adresse, et l'adresse IP sans confiance la plus proche du serveur d'applications est identifiée comme étant l'adresse IP du client. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. -S'ils sont spécifiés, les sous-réseaux ou les adresses IP sont exclus du processus d'identification d'adresse, et l'adresse IP sans confiance la plus proche du serveur d'applications est identifiée comme étant l'adresse IP du client.
    Numérique -Approuve le `n`ème tronçon à partir proxy de face comme étant le client. +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. + +
    +When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
    FonctionFunction -Implémentation de confiance personnalisée. N'utilisez cette option que si vous êtes sûr de vous. -
    -app.set('trust proxy', function (ip) {
    -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
    -  else return false;
    -});
    -
    +Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
    -La définition d'une valeur autre que `false` `trust proxy` entraîne trois modifications importantes : +Enabling `trust proxy` will have the following impact:
    • La valeur de [req.hostname](/{{ page.lang }}/api.html#req.hostname) est dérivée de l'ensemble de valeurs indiqué dans l'en-tête `X-Forwarded-Host`, qui peut être défini par le client ou par le proxy. diff --git a/fr/guide/database-integration.md b/fr/guide/database-integration.md old mode 100755 new mode 100644 index 9d8fd0eeb4..ffd2a8bcbb --- a/fr/guide/database-integration.md +++ b/fr/guide/database-integration.md @@ -1,226 +1,268 @@ --- layout: page title: Express database integration +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: fr +redirect_from: " " --- # Intégration de bases de données L'ajout de la fonctionnalité permettant de connecter des bases de données aux applications Express consiste simplement à charger un pilote Node.js approprié pour les bases de données de votre application. Ce document explique brièvement comment ajouter et utiliser dans votre application Express certains des modules Node.js les plus populaires pour les systèmes de base de données : -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongo) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgres) +- [Redis](#redis) +- +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
      -Ces pilotes de base de données ne sont qu'une partie de ceux disponibles. Pour d'autres options, +Ces pilotes de base de données ne sont qu'une partie de ceux disponibles. Pour d'autres options, consultez le site [npm](https://www.npmjs.com/).
      - - ## Cassandra **Module** : [cassandra-driver](https://github.com/datastax/nodejs-driver) **Installation** -
      -
      +### Installation
      +
      +```bash
       $ npm install cassandra-driver
      -
      -
      +``` -**Exemple** +### Exemple -
      -
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      +```js
      +const cassandra = require('cassandra-driver')
      +const client = new cassandra.Client({ contactPoints: ['localhost'] })
      +
      +client.execute('select key from system.local', (err, result) => {
      +  if (err) throw err
      +  console.log(result.rows[0])
      +})
      +```
       
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      -
      +## Couchbase - +**Module**: [couchnode](https://github.com/couchbase/couchnode) + +### Installation + +```bash +$ npm install couchbase +``` + +### Exemple + +```js +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') + +// add a document to a bucket +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) + +// get all documents with shoe size 13 +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) +``` ## CouchDB **Module** : [nano](https://github.com/dscape/nano) **Installation** -
      -
      +### Installation
      +
      +```bash
       $ npm install nano
      -
      -
      +``` -**Exemple** +### Exemple -
      -
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      +```js
      +const nano = require('nano')('http://localhost:5984')
      +nano.db.create('books')
      +const books = nano.db.use('books')
       
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      +// Insert a book document in the books database
      +books.insert({ name: 'The Art of war' }, null, (err, body) => {
      +  if (err) {
      +    console.log(err)
      +  } else {
      +    console.log(body)
         }
      -});
      +})
       
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      -
      - - +// Get a list of all books +books.list((err, body) => { + if (err) { + console.log(err) + } else { + console.log(body.rows) + } +}) +``` ## LevelDB **Module** : [levelup](https://github.com/rvagg/node-levelup) **Installation** -
      -
      -$ npm install level levelup leveldown
      -
      -
      +### Installation -**Exemple** +```bash +$ npm install level levelup leveldown +``` -
      -
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      +### Exemple
       
      -db.put('name', 'LevelUP', function (err) {
      +```js
      +const levelup = require('levelup')
      +const db = levelup('./mydb')
       
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      +db.put('name', 'LevelUP', (err) => {
      +  if (err) return console.log('Ooops!', err)
       
      -});
      -
      -
      + db.get('name', (err, value) => { + if (err) return console.log('Ooops!', err) - + console.log(`name=${value}`) + }) +}) +``` ## MySQL **Module** : [mysql](https://github.com/felixge/node-mysql/) **Installation** -
      -
      +### Installation
      +
      +```bash
       $ npm install mysql
      -
      -
      +``` -**Exemple** +### Exemple -
      -
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      +```js
      +const mysql = require('mysql')
      +const connection = mysql.createConnection({
      +  host: 'localhost',
      +  user: 'dbuser',
      +  password: 's3kreee7',
      +  database: 'my_db'
      +})
       
      -connection.connect();
      +connection.connect()
       
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
      +  if (err) throw err
       
      -connection.end();
      -
      -
      + console.log('The solution is: ', rows[0].solution) +}) - +connection.end() +``` ## MongoDB **Module** : [mongodb](https://github.com/mongodb/node-mongodb-native) **Installation** -
      -
      +### Installation
      +
      +```bash
       $ npm install mongodb
      -
      -
      +``` -**Exemple** +### Example (v2.\*) -
      -
      -var MongoClient = require('mongodb').MongoClient;
      +```js
      +const MongoClient = require('mongodb').MongoClient
       
      -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
      -  if (err) {
      -    throw err;
      -  }
      -  db.collection('mammals').find().toArray(function(err, result) {
      -    if (err) {
      -      throw err;
      -    }
      -    console.log(result);
      -  });
      -});
      -
      -
      +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { + if (err) throw err -Si vous voulez un pilote de modèle d'objet pour MongoDB, recherchez [Mongoose](https://github.com/LearnBoost/mongoose). + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +### Example (v3.\*) + +```js +const MongoClient = require('mongodb').MongoClient + +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { + if (err) throw err + + const db = client.db('animals') + + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` - +Si vous voulez un pilote de modèle d'objet pour MongoDB, recherchez [Mongoose](https://github.com/LearnBoost/mongoose). ## Neo4j **Module** : [apoc](https://github.com/hacksparrow/apoc) **Installation** -
      -
      -$ npm install apoc
      -
      -
      +### Installation -**Exemple** +```bash +$ npm install neo4j-driver +``` -
      -
      -var apoc = require('apoc');
      +### Exemple
       
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      -  }
      -);
      -
      -
      +```js +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) - +const session = driver.session() + +session.readTransaction((tx) => { + return tx.run('MATCH (n) RETURN count(n) AS count') + .then((res) => { + console.log(res.records[0].get('count')) + }) + .catch((error) => { + console.log(error) + }) +}) +``` ## Oracle @@ -228,9 +270,9 @@ apoc.query('match (n) return n').exec().then( ### Installation - Remarque: [Voir les conditions préalables à l'installation](https://github.com/oracle/node-oracledb#-installation). +Remarque: [Voir les conditions préalables à l'installation](https://github.com/oracle/node-oracledb#-installation). -```sh +```bash $ npm install oracledb ``` @@ -268,137 +310,182 @@ async function getEmployee (empId) { getEmployee(101) ``` - - ## PostgreSQL **Module** : [pg-promise](https://github.com/vitaly-t/pg-promise) **Installation** -
      -
      -$ npm install pg-promise
      -
      -
      - -**Exemple** +### Installation -
      -
      -var pgp = require("pg-promise")(/*options*/);
      -var db = pgp("postgres://username:password@host:port/database");
      +```bash
      +$ npm install pg-promise
      +```
       
      -db.one("SELECT $1 AS value", 123)
      -    .then(function (data) {
      -        console.log("DATA:", data.value);
      -    })
      -    .catch(function (error) {
      -        console.log("ERROR:", error);
      -    });
      -
      -
      +### Exemple - +```js +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') + +db.one('SELECT $1 AS value', 123) + .then((data) => { + console.log('DATA:', data.value) + }) + .catch((error) => { + console.log('ERROR:', error) + }) +``` ## Redis **Module** : [redis](https://github.com/mranney/node_redis) **Installation** -
      -
      +### Installation
      +
      +```bash
       $ npm install redis
      -
      -
      +``` + +### Exemple -**Exemple** +```js +const redis = require('redis') +const client = redis.createClient() + +client.on('error', (err) => { + console.log(`Error ${err}`) +}) -
      -
      -var client = require('redis').createClient();
      +client.set('string key', 'string val', redis.print)
      +client.hset('hash key', 'hashtest 1', 'some value', redis.print)
      +client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
       
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      +client.hkeys('hash key', (err, replies) => {
      +  console.log(`${replies.length} replies:`)
       
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      +  replies.forEach((reply, i) => {
      +    console.log(`    ${i}: ${reply}`)
      +  })
      +
      +  client.quit()
      +})
      +```
       
      -client.hkeys('hash key', function (err, replies) {
      +## SQL Server
       
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      +**Module**: [tedious](https://github.com/tediousjs/tedious)
       
      -  client.quit();
      +### Installation
       
      -});
      -
      -
      +```bash +$ npm install tedious +``` - +### Exemple + +```js +const Connection = require('tedious').Connection +const Request = require('tedious').Request + +const config = { + server: 'localhost', + authentication: { + type: 'default', + options: { + userName: 'your_username', // update me + password: 'your_password' // update me + } + } +} + +const connection = new Connection(config) + +connection.on('connect', (err) => { + if (err) { + console.log(err) + } else { + executeStatement() + } +}) + +function executeStatement () { + request = new Request("select 123, 'hello world'", (err, rowCount) => { + if (err) { + console.log(err) + } else { + console.log(`${rowCount} rows`) + } + connection.close() + }) + + request.on('row', (columns) => { + columns.forEach((column) => { + if (column.value === null) { + console.log('NULL') + } else { + console.log(column.value) + } + }) + }) + + connection.execSql(request) +} +``` ## SQLite **Module** : [sqlite3](https://github.com/mapbox/node-sqlite3) **Installation** -
      -
      -$ npm install sqlite3
      -
      -
      +### Installation -**Exemple** +```bash +$ npm install sqlite3 +``` -
      -
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      +### Exemple
       
      -db.serialize(function() {
      +```js
      +const sqlite3 = require('sqlite3').verbose()
      +const db = new sqlite3.Database(':memory:')
       
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      +db.serialize(() => {
      +  db.run('CREATE TABLE lorem (info TEXT)')
      +  const stmt = db.prepare('INSERT INTO lorem VALUES (?)')
       
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      +  for (let i = 0; i < 10; i++) {
      +    stmt.run(`Ipsum ${i}`)
         }
       
      -  stmt.finalize();
      +  stmt.finalize()
       
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      +  db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
      +    console.log(`${row.id}: ${row.info}`)
      +  })
      +})
       
      -db.close();
      -
      -
      - - +db.close() +``` ## ElasticSearch **Module** : [elasticsearch](https://github.com/elastic/elasticsearch-js) **Installation** -
      -
      +### Installation
      +
      +```bash
       $ npm install elasticsearch
      -
      -
      +``` -**Exemple** +### Exemple -
      -
      -var elasticsearch = require('elasticsearch');
      -var client = elasticsearch.Client({
      +```js
      +const elasticsearch = require('elasticsearch')
      +const client = elasticsearch.Client({
         host: 'localhost:9200'
      -});
      +})
       
       client.search({
         index: 'books',
      @@ -411,10 +498,9 @@ client.search({
             }
           }
         }
      -}).then(function(response) {
      -  var hits = response.hits.hits;
      -}, function(error) {
      -  console.trace(error.message);
      -});
      -
      -
      +}).then((response) => { + const hits = response.hits.hits +}, (error) => { + console.trace(error.message) +}) +``` diff --git a/fr/guide/debugging.md b/fr/guide/debugging.md old mode 100755 new mode 100644 index 8593b445f1..1053f85bf1 --- a/fr/guide/debugging.md +++ b/fr/guide/debugging.md @@ -1,41 +1,28 @@ --- layout: page title: Débogage d'Express +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: fr +redirect_from: " " --- # Débogage d'Express -Express fait appel au module [debug](https://www.npmjs.com/package/debug) en interne -pour journaliser les informations concernant les correspondances de route, les fonctions middleware utilisées, le -mode de l'application ainsi que le flux du cycle de demande-réponse. - -
      -Le module `debug` est en quelque sorte une version étendue de `console.log`, mais contrairement à ce dernier,`` vous n'avez pas besoin de mettre en commentaire les journaux de -`debug` dans le code de production. La journalisation est désactivée par défaut et peut être activée de manière conditionnelle à l'aide de la variable d'environnement `DEBUG`. -
      - Pour afficher tous les journaux internes utilisés dans Express, affectez à la variable d'environnement `DEBUG` la valeur `express:*` lors du lancement de votre application. -
      -
      +```bash
       $ DEBUG=express:* node index.js
      -
      -
      +``` Sous Windows, utilisez la commande correspondante. -
      -
      -> set DEBUG=express:* & node index.js
      -
      -
      +```bash +> $env:DEBUG = "express:*"; 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](/{{ page.lang }}/starter/generator.html) imprime le résultat suivant : -
      -
      +```bash
       $ DEBUG=express:* node ./bin/www
         express:router:route new / +0ms
         express:router:layer new / +1ms
      @@ -71,19 +58,17 @@ $ DEBUG=express:* node ./bin/www
         express:router:layer new / +1ms
         express:router use /users router +0ms
         express:router:layer new /users +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -
      -
      +``` Si une demande est par la suite effectuée à 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
      @@ -99,29 +84,46 @@ Si une demande est par la suite effectuée à l'application, vous verrez les jou
         express:view lookup "index.pug" +338ms
         express:view stat "/projects/example/views/index.pug" +0ms
         express:view render "/projects/example/views/index.pug" +1ms
      -
      -
      +``` Pour afficher les journaux uniquement à partir de l'implémentation du routeur, affectez à la variable d'environnement `DEBUG` la valeur `express:router`. De la même façon, pour afficher les journaux uniquement à partir de l'implémentation de l'application, affectez à la variable d'environnement `DEBUG` la valeur `express:application`, et ainsi de suite. ## Applications générées par la commande `express` -Une application générée par la commande `express` fait également appel au module `debug` et son espace de nom de débogage est délimité par le nom de l'application. +Une application générée par la commande `express` également appel au module `debug` et son espace de nom de débogage est délimité par le nom de l'application. Ainsi, si vous avez généré l'application à l'aide de `$ express sample-app`, vous pouvez activer les instructions de débogage en exécutant la commande suivante : -
      -
      +```bash
       $ DEBUG=sample-app:* node ./bin/www
      -
      -
      +``` Vous pouvez spécifier plusieurs espaces de noms de débogage en affectant une liste de noms séparés par des virgules : -
      -
      +```bash
       $ DEBUG=http,mail,express:* node index.js
      -
      -
      +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -Pour plus d'informations sur le module `debug`, voir [debug](https://www.npmjs.com/package/debug). +{% include admonitions/note.html content=debug-text %} diff --git a/fr/guide/error-handling.md b/fr/guide/error-handling.md old mode 100755 new mode 100644 index fe1e09e421..41a4381130 --- a/fr/guide/error-handling.md +++ b/fr/guide/error-handling.md @@ -1,124 +1,146 @@ --- layout: page title: Traitement d'erreurs Express +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: fr +redirect_from: " " --- # Traitement d'erreurs -Définissez les fonctions middleware de traitement d'erreurs de la même manière que les autres fonctions middleware, -à l'exception près que les fonctions de traitement d'erreurs se composent de quatre arguments et non de trois : -`(err, req, res, next)`. Par exemple : +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      +## Catching Errors -Définissez le middleware de traitement d'erreurs en dernier, après les autres appels `app.use()` et de routes ; par exemple : +It's important to ensure that Express catches all errors that occur while +running route handlers and middleware. -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +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. Par exemple :
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      -  // logic
      -});
      -
      -
      +```js +app.get('/', (req, res) => { + throw new Error('BROKEN') // Express will catch this on its own. +}) +``` -Les réponses issues d'une fonction middleware peuvent être au format de votre choix, par exemple une page d'erreur HTML, un simple message ou une chaîne JSON. +Définissez les fonctions middleware de traitement d'erreurs de la même manière que les autres fonctions middleware, +à l'exception près que les fonctions de traitement d'erreurs se composent de quatre arguments et non de trois : +`(err, req, res, next)`. Par exemple : -A des fins organisationnelles (et d'infrastructure de niveau supérieur), vous pouvez définir plusieurs fonctions middleware de traitement d'erreurs, tout comme vous le feriez avec d'autres fonctions middleware ordinaires. -Par exemple, si vous vouliez définir un gestionnaire d'erreurs pour les demandes réalisées avec `XHR` et pour celles réalisées sans, vous pourriez utiliser les commandes suivantes : +```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) + } + }) +}) +``` -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +Si vous disposez d'un gestionnaire de routage avec plusieurs fonctions callback, vour pouvez utiliser le paramètre `route` pour passer au gestionnaire de routage suivant.
      +Par exemple :
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      -
      +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` -Dans cet exemple, les erreurs `logErrors` génériques pourraient écrire des informations de demande et d'erreur dans `stderr`, par exemple : +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. -
      -
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      -
      +Si vous transmettez tout à la fonction `next()` (sauf la chaîne `'route'`), Express considère la demande en cours +comme étant erronée et ignorera tout routage de gestion non lié à une erreur et toute fonction middleware restants. -Egalement dans cet exemple, `clientErrorHandler` est défini comme suit ; dans ce cas, l'erreur est explicitement transmise à la fonction suivante : +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: -
      -
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      -  } else {
      -    next(err);
      +```js
      +app.get('/', [
      +  function (req, res, next) {
      +    fs.writeFile('/inaccessible-path', 'data', next)
      +  },
      +  function (req, res) {
      +    res.send('OK')
         }
      -}
      -
      -
      +]) +``` -La fonction "catch-all" `errorHandler` peut être mise en oeuvre comme suit : +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. -
      -
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      +You must catch errors that occur in asynchronous code invoked by route handlers or +middleware and pass them to Express for processing. Par exemple : -Si vous transmettez tout à la fonction `next()` (sauf la chaîne `'route'`), Express considère la demande en cours -comme étant erronée et ignorera tout routage de gestion non lié à une erreur et toute fonction middleware restants. Si vous voulez gérer cette erreur de quelque façon que ce soit, vous devrez créer -une route de gestion d'erreur tel que décrit dans la section suivante. +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN') + } catch (err) { + next(err) + } + }, 100) +}) +``` -Si vous disposez d'un gestionnaire de routage avec plusieurs fonctions callback, vour pouvez utiliser le paramètre `route` pour passer au gestionnaire de routage suivant. Par exemple : +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. -
      -
      -app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      +Use promises to avoid the overhead of the `try...catch` block or when using functions
      +that return promises.  Par exemple :
       
      -      // continue handling this request
      -      next('route');
      -    }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      -
      +```js +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { + throw new Error('BROKEN') + }).catch(next) // Errors will be passed to Express. +}) +``` -Dans cet exemple, le gestionnaire `getPaidContent` sera ignoré, mais tous les gestionnaires restants dans `app` pour `/a_route_behind_paywall` continueront d'être exécutés. +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. -
      -Les appels `next()` et `next(err)` indiquent que le gestionnaire en cours a fini et quel est son état. -`next(err)` ignorera tous les gestionnaires restants dans la chaîne, sauf ceux définis pour gérer les erreurs tel que décrit ci-dessus. -
      +You could also use a chain of handlers to rely on synchronous error +catching, by reducing the asynchronous code to something trivial. Par exemple : + +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +The above example has a couple of trivial statements from 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 +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. + +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. ## Le gestionnaire de traitement d'erreurs par défaut @@ -132,6 +154,16 @@ trace de pile. La trace de pile n'est pas incluse dans l'environnement de produc Définissez la variable d'environnement `NODE_ENV` sur `production` afin d'exécuter l'application en mode production.
    +When an error is written, the following information is added to the +response: + +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. + Si vous appelez `next()` avec une erreur après avoir démarré l'écriture de la réponse (par exemple, si vous rencontrez une erreur lors de la diffusion en flux de la réponse au client) le gestionnaire de traitement d'erreurs par défaut Express ferme la @@ -141,14 +173,121 @@ De ce fait, lorsque vous ajoutez un gestionnaire d'erreurs personnalisé, vous d les mécanismes de gestion d'erreur par défaut à Express, lorsque les en-têtes ont déjà été envoyés au client : -
    -
    -function errorHandler(err, req, res, next) {
    +```js
    +function errorHandler (err, req, res, next) {
       if (res.headersSent) {
    -    return next(err);
    +    return next(err)
    +  }
    +  res.status(500)
    +  res.render('error', { error: err })
    +}
    +```
    +
    +Note that the default error handler can get triggered if you call `next()` with an error
    +in your code more than once, even if custom error handling middleware is in place.
    +
    +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html).
    +
    +## Writing error handlers
    +
    +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)`. Par exemple :
    +
    +```js
    +app.use((err, req, res, next) => {
    +  console.error(err.stack)
    +  res.status(500).send('Something broke!')
    +})
    +```
    +
    +Définissez le middleware de traitement d'erreurs en dernier, après les autres appels `app.use()` et de routes ; par exemple :
    +
    +```js
    +const bodyParser = require('body-parser')
    +const methodOverride = require('method-override')
    +
    +app.use(bodyParser.urlencoded({
    +  extended: true
    +}))
    +app.use(bodyParser.json())
    +app.use(methodOverride())
    +app.use((err, req, res, next) => {
    +  // logic
    +})
    +```
    +
    +Les réponses issues d'une fonction middleware peuvent être au format de votre choix, par exemple une page d'erreur HTML, un simple message ou une chaîne JSON.
    +
    +A des fins organisationnelles (et d'infrastructure de niveau supérieur), vous pouvez définir plusieurs fonctions middleware de traitement d'erreurs, tout comme vous le feriez avec d'autres fonctions middleware ordinaires. Par exemple, si vous vouliez définir un gestionnaire d'erreurs pour les demandes réalisées avec `XHR` et pour celles réalisées sans, vous pourriez utiliser les commandes suivantes :
    +
    +```js
    +const bodyParser = require('body-parser')
    +const methodOverride = require('method-override')
    +
    +app.use(bodyParser.urlencoded({
    +  extended: true
    +}))
    +app.use(bodyParser.json())
    +app.use(methodOverride())
    +app.use(logErrors)
    +app.use(clientErrorHandler)
    +app.use(errorHandler)
    +```
    +
    +Dans cet exemple, les erreurs `logErrors` génériques pourraient écrire des informations de demande et d'erreur dans `stderr`, par exemple :
    +
    +```js
    +function logErrors (err, req, res, next) {
    +  console.error(err.stack)
    +  next(err)
    +}
    +```
    +
    +Egalement dans cet exemple, `clientErrorHandler` est défini comme suit ; dans ce cas, l'erreur est explicitement transmise à la fonction suivante :
    +
    +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.
    +
    +```js
    +function clientErrorHandler (err, req, res, next) {
    +  if (req.xhr) {
    +    res.status(500).send({ error: 'Something failed!' })
    +  } else {
    +    next(err)
       }
    -  res.status(500);
    -  res.render('error', { error: err });
     }
    -
    -
    +``` + +La fonction "catch-all" `errorHandler` peut être mise en oeuvre comme suit : + +```js +function errorHandler (err, req, res, next) { + res.status(500) + res.render('error', { error: err }) +} +``` + +If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. Par exemple : + +```js +app.get('/a_route_behind_paywall', + (req, res, next) => { + if (!req.user.hasPaid) { + // continue handling this request + next('route') + } else { + next() + } + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` + +Dans cet exemple, le gestionnaire `getPaidContent` sera ignoré, mais tous les gestionnaires restants dans `app` pour `/a_route_behind_paywall` continueront d'être exécutés. + +
    +Les appels `next()` et `next(err)` indiquent que le gestionnaire en cours a fini et quel est son état. `next(err)` ignorera tous les gestionnaires restants dans la chaîne, sauf ceux définis pour gérer les erreurs tel que décrit ci-dessus. +
    diff --git a/fr/guide/migrating-4.md b/fr/guide/migrating-4.md old mode 100755 new mode 100644 index 1d51088405..025f22c378 --- a/fr/guide/migrating-4.md +++ b/fr/guide/migrating-4.md @@ -1,8 +1,9 @@ --- layout: page title: Migration vers Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: fr +redirect_from: " " --- # Migration vers Express 4 @@ -24,7 +25,7 @@ Cet article couvre : De nombreuses modifications importantes ont été faites dans Express 4 :
      -
    • Modification du système principal et middleware d'Express. Les dépendances Connect et des middleware intégrés ont été supprimées, vous devez donc ajouter les middleware vous-même. +
    • Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
    • Modifications du système de routage.
    • Autres modifications diverses.
    • @@ -32,8 +33,8 @@ De nombreuses modifications importantes ont été faites dans Express 4 : Voir aussi : -* [Nouvelles fonctions dans la version 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migration de la version 3.x vers 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [Nouvelles fonctions dans la version 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [Migration de la version 3.x vers 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

      Modification du système principal et middleware d'Express @@ -53,7 +54,7 @@ middleware requis pour exécuter votre application. Procédez comme suit : La table suivante répertorie le middelware Express 3 et ces équivalents dans Express 4. - + @@ -85,7 +86,7 @@ La table suivante répertorie le middelware Express 3 et ces équivalents dans E -
      Express 3Express 4
      Express 3Express 4
      express.bodyParser body-parser + multer
      serve-index
      express.static serve-static
      + Vous trouverez ici la [liste complète](https://github.com/senchalabs/connect#middleware) du middleware Express 4. @@ -98,14 +99,13 @@ GitHub. Dans la version 4 vous pouvez utilisez un paramètre variable pour définir le chemin vers lequel les fonctions middleware sont chargées, puis lire la valeur de ce paramètre dans le gestionnaire de routage. Par exemple : -
      -
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -});
      -
      -
      +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` +

      Le système de routage

      @@ -117,8 +117,9 @@ La façon de définir des routes n'a pas changé mais le système de routage pos pour vous aider à organiser vos routes : {: .doclist } -* Une nouvelle méthode, `app.route()`, permettant de créer des gestionnaires de routage sous forme de chaîne pour un chemin de routage. -* Une nouvelle classe, `express.Router`, permettant de créer des gestionnaires de routage modulaires pouvant être montés. + +- Une nouvelle méthode, `app.route()`, permettant de créer des gestionnaires de routage sous forme de chaîne pour un chemin de routage. +- Une nouvelle classe, `express.Router`, permettant de créer des gestionnaires de routage modulaires pouvant être montés.

      méthode app.route()

      @@ -126,20 +127,18 @@ La nouvelle méthode `app.route()` vous permet de créer des gestionnaires de ro Voici quelques exemples de gestionnaires de chemin de chaînage définis à l'aide de la fonction `app.route()`. -
      -
      +```js
       app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      +  .get((req, res) => {
      +    res.send('Get a random book')
      +  })
      +  .post((req, res) => {
      +    res.send('Add a book')
         })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      +  .put((req, res) => {
      +    res.send('Update the book')
         })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      +```

      classe express.Router

      @@ -151,38 +150,36 @@ L'exemple suivant créé une routeur en tant que module, charge un middleware da Par exemple, créez un fichier de routage nommé `birds.js` dans le répertoire app, avec le contenu suivant : -
      -
      -var express = require('express');
      -var router = express.Router();
      +```js
      +var express = require('express')
      +var router = express.Router()
       
       // middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      +router.use((req, res, next) => {
      +  console.log('Time: ', Date.now())
      +  next()
      +})
       // define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      +router.get('/', (req, res) => {
      +  res.send('Birds home page')
      +})
       // define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      +router.get('/about', (req, res) => {
      +  res.send('About birds')
      +})
       
      -module.exports = router;
      -
      -
      +module.exports = router +``` Puis, chargez le module de routage dans l'application : -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      +```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` L'application pourra gérer des demandes dans les chemins `/birds` et `/birds/about`, et appellera le middleware `timeLog` spécifique à la route. @@ -194,7 +191,7 @@ Autres modifications Le tableau suivant répertorie les autres modifications mineures mais importantes dans Express 4 : - + @@ -252,7 +249,7 @@ Ne résout plus les adresses URL relatives. `req.params` @@ -304,7 +301,7 @@ Cette fonctionnalité se limite désormais à définir la valeur de cookie de ba `res.cookie()` pour plus de fonctionnalités. -
      Objet Description
      -Anciennement un tableau ; il s'agit dorénavant d'un objet. +Was an array; now an object.
      +

      Exemple de migration d'application

      @@ -319,48 +316,45 @@ Application de la version 3 Examinons une application Express v.3 avec le fichier `app.js` suivant : -
      -
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      +```js
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var http = require('http')
      +var path = require('path')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(express.favicon())
      +app.use(express.logger('dev'))
      +app.use(express.methodOverride())
      +app.use(express.session({ secret: 'your secret here' }))
      +app.use(express.bodyParser())
      +app.use(app.router)
      +app.use(express.static(path.join(__dirname, 'public')))
       
       // development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(express.errorHandler())
       }
       
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

      package.json

      Voici à quoi ressemble le fichier `package.json` qui accompagne la version 3 : -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -373,8 +367,7 @@ Voici à quoi ressemble le fichier `package.json` qui accompagne la version 3 :
           "pug": "*"
         }
       }
      -
      -
      +```

      Processus @@ -383,24 +376,22 @@ Processus Commencez le processus de migration en installant le middleware requis pour l'application Express 4 et en mettant à jour Express et Pug vers leur version la plus récente respective à l'aide de la commande suivante : -
      -
      +```bash
       $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      -
      +``` Apportez les modifications suivantes à `app.js` : 1. Les fonctions Express Middleware intégrées `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` et - `express.errorHandler` ne sont plus disponibles sur l'objet - `express`. Vous devez installer leurs fonctions alternatives - manuellement et les charger dans l'application. + `express.logger`, `express.methodOverride`, + `express.session`, `express.bodyParser` et + `express.errorHandler` ne sont plus disponibles sur l'objet + `express`. Vous devez installer leurs fonctions alternatives + manuellement et les charger dans l'application. 2. Vous ne devez plus charger la fonction `app.router`. - Il ne s'agit pas d'un objet d'application Express 4 valide. Supprimez le code - `app.use(app.router);`. + Il ne s'agit pas d'un objet d'application Express 4 valide. Supprimez le code + `app.use(app.router);`. 3. Assurez-vous que les fonctions middleware sont chargées dans l'ordre correct - chargez `errorHandler` après avoir chargé les routes d'application. @@ -410,8 +401,7 @@ Apportez les modifications suivantes à `app.js` : Le fait d'exécuter la commande `npm` ci-dessus mettra à jour `package.json` comme suit : -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -424,76 +414,77 @@ Le fait d'exécuter la commande `npm` ci-dessus mettra à jour `package.json` co
           "errorhandler": "^1.1.1",
           "express": "^4.8.0",
           "express-session": "^1.7.2",
      -    "pug": "^2.0.0-beta6",
      +    "pug": "^2.0.0",
           "method-override": "^2.1.2",
           "morgan": "^1.2.2",
           "multer": "^0.1.3",
           "serve-favicon": "^2.0.1"
         }
       }
      -
      -
      +```

      app.js

      Puis, supprimez le code non valide, chargez les middleware requis et procédez aux autres changements, le cas échéant. Voici à quoi ressemble le fichier `app.js` : -
      -
      -var http = require('http');
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      +```js
      +var http = require('http')
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var path = require('path')
       
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      +var favicon = require('serve-favicon')
      +var logger = require('morgan')
      +var methodOverride = require('method-override')
      +var session = require('express-session')
      +var bodyParser = require('body-parser')
      +var multer = require('multer')
      +var errorHandler = require('errorhandler')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
      +app.use(logger('dev'))
      +app.use(methodOverride())
      +app.use(session({
      +  resave: true,
      +  saveUninitialized: true,
      +  secret: 'uwotm8'
      +}))
      +app.use(bodyParser.json())
      +app.use(bodyParser.urlencoded({ extended: true }))
      +app.use(multer())
      +app.use(express.static(path.join(__dirname, 'public')))
      +
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
       // error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(errorHandler())
       }
       
      -var server = http.createServer(app);
      -server.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```
      A mois que vous deviez utiliser le module `http` (socket.io/SPDY/HTTPS) directement, vous n'avez pas à le charger et l'application peut être démarrée comme suit : -
      -app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +

      Exécutez l'application

      @@ -501,41 +492,38 @@ A mois que vous deviez utiliser le module `http` (socket.io/SPDY/HTTPS) directem Le processus de migration est terminé et l'application est désormais une application Express 4. Pour confirmer, démarrez l'application en utilisant la commande suivante : -
      -
      +```bash
       $ node .
      -
      -
      +``` Chargez [http://localhost:3000](http://localhost:3000) - et voyez comment la page d'accueil est générée par Express 4. +et voyez comment la page d'accueil est générée par Express 4.

      Mise à niveau vers le générateur d'applications Express 4

      L'outil de ligne de commande qui permet de générer une application Express est toujours - `express`, mais pour effectuer la mise à niveau vers la nouvelle version, vous devez désinstaller - le générateur d'applications Express 3 puis installer la nouvelle version d'`express-generator`. +`express`, mais pour effectuer la mise à niveau vers la nouvelle version, vous devez désinstaller +le générateur d'applications Express 3 puis installer la nouvelle version d'`express-generator`.

      Installation

      Si le générateur d'applications Express 3 est installé sur votre système, vous devez le désinstaller : -
      -
      +```bash
       $ npm uninstall -g express
      -
      -
      +``` + En fonction de la configuration de vos privilèges de fichier et de répertoire, vous devrez exécuter cette commande avec `sudo`.A présent, installez le nouveau générateur : -
      -
      +Now install the new generator:
      +
      +```bash
       $ npm install -g express-generator
      -
      -
      +``` En fonction de la configuration de vos privilèges de fichier et de répertoire, -vous devrez exécuter cette commande avec `sudo`. +vous devrez exécuter cette commande avec `sudo`.A présent, installez le nouveau générateur : Désormais, la commande `express` sur votre système est mise à jour vers le générateur Express 4. @@ -544,19 +532,18 @@ Désormais, la commande `express` sur votre système est mise à jour vers le g Les options et les syntaxe de commande restent généralement identiques, avec les exceptions suivantes : {: .doclist } -* L'option `--sessions` a été supprimée. -* L'option `--jshtml` a été supprimée. -* L'option `--hogan` a été ajoutée à la prise en charge de [Hogan.js](http://twitter.github.io/hogan.js/). + +- L'option `--sessions` a été supprimée. +- L'option `--jshtml` a été supprimée. +- L'option `--hogan` a été ajoutée à la prise en charge de [Hogan.js](http://twitter.github.io/hogan.js/).

      Exemple

      Exécutez la commande suivante pour créer une application Express 4 : -
      -
      +```bash
       $ express app4
      -
      -
      +``` Si vous examinez le contenu du fichier `app4/app.js`, vous remarquerez que toutes les fonctions middleware (sauf `express.static`) qui sont requises pour @@ -567,11 +554,9 @@ Vous noterez également que le fichier `app.js` est désormais un module Node.js Après avoir installé les dépendances, démarrez l'application en utilisant la commande suivante : -
      -
      +```bash
       $ npm start
      -
      -
      +``` Si vous examinez le script de démarrage npm dans le fichier `package.json`, vous remarquerez dorénavant que la commande qui démarre l'application est @@ -590,26 +575,22 @@ Pour se débarrasser du répertoire `www` et garder la présentation d'Express 3 supprimez la ligne `module.exports = app;` à la fin du fichier `app.js`, puis collez le code suivant à la place : -
      -
      -app.set('port', process.env.PORT || 3000);
      +```js
      +app.set('port', process.env.PORT || 3000)
       
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      -
      +var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` Assurez-vous d'avoir chargé le module `debug` en haut du fichier `app.js` à l'aide du code suivant : -
      -
      -var debug = require('debug')('app4');
      -
      -
      +```js +var debug = require('debug')('app4') +``` Ensuite, modifiez `"start": "node ./bin/www"` dans le fichier `package.json` en `"start": "node app.js"`. Vous avez à présent déplacé la fonctionnalité depuis `./bin/www` de nouveau -dans `app.js`. Cette modification n'est pas recommandée, mais l'exercice vous aide à comprendre le mode de fonctionnement +dans `app.js`. Cette modification n'est pas recommandée, mais l'exercice vous aide à comprendre le mode de fonctionnement du fichier `./bin/www` et la raison pour laquelle le fichier `app.js` ne se lance plus seul. diff --git a/fr/guide/migrating-5.md b/fr/guide/migrating-5.md old mode 100755 new mode 100644 index 8269d4319f..656f91e3ef --- a/fr/guide/migrating-5.md +++ b/fr/guide/migrating-5.md @@ -1,33 +1,25 @@ --- layout: page title: Migration vers Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: fr +redirect_from: " " --- # Migration vers Express 5

      Présentation

      -Express 5.0 est encore au stade d'édition alpha mais voici un -aperçu des modifications qui figureront dans l'édition et la procédure -de migration de l'application Express 4 vers Express 5. - Express 5 n'est pas très différent d'Express 4 : les modifications apportées à l'API ne sont pas aussi importantes qu'entre -les versions 3.0 et 4.0. -Bien que l'API de base reste identique, des modifications radicales ont été apportées ; en d'autres termes, un programme Express 4 risque de ne pas fonctionner si +les versions 3.0 et 4.0. Bien que l'API de base reste identique, des modifications radicales ont été apportées ; en d'autres termes, un programme Express 4 risque de ne pas fonctionner si vous le mettez à jour pour utiliser Express 5. -Pour installer la dernière version alpha et pour -prévisualiser Express 5, entrez la commande suivante dans le -répertoire principal de l'application : +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -
      -
      -$ npm install express@5.0.0-alpha.2 --save
      -
      -
      +```sh +npm install "express@5" +``` Vous pouvez alors exécuter les tests automatisés pour voir les échecs et corriger les problèmes en fonction des mises à jour @@ -36,13 +28,25 @@ exécutez votre application pour détecter les erreurs qui se produisent. Vous saurez tout de suite si l'application utilise des méthodes ou des propriétés. -

      Modifications dans Express 5

      +## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: + +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). -Voici la liste des modifications (par rapport à l'édition alpha -2) qui vous concerneront en tant qu'utilisateur d'Express. -Consultez la -[demande d'extraction](https://github.com/expressjs/express/pull/2237) -pour une liste de toutes les fonctions planifiées. +

      Modifications dans Express 5

      **Méthodes et propriétés supprimées** @@ -55,32 +59,47 @@ nom pour app.param(name, fn)
    • req.param(name)
    • res.json(obj, status)
    • res.jsonp(obj, status)
    • +
    • res.redirect('back') and res.location('back')
    • +
    • res.redirect(url, status)
    • res.send(body, status)
    • res.send(status)
    • res.sendfile()
    • +
    • router.param(fn)
    • +
    • express.static.mime
    • +
    • express:router debug logs
    -**Modifié** +**Améliorations** -**Améliorations** +**Modifié** -

    Méthodes et propriétés supprimées

    +## Méthodes et propriétés supprimées Si vous utilisez une de ces méthodes ou propriétés dans votre application, elle tombera en panne. Vous devrez donc modifier votre application après la mise à jour vers la version 5. -

    app.del()

    +

    app.del()

    Express 5 ne prend plus en charge la fonction `app.del()`. Si vous utilisez cette fonction, une @@ -91,33 +110,85 @@ Initialement, `del` était utilisé au lieu de `delete` car `delete` est un mot clé réservé dans JavaScript. Cependant, à partir d'ECMAScript 6, `delete` et les autres mots clés réservés peuvent -être utilisés en toute légalité comme noms de propriété. Vous pouvez lire la -discussion qui a donné lieu à l'obsolescence de la fonction -`app.del` ici. +être utilisés en toute légalité comme noms de propriété. + +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` + +{% endcapture %} -

    app.param(fn)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) + +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

    app.param(fn)

    La signature `app.param(fn)` servait à modifier le comportement de la fonction `app.param(name, fn)`. Elle est obsolète depuis la version 4.11.0 et Express 5 ne la prend plus en charge. -

    Noms de méthodes au pluriel

    +

    Noms de méthodes au pluriel

    Les noms de méthode suivants ont été mis au pluriel. Dans Express 4, l'utilisation des anciennes méthodes ont généré un avertissement d'obsolescence. Express 5 ne les prend plus du tout en charge : +`req.acceptsLanguage()` est remplacé par +`req.acceptsLanguages()`. + `req.acceptsCharset()` est remplacé par `req.acceptsCharsets()`. `req.acceptsEncoding()` est remplacé par `req.acceptsEncodings()`. -`req.acceptsLanguage()` est remplacé par -`req.acceptsLanguages()`. +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: -

    Signe deux-points (:) de tête dans le nom de la -fonction app.param(name, fn)

    +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-pluralized-methods %} + +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    Signe deux-points (:) de tête dans le nom de la +fonction app.param(name, fn)

    Le signe deux-points (:) de tête dans le nom de la fonction `app.param(name, fn)` est une subsistance d'Express 3 et, pour des raisons de @@ -129,14 +200,45 @@ signe deux-points. Cela n'affectera normalement pas votre code si vous lisez la documentation Express 4 d'[app.param](/{{ page.lang }}/4x/api.html#app.param) car cela ne mentionne pas le signe deux-points de tête. -

    req.param(name)

    +

    req.param(name)

    Cette méthode potentiellement déroutante et dangereuse d'extraction des données de formulaire a été supprimée. Vous devrez désormais rechercher spécifiquement le nom du paramètre soumis dans l'objet `req.params`, `req.body` ou `req.query`. -

    res.json(obj, status)

    +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    Express 5 ne prend plus en charge la signature `res.json(obj, status)`. A la place, définissez le @@ -144,24 +246,110 @@ statut et enchaînez-le à la méthode `res.json()` comme suit : `res.status(status).json(obj)`. -

    res.jsonp(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    Express 5 ne prend plus en charge la signature `res.jsonp(obj, status)`. A la place, définissez le statut et enchaînez-le à la méthode `res.jsonp()` comme suit : `res.status(status).jsonp(obj)`. -

    res.send(body, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    Express 5 ne prend plus en charge la signature `res.send(obj, status)`. A la place, définissez le statut et enchaînez-le à la méthode `res.send()` comme suit : `res.status(status).send(obj)`. -

    res.send(status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} -Express 5 ne prend plus en charge la signature -res.send(statut), où *`statut`* +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    + +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    + +Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) + +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` + +

    res.send(status)

    + +Express 5 ne prend plus en charge la signature res.send(statut), où _`statut`_ est un nombre. A la place, utilisez la fonction `res.sendStatus(statusCode)` qui définit le code de statut de l'en-tête de réponse HTTP et envoie @@ -170,37 +358,248 @@ Si vous devez envoyer un nombre à l'aide de la fonction `res.send()`, mettez ce nombre entre guillemets pour qu'Express ne l'interprète pas comme une tentative d'utilisation de l'ancienne signature non prise en charge. -

    res.sendfile()

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) + +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

    res.sendfile()

    La fonction `res.sendfile()` a été remplacée par une version CamelCase `res.sendFile()` dans Express 5. -

    Modifié

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. Elle est obsolète depuis la +version 4.11.0 et Express 5 ne la prend plus en charge. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## Modifié + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` -

    app.router

    +- Regexp characters are not supported. Par exemple : + +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +Par exemple : + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    L'objet `app.router`, qui a été supprimé dans Express 4, est revenu dans Express 5. Dans la version, cet objet n'est qu'une référence dans le routeur Express de base, contrairement à Express 3, où une application devait le charger explicitement. -

    req.host

    +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    Dans Express 4, la `req.host` retirait de manière incorrecte le numéro de port s'il était présent. Dans Express 5, ce numéro de port est conservé. -

    req.query

    +

    req.query

    + +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -Dans Express 4.7 et à partir d'Express 5, l'option -d'analyseur de requêtes peut accepter `false` pour -désactiver l'analyse syntaxique de chaîne de requête lorsque vous -souhaitez utiliser votre propre fonction pour la logique d'analyse -syntaxique de chaîne de requête. +

    res.clearCookie

    -

    Améliorations

    +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. -

    res.render()

    +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## Améliorations + +

    res.render()

    Cette méthode impose désormais un comportement asynchrone pour tous les moteurs de vue. Cela évite les bogues générés par les moteurs de vue qui avaient une implémentation synchrone et qui ne prenaient pas en compte l'interface recommandée. + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/fr/guide/overriding-express-api.md b/fr/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/fr/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/fr/guide/routing.md b/fr/guide/routing.md old mode 100755 new mode 100644 index 5413e98e58..2f1a47bdff --- a/fr/guide/routing.md +++ b/fr/guide/routing.md @@ -1,28 +1,38 @@ --- layout: page title: Routage Express +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: fr +redirect_from: " " --- # Routage -*Routage* fait référence à la définition de points finaux d'application (URI) et à la façon dont ils répondent aux demandes client. +_Routage_ fait référence à la définition de points finaux d'application (URI) et à la façon dont ils répondent aux demandes client. Pour une introduction au routage, voir [Basic routing](/{{ page.lang }}/starter/basic-routing.html). +You define routing using methods of the Express `app` object that correspond to HTTP methods; +for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). + +These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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 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 +to the next callback. + Le code suivant est un exemple de routage très basique. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
     // respond with "hello world" when a GET request is made to the homepage
    -app.get('/', function(req, res) {
    -  res.send('hello world');
    -});
    -
    -
    +app.get('/', (req, res) => { + res.send('hello world') +}) +```

    Méthodes de routage

    @@ -30,151 +40,207 @@ Une méthode de routage est dérivée de l'une des méthodes HTTP, et est liée Le code suivant est un exemple de routes qui sont définies pour les méthodes GET et POST jusqu'à la route de l'application. -
    -
    +```js
     // GET method route
    -app.get('/', function (req, res) {
    -  res.send('GET request to the homepage');
    -});
    +app.get('/', (req, res) => {
    +  res.send('GET request to the homepage')
    +})
     
     // POST method route
    -app.post('/', function (req, res) {
    -  res.send('POST request to the homepage');
    -});
    -
    -
    +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` -Express prend en charge les méthodes de routage suivantes qui correspondent aux méthodes HTTP : `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search`, and `connect`. - -
    -Pour router des méthodes qui se traduisent par des noms de variables JavaScript non valides, utilisez la notation entre crochets. For example, -`app['m-search']('/', function ...` -
    +Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). Il existe une méthode de routage spéciale, `app.all()`, qui n'est pas dérivée d'une méthode HTTP. Cette méthode est utilisée pour charger des fonctions middleware à un chemin d'accès pour toutes les méthodes de demande. -Dans l'exemple suivant, le gestionnaire sera exécuté pour les demandes de "/secret", que vous utilisiez GET, POST, PUT, DELETE ou toute autre méthode de demande HTTP prise en charge dans le [module http](https://nodejs.org/api/http.html#http_http_methods). - -
    -
    -app.all('/secret', function (req, res, next) {
    -  console.log('Accessing the secret section ...');
    -  next(); // pass control to the next handler
    -});
    -
    -
    +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +```

    Chemins de routage

    Les chemins de routage, combinés à une méthode de demande, définissent les noeuds finaux sur lesquels peuvent être effectuées les demandes. Les chemins de routage peuvent être des chaînes, des masques de chaîne ou des expressions régulières. -
    - Express utilise [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) pour faire correspondre les chemins de routage ; pour connaître toutes les façons de définir des chemins de routage, voir la documentation path-to-regexp. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) est un outil pratique permettant de tester des routes Express de base, bien qu'il ne prenne pas en charge le filtrage par motif. -
    +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
    -Les chaînes de requête ne font pas partie du chemin de routage. -
    +{% include admonitions/caution.html content=caution-character %} + +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} + +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) est un outil pratique permettant de tester des routes Express de base, bien qu'il ne prenne pas en charge le filtrage par motif. + +{% endcapture %} -Il s'agit d'exemples de chemins de routage basés sur des chaînes. +{% include admonitions/note.html content=note-path-to-regexp %} + +{% capture query-string-note %} + +Query strings are not part of the route path. + +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### Il s'agit d'exemples de chemins de routage basés sur des chaînes. Ce chemin de routage fera correspondre des demandes à la route racine, `/`. -
    -
    -app.get('/', function (req, res) {
    -  res.send('root');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` Ce chemin de routage fera correspondre des demandes à `/about`. -
    -
    -app.get('/about', function (req, res) {
    -  res.send('about');
    -});
    -
    -
    +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` Ce chemin de routage fera correspondre des demandes à `/random.text`. -
    -
    -app.get('/random.text', function (req, res) {
    -  res.send('random.text');
    -});
    -
    -
    +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` + +### Il s'agit d'exemples de chemins de routage basés sur des masques de chaîne. + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -Il s'agit d'exemples de chemins de routage basés sur des masques de chaîne. +{% include admonitions/caution.html content=caution-string-patterns %} Ce chemin de routage fait correspondre `acd` et `abcd`. -
    -
    -app.get('/ab?cd', function(req, res) {
    -  res.send('ab?cd');
    -});
    -
    -
    +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` Ce chemin de routage fait correspondre `abcd`, `abbcd`, `abbbcd`, etc. -
    -
    -app.get('/ab+cd', function(req, res) {
    -  res.send('ab+cd');
    -});
    -
    -
    +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` Ce chemin de routage fait correspondre `abcd`, `abxcd`, `abRABDOMcd`, `ab123cd`, etc. -
    -
    -app.get('/ab*cd', function(req, res) {
    -  res.send('ab*cd');
    -});
    -
    -
    +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` Ce chemin de routage fait correspondre `/abe` et `/abcde`. -
    -
    -app.get('/ab(cd)?e', function(req, res) {
    - res.send('ab(cd)?e');
    -});
    -
    -
    +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` -
    -Les caractères ?, +, * et () sont des sous-ensembles de leur expression régulière équivalente. Le trait d'union (-) et le point (.) sont interprétés littéralement par des chemins d'accès basés sur des chaînes. -
    - -Exemples de chemins de routage basés sur des expressions régulières : +### Exemples de chemins de routage basés sur des expressions régulières : Ce chemin de routage fera correspondre tout élément dont le nom de chemin comprend la lettre "a". -
    -
    -app.get(/a/, function(req, res) {
    -  res.send('/a/');
    -});
    -
    -
    +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` Ce chemin de routage fera correspondre `butterfly` et `dragonfly`, mais pas `butterflyman`, `dragonfly man`, etc. -
    -
    -app.get(/.*fly$/, function(req, res) {
    -  res.send('/.*fly$/');
    -});
    -
    -
    +```js +app.get(/.*fly$/, (req, res) => { + res.send('/.*fly$/') +}) +``` + +

    +Les chaînes de requête ne font pas partie du chemin de routage. +

    + +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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
    +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +
    + +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. + +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` + +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` + +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): + +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` + +{% capture escape-advisory %} + +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %}

    Gestionnaires de routage

    @@ -182,89 +248,81 @@ Vous pouvez fournir plusieurs fonctions de rappel qui se comportent comme des [m Les gestionnaires de route se trouvent sous la forme d'une fonction, d'un tableau de fonctions ou d'une combinaison des deux, tel qu'indiqué dans les exemples suivants. -Une fonction de rappel unique peut traiter une route. Par exemple : +Une fonction de rappel unique peut traiter une route. Par exemple : -
    -
    -app.get('/example/a', function (req, res) {
    -  res.send('Hello from A!');
    -});
    -
    -
    +```js +app.get('/example/a', (req, res) => { + res.send('Hello from A!') +}) +``` Plusieurs fonctions de rappel peuvent traiter une route (n'oubliez pas de spécifier l'objet `next`). Par exemple : -
    -
    -app.get('/example/b', function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from B!');
    -});
    -
    -
    - -Un tableau de fonctions de rappel peut traiter une route. Par exemple : - -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +app.get('/example/b', (req, res, next) => {
    +  console.log('the response will be sent by the next function ...')
    +  next()
    +}, (req, res) => {
    +  res.send('Hello from B!')
    +})
    +```
    +
    +Un tableau de fonctions de rappel peut traiter une route. Par exemple :
    +
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -var cb2 = function (req, res) {
    -  res.send('Hello from C!');
    +const cb2 = function (req, res) {
    +  res.send('Hello from C!')
     }
     
    -app.get('/example/c', [cb0, cb1, cb2]);
    -
    -
    +app.get('/example/c', [cb0, cb1, cb2]) +``` -Une combinaison de fonctions indépendantes et des tableaux de fonctions peuvent gérer une route. Par exemple : +Une combinaison de fonctions indépendantes et des tableaux de fonctions peuvent gérer une route. Par exemple : -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/d', [cb0, cb1], function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from D!');
    -});
    -
    -
    +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +```

    Méthodes de réponse

    Les méthodes de l'objet de réponse (`res`) décrites dans le tableau suivant peuvent envoyer une réponse au client, et mettre fin au cycle de demande-réponse. Si aucune de ces méthodes n'est appelée par un gestionnaire de routage, la demande du client restera bloquée. -| Méthode | Description -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Vous invite à télécharger un fichier. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Met fin au processus de réponse. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Envoie une réponse JSON. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Envoie une réponse JSON avec une prise en charge JSONP. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirige une demande. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Génère un modèle de vue. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Envoie une réponse de divers types. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Envoie une réponse sous forme de flux d'octets. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Définit le code de statut de réponse et envoie sa représentation sous forme de chaîne comme corps de réponse. +| Méthode | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Vous invite à télécharger un fichier. | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Met fin au processus de réponse. | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Envoie une réponse JSON. | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Envoie une réponse JSON avec une prise en charge JSONP. | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirige une demande. | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Génère un modèle de vue. | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Envoie une réponse de divers types. | +| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Send a file as an octet stream. | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Définit le code de statut de réponse et envoie sa représentation sous forme de chaîne comme corps de réponse. |

    app.route()

    @@ -273,20 +331,18 @@ Etant donné que le chemin est spécifié à une seul emplacement, la création Voici quelques exemples de gestionnaires de chemin de chaînage définis à l'aide de `app.route()`. -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
    +  })
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .put((req, res) => {
    +    res.send('Update the book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    +```

    express.Router

    @@ -296,37 +352,43 @@ L'exemple suivant créé une routeur en tant que module, charge une fonction mid Créez un fichier de routage nommé `birds.js` dans le répertoire app, avec le contenu suivant : -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const router = express.Router()
     
     // middleware that is specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +const timeLog = (req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +}
    +router.use(timeLog)
    +
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` Puis, chargez le module de routage dans l'application : -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +const birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` L'application pourra dorénavant gérer des demandes dans `/birds` et `/birds/about`, et appeler la fonction middleware `timeLog` spécifique à la 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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/fr/guide/using-middleware.md b/fr/guide/using-middleware.md old mode 100755 new mode 100644 index a976723d04..f752e5ddda --- a/fr/guide/using-middleware.md +++ b/fr/guide/using-middleware.md @@ -1,205 +1,244 @@ --- layout: page title: Utilisation de middleware Express +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: fr +redirect_from: " " --- # Utilisation de middleware Express est une infrastructure web middleware et de routage, qui a des fonctions propres minimes : une application Express n'est ni plus ni moins qu'une succession d'appels de fonctions middleware. -Les fonctions de *middleware* sont des fonctions qui peuvent accéder à l'[objet Request](/{{ page.lang }}/4x/api.html#req) (`req`), l'[objet response](/{{ page.lang }}/4x/api.html#res) (`res`) et à la fonction middleware suivant dans le cycle demande-réponse de l'application. La fonction middleware suivant est couramment désignée par une variable nommée `next`. +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the next middleware function in the application's request-response cycle. La fonction middleware suivant est couramment désignée par une variable nommée `next`. Les fonctions middleware effectuent les tâches suivantes : -* Exécuter tout type de code. -* Apporter des modifications aux objets de demande et de réponse. -* Terminer le cycle de demande-réponse. -* Appeler la fonction middleware suivant dans la pile. +- Exécuter tout type de code. +- Apporter des modifications aux objets de demande et de réponse. +- Terminer le cycle de demande-réponse. +- Appeler la fonction middleware suivant dans la pile. Si la fonction middleware en cours ne termine pas le cycle de demande-réponse, elle doit appeler la fonction `next()` pour transmettre le contrôle à la fonction middleware suivant. Sinon, la demande restera bloquée. Une application Express peut utiliser les types de middleware suivants : - - [Middleware niveau application](#middleware.application) - - [Middleware niveau routeur](#middleware.router) - - [Middleware de traitement d'erreurs](#middleware.error-handling) - - [Middleware intégré](#middleware.built-in) - - [Middleware tiers](#middleware.third-party) +- [Middleware niveau application](#middleware.application) +- [Middleware niveau routeur](#middleware.router) +- [Middleware de traitement d'erreurs](#middleware.error-handling) +- [Middleware intégré](#middleware.built-in) +- [Middleware tiers](#middleware.third-party) Vous pouvez charger le middleware niveau application et niveau routeur à l'aide d'un chemin de montage facultatif. Vous pouvez également charger une série de fonctions middleware ensemble, ce qui crée une sous-pile du système de middleware à un point de montage.

    Middleware niveau application

    -Liez le middleware niveau application à une instance de l'objet [app object](/{{ page.lang }}/4x/api.html#app) en utilisant les fonctions `app.use()` et `app.METHOD()`, où `METHOD` est la méthode HTTP de la demande que gère la fonction middleware (par exemple GET, PUT ou POST) en minuscules. +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. Cet exemple illustre une fonction middleware sans chemin de montage. La fonction est exécutée à chaque fois que l'application reçoit une demande. -
    -
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    -
    -
    +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` Cet exemple illustre une fonction middleware montée sur le chemin `/user/:id`. La fonction est exécutée pour tout type de demande HTTP sur le chemin`/user/:id`. -
    -
    -app.use('/user/:id', function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Cet exemple illustre une route et sa fonction de gestionnaire (système de middleware). La fonction gère les demandes GET adressées au chemin `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  res.send('USER');
    -});
    -
    -
    +```js +app.get('/user/:id', (req, res, next) => { + res.send('USER') +}) +``` Voici un exemple de chargement d'une série de fonctions middleware sur un point de montage, avec un chemin de montage. Il illustre une sous-pile de middleware qui imprime les infos de demande pour tout type de demande HTTP adressée au chemin `/user/:id`. -
    -
    -app.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Les gestionnaires de routage vous permettent de définir plusieurs routes pour un chemin. L'exemple ci-dessous définit deux routes pour les demandes GET adressées au chemin `/user/:id`. La deuxième route ne causera aucun problème, mais ne sera jamais appelée puisque la première route boucle le cycle demande-réponse. Cet exemple illustre une sous-pile de middleware qui gère les demandes GET adressées au chemin `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -}, function (req, res, next) {
    -  res.send('User Info');
    -});
    +```js
    +app.get('/user/:id', (req, res, next) => {
    +  console.log('ID:', req.params.id)
    +  next()
    +}, (req, res, next) => {
    +  res.send('User Info')
    +})
     
     // handler for the /user/:id path, which prints the user ID
    -app.get('/user/:id', function (req, res, next) {
    -  res.end(req.params.id);
    -});
    -
    -
    +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) +}) +``` Pour ignorer les fonctions middleware issues d'une pile de middleware de routeur, appelez `next('route')` pour passer le contrôle à la prochaine route. -**REMARQUE **: `next('route')` ne fonctionnera qu'avec les fonctions middleware qui ont été chargées via les fonctions `app.METHOD()` ou `router.METHOD()`. + +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} Cet exemple illustre une sous-pile de middleware qui gère les demandes GET adressées au chemin `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    +```js
    +app.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next route
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass the control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    -  // render a regular page
    -  res.render('regular');
    -});
    +  else next()
    +}, (req, res, next) => {
    +  // send a regular response
    +  res.send('regular')
    +})
     
    -// handler for the /user/:id path, which renders a special page
    -app.get('/user/:id', function (req, res, next) {
    -  res.render('special');
    -});
    -
    -
    +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +Voici un exemple d'utilisation de la fonction middleware `express.static` avec un objet options élaboré : + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

    Middleware niveau routeur

    Le middleware niveau routeur fonctionne de la même manière que le middleware niveau application, à l'exception près qu'il est lié à une instance de `express.Router()`. -
    -
    -var router = express.Router();
    -
    -
    +```js +const router = express.Router() +``` + Chargez le middleware niveau routeur par le biais des fonctions `router.use()` et `router.METHOD()`. Le code d'exemple suivant réplique le système de middleware illustré ci-dessus pour le middleware niveau application, en utilisant un middleware niveau routeur : -
    -
    -var app = express();
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const app = express()
    +const router = express.Router()
     
     // a middleware function with no mount path. This code is executed for every request to the router
    -router.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time:', Date.now())
    +  next()
    +})
     
     // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    -router.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    +router.use('/user/:id', (req, res, next) => {
    +  console.log('Request URL:', req.originalUrl)
    +  next()
    +}, (req, res, next) => {
    +  console.log('Request Type:', req.method)
    +  next()
    +})
     
     // a middleware sub-stack that handles GET requests to the /user/:id path
    -router.get('/user/:id', function (req, res, next) {
    +router.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next router
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    +  else next()
    +}, (req, res, next) => {
       // render a regular page
    -  res.render('regular');
    -});
    +  res.render('regular')
    +})
     
     // handler for the /user/:id path, which renders a special page
    -router.get('/user/:id', function (req, res, next) {
    -  console.log(req.params.id);
    -  res.render('special');
    -});
    +router.get('/user/:id', (req, res, next) => {
    +  console.log(req.params.id)
    +  res.render('special')
    +})
     
     // mount the router on the app
    -app.use('/', router);
    -
    -
    +app.use('/', router) +``` + +Pour obtenir plus de détails sur la fonction `serve-static` et ses options, reportez-vous à la documentation [serve-static](https://github.com/expressjs/serve-static). + +Cet exemple illustre une sous-pile de middleware qui gère les demandes GET adressées au chemin `/user/:id`. + +```js +const express = require('express') +const app = express() +const router = express.Router() + +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) + +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) + +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +```

    Middleware de traitement d'erreurs

    -Le middleware de traitement d'erreurs comporte toujours *quatre* arguments. Vous devez fournir quatre arguments pour l'identifier comme une fonction middleware de traitement d'erreurs. 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 ordinaire et n'arrivera pas à gérer les erreurs. +Le middleware de traitement d'erreurs comporte toujours *quatre* arguments. Vous devez fournir quatre arguments pour l'identifier comme une fonction middleware de traitement d'erreurs. 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 ordinaire et n'arrivera pas à gérer les erreurs.
    Définissez les fonctions middleware de traitement d'erreurs de la même façon que d'autres fonctions middleware, à l'exception près qu'il faudra 4 arguments au lieu de 3, et plus particulièrement avec la signature `(err, req, res, next)`) : -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Pour obtenir des détails sur le middleware de traitement d'erreurs, reportez-vous à : [Traitement d'erreurs](/{{ page.lang }}/guide/error-handling.html). @@ -208,56 +247,11 @@ Pour obtenir des détails sur le middleware de traitement d'erreurs, reportez-vo Depuis la version 4.x, Express ne dépend plus de [Connect](https://github.com/senchalabs/connect). A l'exception de `express.static`, toutes les fonctions middleware précédemment incluses à Express' font désormais partie de modules distincts. Veuillez vous reporter à [la liste des fonctions middleware](https://github.com/senchalabs/connect#middleware). -

    express.static(root, [options])

    - -La seule fonction middleware intégrée dans Express est `express.static`. Cette fonction est basée sur [serve-static](https://github.com/expressjs/serve-static) et a la responsabilité de servir les actifs statiques d'une application Express. - -L'argument `root` spécifie le répertoire racine à partir duquel servir les actifs statiques. - -L'objet `options` facultatif peut avoir les propriétés suivantes : - -| Propriété | Description | Type | Valeur par défaut | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | Option pour servir les fichiers dotfiles. Les valeurs possibles sont "allow", "deny" et "ignore" | Chaîne | "ignore" | -| `etag` | Activer ou désactiver la génération etag | Booléen | `true` | -| `extensions` | Définit l'extension de fichier de rechange. | Tableau | `[]` | -| `index` | Envoie le fichier d'index du répertoire. Utilisez `false` pour désactiver l'indexation de répertoire. | Mix | "index.html" | - `lastModified` | Définit l'en-tête `Last-Modified` sur la date de dernière modification du fichier dans le système d'exploitation. Les valeurs possibles sont `true` ou `false`. | Booléen | `true` | -| `maxAge` | Définit la propriété max-age de l'en-tête Cache-Control, en millisecondes ou par une chaîne au format [ms format](https://www.npmjs.org/package/ms) | Numérique | 0 | -| `redirect` | Réapplique les barres obliques "/" lorsque le chemin d'accès est un répertoire. | Booléen | `true` | -| `setHeaders` | Fonction pour définir les en-têtes HTTP à servir avec le fichier. | Fonction | | +La seule fonction middleware intégrée dans Express est `express.static`. -Voici un exemple d'utilisation de la fonction middleware `express.static` avec un objet options élaboré : - -
    -
    -var options = {
    -  dotfiles: 'ignore',
    -  etag: false,
    -  extensions: ['htm', 'html'],
    -  index: false,
    -  maxAge: '1d',
    -  redirect: false,
    -  setHeaders: function (res, path, stat) {
    -    res.set('x-timestamp', Date.now());
    -  }
    -}
    -
    -app.use(express.static('public', options));
    -
    -
    - -Vous pouvez avoir plusieurs répertoires statiques par application : - -
    -
    -app.use(express.static('public'));
    -app.use(express.static('uploads'));
    -app.use(express.static('files'));
    -
    -
    - -Pour obtenir plus de détails sur la fonction `serve-static` et ses options, reportez-vous à la documentation [serve-static](https://github.com/expressjs/serve-static). +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**

    Middleware tiers

    @@ -267,21 +261,17 @@ Installez le module Node.js pour la fonctionnalité requise, puis chargez-le dan L'exemple suivant illustre l'installation et le chargement de la fonction middleware d'analyse de cookie `cookie-parser`. -
    -
    +```bash
     $ npm install cookie-parser
    -
    -
    +``` -
    -
    -var express = require('express');
    -var app = express();
    -var cookieParser = require('cookie-parser');
    +```js
    +const express = require('express')
    +const app = express()
    +const cookieParser = require('cookie-parser')
     
     // load the cookie-parsing middleware
    -app.use(cookieParser());
    -
    -
    +app.use(cookieParser()) +``` Pour obtenir une liste non exhaustive des fonctions middleware tiers utilisées couramment avec Express, reportez-vous à : [Middleware tiers](../resources/middleware.html). diff --git a/fr/guide/using-template-engines.md b/fr/guide/using-template-engines.md old mode 100755 new mode 100644 index 337ad48932..7213af9e5e --- a/fr/guide/using-template-engines.md +++ b/fr/guide/using-template-engines.md @@ -1,61 +1,62 @@ --- layout: page title: Utilisation de moteurs de modèles avec Express +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: fr +redirect_from: " " --- # Utilisation de moteurs de modèles avec Express -Pour qu'Express puisse afficher le rendu des fichiers modèles, vous devez définir les paramètres d'application suivants : +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +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. -* `views`, le répertoire dans lequel se trouvent les fichiers modèles. Par exemple : `app.set('views', './views')` -* `view engine`, le moteur de modèle à utiliser. Par exemple : `app.set('view engine', 'pug')` +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. + +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: + +- `views`, le répertoire dans lequel se trouvent les fichiers modèles. Par exemple : `app.set('views', './views')` + This defaults to the `views` directory in the application root directory. +- `view engine`, le moteur de modèle à utiliser. Par exemple : `app.set('view engine', 'pug')` Ensuite, installez le package npm du moteur de modèle correspondant : -
    -
    +```bash
     $ npm install pug --save
    -
    -
    +```
    Les moteurs de modèles conformes à Express tels que Pug exportent une fonction nommée `__express(filePath, options, callback)`, qui est appelée par la fonction `res.render()` pour générer le code de modèle. Certaines moteurs de modèles ne suivent pas cette convention. La bibliothèque [Consolidate.js](https://www.npmjs.org/package/consolidate) suit cette convention en mappant tous les moteurs de modèles Node.js répandus, et fonctionne donc parfaitement avec Express. +
    Une fois le moteur de vue défini, vous n'avez pas à spécifier le moteur ou à charger le module de moteur de modèles dans votre application ; Express charge le module en interne, comme indiqué ci-dessous (pour l'exemple ci-dessus). -
    -
    -app.set('view engine', 'pug');
    -
    -
    +```js +app.set('view engine', 'pug') +``` Créez un fichier de modèle Pug nommé `index.pug` dans le répertoire `views`, avec le contenu suivant : -
    -
    +```pug
     html
       head
         title= title
       body
         h1= message
    -
    -
    +``` Puis, créez une route pour générer le fichier `index.pug`. Si la propriété `view engine` n'est pas définie, vous devez spécifier l'extension du fichier `view`. Sinon, vous pouvez l'omettre. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` Lorsque vous faites une demande vers la page d'accueil, le fichier `index.pug` est généré en HTML. -Pour en savoir plus sur le fonctionnement des moteurs de modèle dans Express, voir : ["Développement de moteurs de modèles pour Express"](/{{ page.lang }}/advanced/developing-template-engines.html). +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/fr/guide/writing-middleware.md b/fr/guide/writing-middleware.md old mode 100755 new mode 100644 index 888ef14736..9c64f8f560 --- a/fr/guide/writing-middleware.md +++ b/fr/guide/writing-middleware.md @@ -1,33 +1,35 @@ --- layout: page title: Ecriture de middleware utilisable dans les applications Express +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: fr +redirect_from: " " --- # Ecriture de middleware utilisable dans les applications Express

    Présentation

    -Les fonctions de *middleware* sont des fonctions qui peuvent accéder à l'[objet Request](/{{ page.lang }}/4x/api.html#req) (`req`), l'[objet response](/{{ page.lang }}/4x/api.html#res) (`res`) et à la fonction middleware suivant dans le cycle demande-réponse de l'application. La fonction middleware suivant est couramment désignée par une variable nommée `next`. +Les fonctions de _middleware_ sont des fonctions qui peuvent accéder à l'[objet Request](/{{ page.lang }}/4x/api.html#req) (`req`), l'[objet response](/{{ page.lang }}/4x/api.html#res) (`res`) et à la fonction middleware suivant dans le cycle demande-réponse de l'application. La fonction middleware suivant est couramment désignée par une variable nommée `next`. Les fonctions middleware effectuent les tâches suivantes : -* Exécuter tout type de code. -* Apporter des modifications aux objets de demande et de réponse. -* Terminer le cycle de demande-réponse. -* Appeler le middleware suivant dans la pile. +- Exécuter tout type de code. +- Apporter des modifications aux objets de demande et de réponse. +- Terminer le cycle de demande-réponse. +- Appeler le middleware suivant dans la pile. Si la fonction middleware en cours ne termine pas le cycle de demande-réponse, elle doit appeler la fonction `next()` pour transmettre le contrôle à la fonction middleware suivant. Sinon, la demande restera bloquée. L'exemple suivant montre les éléments d'un appel de fonction middleware: - -
    - +
    + + -
    Chemin (route) auquel la fonction middleware s'applique.
    @@ -40,85 +42,64 @@ L'exemple suivant montre les éléments d'un appel de fonction middleware:
    Argument de demande HTTP à la fonction middleware, appelé "req" par convention.
    +Elements of a middleware function call -
    Méthode HTTP à laquelle la fonction middleware s'applique.
    +
    +
    Méthode HTTP à laquelle la fonction middleware s'applique.
    +
    - +

    Exemple

    Voici un exemple d'une application Express "Hello World" simple, pour laquelle vous allez définir deux fonctions middleware : +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. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    - -

    Développement

    +app.listen(3000) +``` +

    Middleware function myLogger

    Voici un exemple simple de fonction middleware appelée "myLogger". Cette fonction imprime simplement "LOGGED" lorsqu'une demande traverse l'application. La fonction middleware est affectée à une variable nommée `myLogger`. -
    -
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    -
    -
    +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
    -Notez l'appel ci-dessus de la fonction `next()`, qui appelle la fonction middleware suivant dans l'application. La fonction `next()` ne fait pas partie du Node.js ou de l'API Express, mais c'est le troisième argument qui est transmis à la fonction middleware. La fonction `next()` peut porter n'importe quel nom, mais par convention elle est toujours appelée "next". Pour éviter toute confusion, il est préférable de respecter cette convention. +Notice the call above to `next()`. Notez l'appel ci-dessus de la fonction `next()`, qui appelle la fonction middleware suivant dans l'application. +La fonction `next()` ne fait pas partie du Node.js ou de l'API Express, mais c'est le troisième argument qui est transmis à la fonction middleware. La fonction `next()` peut porter n'importe quel nom, mais par convention elle est toujours appelée "next". +Pour éviter toute confusion, il est préférable de respecter cette convention.
    Pour charger la fonction middleware, appelez `app.use()` en spécifiant la fonction middleware. Par exemple, le code suivant charge la fonction middleware `myLogger` avant la route au chemin racine (/). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    +const myLogger = function (req, res, next) {
    +  console.log('LOGGED')
    +  next()
    +}
     
    -app.use(myLogger);
    +app.use(myLogger)
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    +app.listen(3000) +``` Chaque fois que l'application reçoit une demande, elle imprime le message "LOGGED" sur le terminal. @@ -128,43 +109,112 @@ Si `myLogger` est chargé après la route au chemin racine, la demande ne l'atte La fonction middleware `myLogger` imprime simplement un message, puis traite la demande à la fonction middleware suivant dans la pile en appelant la fonction `next()`. +

    Middleware function requestTime

    + L'exemple suivant ajoute une propriété appelée `requestTime` à l'objet Request. Nous nommerons cette fonction middleware "requestTime". -
    -
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    -
    -
    +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` L'application utilise désormais la fonction middleware `requestTime`. De plus, la fonction callback de la route du chemin racine utilise la propriété que la fonction middleware ajoute à `req` (l'objet Request). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    +const requestTime = function (req, res, next) {
    +  req.requestTime = Date.now()
    +  next()
    +}
     
    -app.use(requestTime);
    +app.use(requestTime)
     
    -app.get('/', function (req, res) {
    -  var responseText = 'Hello World!
    '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) -app.listen(3000); -
    -
    +app.listen(3000) +``` Si vous effectuez une demande à la racine de l'application, cette dernière affiche maintenant l'horodatage de la demande dans le navigateur. +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    + Puisque vous avez accès à l'objet Request, à l'objet Response, à la fonction middleware suivant dans la pile et à l'API Node.js complète, le champ des possibles avec les fonctions middleware est infini. Pour plus d'informations sur les middleware Express, voir [Utilisation de middleware Express](/{{ page.lang }}/guide/using-middleware.html). + +

    Configurable middleware

    + +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. + +File: `my-middleware.js` + +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` + +The middleware can now be used as shown below. + +```js +const mw = require('./my-middleware.js') + +app.use(mw({ option1: '1', option2: '2' })) +``` + +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/fr/index.md b/fr/index.md index aa18bbd47e..be45482a6a 100644 --- a/fr/index.md +++ b/fr/index.md @@ -1,53 +1,61 @@ --- layout: home -title: Express - Infrastructure d'application Web Node.js +title: Express - Node.js web application framework +description: "Express is a fast, unopinionated, minimalist web framework for Node.js, providing a robust set of features for web and mobile applications." menu: home -lang: fr - +redirect_from: " " --- +
    - {% include header/header-{{ page.lang }}.html %} -
    - - Infrastructure Web minimaliste, souple et rapide pour Node.js + +

    Fast, unopinionated, minimalist web framework for Node.js

    -
    $ npm install express --save
    +
    $ npm install express --save
    -
    - -
    -
    - +
    -
    - -
    -
    -

    Applications Web

    Express est une infrastructure d'applications Web Node.js minimaliste et flexible qui fournit un ensemble de fonctionnalités robuste pour les applications Web et mobiles. -
    +```javascript +const express = require('express') +const app = express() +const port = 3000 -
    -

    API

    Grâce à une foule de méthodes utilitaires HTTP et de middleware mise à votre disposition, la création d'une API robuste est simple et rapide. -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -
    -

    Performance

    Express apporte une couche fine de fonctionnalités d'application Web fondamentales, sans masquer les fonctionnalités de Node.js que vous connaissez et appréciez. -
    +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` -
    -
    - diff --git a/fr/resources/community.md b/fr/resources/community.md old mode 100755 new mode 100644 index 6a84226915..e6305cf9c2 --- a/fr/resources/community.md +++ b/fr/resources/community.md @@ -1,39 +1,92 @@ --- layout: page title: Communauté Express -menu: ressources -lang: fr +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. +menu: resources +redirect_from: " " --- # Communauté -## Liste de diffusion +## Technical committee -Rejoignez plus de 2000 utilisateurs Express ou parcourez plus de 5000 discussions dans le [Groupe Google](https://groups.google.com/group/express-js). +The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, +and other issues relevant to the Express project. Each meeting is typically announced in an +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is +open to all observers. -## Gitter +The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -Le [chatroom expressjs/express](https://gitter.im/expressjs/express) est un endroit idéal -pour les développeurs de logiciel intéressés par des discussions quotidiennes en rapport avec Express. +Members of the Express technical committee are: -## Canal IRC +**Active:** -Chaque jour, des centaines de développeurs de logiciels vous répondent dans la rubrique #express sur Freenode. -Si vous avez des questions sur l'infrastructure, inscrivez-vous pour obtenir rapidement des informations en retour. +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida -## Exemples +**Inactive:** -Regardez des douzaines d'[exemples](https://github.com/expressjs/express/tree/master/examples) d'applications Express dans le référentiel qui couvre tous les sujets, en allant de l'authentification et la conception de l'interface de -programme d'application jusqu'à l'intégration du moteur modèle. +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express is made of many modules + +Notre communauté si animée a créé une large gamme d'extensions, +[modules middleware](/{{ page.lang }}/resources/middleware.html) et des +infrastructures de niveau supérieur. + +Additionally, the Express community maintains modules in these two GitHub orgs: + +- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. + +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). ## Problèmes Si vous êtes tombé sur ce que vous pensez être un bug, ou si vous voulez seulement faire une demande de fonctionnalité, ouvrez un ticket dans la [file d'attente d'incidents](https://github.com/expressjs/express/issues). -## Troisième partie +## Exemples -Notre communauté si animée a créé une large gamme d'extensions, -[modules middleware](/{{ page.lang }}/resources/middleware.html) et des -infrastructures de niveau supérieur. Consultez-les sur le [wiki](https://github.com/expressjs/express/wiki). +Regardez des douzaines d'[exemples](https://github.com/expressjs/express/tree/master/examples) d'applications Express dans le référentiel qui couvre tous les sujets, en allant de l'authentification et la conception de l'interface de +programme d'application jusqu'à l'intégration du moteur modèle. + +## Github Discussions + +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. + +# Branding of Express.js + +## Express.js Logo + +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/fr/resources/contributing.md b/fr/resources/contributing.md new file mode 100644 index 0000000000..e37cee3122 --- /dev/null +++ b/fr/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/fr/resources/glossary.md b/fr/resources/glossary.md old mode 100755 new mode 100644 index 7c0ad739d0..f2774da7d6 --- a/fr/resources/glossary.md +++ b/fr/resources/glossary.md @@ -1,8 +1,9 @@ --- layout: page title: Glossaire Express +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: fr +redirect_from: " " --- # Glossaire @@ -13,15 +14,11 @@ En général, un ou plusieurs programmes conçus pour réaliser des opérations ### API -Interface de programme d'application. Développez l'abréviation lorsqu'elle est utilisée pour la première fois. - -### demande - -Demande HTTP. Un client soumet un message de demande HTTP à un serveur, qui renvoie une réponse. La demande doit utiliser une des [méthodes de demande](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) telles que GET, POST... +Interface de programme d'application. Développez l'abréviation lorsqu'elle est utilisée pour la première fois. ### Express -Infrastructure Web minimaliste, souple et rapide pour les applications Node.js. En général, on préfère utiliser "Express" que "Express.js," bien que ce dernier soit acceptable. +Infrastructure Web minimaliste, souple et rapide pour les applications Node.js. En général, on préfère utiliser "Express" que "Express.js," bien que ce dernier soit acceptable. ### libuv @@ -29,19 +26,31 @@ Bibliothèque de prise en charge multiplateforme qui se centralise sur les E-S a ### middleware -Fonction qui est appelée par la couche de routage Express avant le gestionnaire de demande final, et qui se trouve entre une demande brute et la route finale prévue. Quelques points subtiles de terminologie autour des middleware : +Fonction qui est appelée par la couche de routage Express avant le gestionnaire de demande final, et qui se trouve entre une demande brute et la route finale prévue. Quelques points subtiles de terminologie autour des middleware : - * `var foo = require('middleware')` est appelé *demande* ou *utilisation* d'un module Node.js. Ensuite, l'instruction `var mw = foo()` renvoie généralement le middleware. - * `app.use(mw)` est appelé *ajout du middleware à la pile de processus global*. - * `app.get('/foo', mw, function (req, res) { ... })` est appelé *ajout du middleware à la pile de processus "GET /foo"*. +- `var foo = require('middleware')` est appelé _demande_ ou _utilisation_ d'un module Node.js. Ensuite, l'instruction `var mw = foo()` renvoie généralement le middleware. +- `app.use(mw)` est appelé _ajout du middleware à la pile de processus global_. +- `app.get('/foo', mw, function (req, res) { ... })` est appelé _ajout du middleware à la pile de processus "GET /foo"_. ### Node.js -Plateforme logicielle utilisée pour générer des applications réseau évolutives. Node.js utilise JavaScript comme langage de script, et atteint un rendement élevé via une E-S non bloquante et une boucle d'événements à une seule unité d'exécution. Voir [nodejs.org](http://nodejs.org/). **Note d'utilisation** : En général, "Node.js," "Node" par la suite. +Plateforme logicielle utilisée pour générer des applications réseau évolutives. Node.js utilise JavaScript comme langage de script, et atteint un rendement élevé via une E-S non bloquante et une boucle d'événements à une seule unité d'exécution. Voir [nodejs.org](http://nodejs.org/). **Note d'utilisation** : En général, "Node.js," "Node" par la suite. ### open-source, open source -Lorsqu'il est utilisé comme adjectif, utilisez la forme avec le trait d'union. Par exemple : "Il s'agit d'un logiciel open-source." Voir [Open-source software sur Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Remarque : Bien qu'open-source ne soit pas commun, nous utilisons les règles anglaises standard pour unir par un trait d'union un adjectif composé. +Lorsqu'il est utilisé comme adjectif, utilisez la forme avec le trait d'union. Par exemple : "Il s'agit d'un logiciel open-source." Voir [Open-source software sur Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). + +{% capture english-rules %} + +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. + +{% endcapture %} + +{% include admonitions/note.html content=english-rules %} + +### demande + +Demande HTTP. Un client soumet un message de demande HTTP à un serveur, qui renvoie une réponse. La demande doit utiliser une des [méthodes de demande](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) telles que GET, POST... ### réponse @@ -49,7 +58,7 @@ Réponse HTTP. Un serveur renvoie un message de réponse HTTP au client. La rép ### route -Partie de l'URL qui permet d'identifier une ressource. Par exemple, dans `http://foo.com/products/id`, "/products/id" est la route. +Partie de l'URL qui permet d'identifier une ressource. Par exemple, dans `http://foo.com/products/id`, "/products/id" est la route. ### routeur diff --git a/fr/resources/learning.md b/fr/resources/learning.md deleted file mode 100755 index c786957750..0000000000 --- a/fr/resources/learning.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: Apprentissage supplémentaire -menu: resources -lang: fr ---- - -# Apprentissage supplémentaire - -
    Disclaimer: Unendorsed community content.
    - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/fr/resources/middleware.md b/fr/resources/middleware.md old mode 100755 new mode 100644 index 7198a03e17..2d624487d9 --- a/fr/resources/middleware.md +++ b/fr/resources/middleware.md @@ -1,64 +1,43 @@ --- -layout: page +layout: middleware title: Middleware Express +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: fr +redirect_from: " " +module: mw-home --- -# Middleware tiers +## Middleware Express Voici quelques modules de middleware Express : - - [body-parser](https://github.com/expressjs/body-parser) : précédemment `express.bodyParser`, `json` et `urlencoded`. - Voir aussi : - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression) : précédemment `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus) : modules de middleware Connect/Express pour une utilisation des images optimale. Bascule les images en `.webp` ou `.jxr`, dans la mesure du possible. - - [connect-timeout](https://github.com/expressjs/timeout) : précédemment `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser) : précédemment `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session) : précédemment `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf) : précédemment `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler) : précédemment `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug) : outil de développement discret qui ajoute un onglet avec des informations sur les variables de canevas (environnements locaux), les sessions en cours, les données de demandes utiles et bien plus, à votre application. - - [express-partial-response](https://github.com/nemtsov/express-partial-response) : module Express Middleware permettant de filtrer des éléments de réponses JSON en fonction de la chaîne de requête `zones` ; en utilisant la réponse partielle de l'API Google. - - [express-session](https://github.com/expressjs/session) : précédemment `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn) : module Express Middleware permettant d'utiliser un CDN pour les actifs statiques, avec la prise en charge de plusieurs hôtes (Par exemple : cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash) : module Express Middleware destiné aux personnes qui sont strictes sur le respect des barres obliques. - - [express-stormpath](https://github.com/stormpath/stormpath-express) : module Express Middleware destiné au stockage utilisateur, à l'authentification, à l'autorisation, à la connexion unique et à la sécurité des données. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize) : module middleware destiné à la redirection des demandes HTTP contenant des majuscules en format canonique en minuscules. - - [helmet](https://github.com/helmetjs/helmet) : module qui aide à sécuriser vos applications en définissant divers en-têtes HTTP. - - [join-io](https://github.com/coderaiser/join-io "join-io") : module permettant de joindre des fichiers à la volée pour réduire le nombre de demandes. - - [method-override](https://github.com/expressjs/method-override) : précédemment `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan) : précédemment `logger` - - [passport](https://github.com/jaredhanson/passport) : module de middleware Express dédié à l'authentification. - - [response-time](https://github.com/expressjs/response-time) : précédemment `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon) : précédemment `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index) : précédemment `express.directory` - - [serve-static](https://github.com/expressjs/serve-static) : module d'utilisation du contenu statique. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry) : URL à empreinte digitale ou en-têtes de mise en cache pour les actifs statiques, y compris la prise en charge d'un ou plusieurs domaines externes. - - [vhost](https://github.com/expressjs/vhost) : précédemment `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers) : module Express Middleware qui offre des méthodes d'auxiliaires courantes destinées aux vues. - - [sriracha-admin](https://github.com/hdngr/siracha) : module Express Middleware qui génère de façon dynamique un site administrateur pour Mongoose. +| [express-slash](https://github.com/ericf/express-slash) : module Express Middleware destiné aux personnes qui sont strictes sur le respect des barres obliques. | Description | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | -Certains modules middleware précédemment inclus avec Connect ne sont plus pris en charge par l'équipe Connect/Express. Ils sont remplacés par un module alternatif ou devraient être remplacés par un module supérieur. Utilisez l'une des alternatives suivantes : +## Pour découvrir plus de modules de middleware, voir : - - express.cookieParser - - [cookies](https://github.com/jed/cookies) et [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) +[view-helpers](https://github.com/madhums/node-view-helpers) : module Express Middleware qui offre des méthodes d'auxiliaires courantes destinées aux vues. -Pour découvrir plus de modules de middleware, voir : +{% include community-caveat.html %} - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| [express-slash](https://github.com/ericf/express-slash) : module Express Middleware destiné aux personnes qui sont strictes sur le respect des barres obliques. | Description | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet) : module qui aide à sécuriser vos applications en définissant divers en-têtes HTTP. | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport) : module de middleware Express dédié à l'authentification. | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/fr/resources/middleware/body-parser.md b/fr/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/fr/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/fr/resources/middleware/compression.md b/fr/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/fr/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/fr/resources/middleware/connect-rid.md b/fr/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/fr/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/fr/resources/middleware/cookie-parser.md b/fr/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/fr/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/fr/resources/middleware/cookie-session.md b/fr/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/fr/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/fr/resources/middleware/cors.md b/fr/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/fr/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/fr/resources/middleware/errorhandler.md b/fr/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/fr/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/fr/resources/middleware/method-override.md b/fr/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/fr/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/fr/resources/middleware/morgan.md b/fr/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/fr/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/fr/resources/middleware/multer.md b/fr/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/fr/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/fr/resources/middleware/response-time.md b/fr/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/fr/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/fr/resources/middleware/serve-favicon.md b/fr/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/fr/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/fr/resources/middleware/serve-index.md b/fr/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/fr/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/fr/resources/middleware/serve-static.md b/fr/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/fr/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/fr/resources/middleware/session.md b/fr/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/fr/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/fr/resources/middleware/timeout.md b/fr/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/fr/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/fr/resources/middleware/vhost.md b/fr/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/fr/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/fr/resources/utils.md b/fr/resources/utils.md new file mode 100644 index 0000000000..f58beb26e1 --- /dev/null +++ b/fr/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/fr/starter/basic-routing.md b/fr/starter/basic-routing.md old mode 100755 new mode 100644 index 5019ea7a89..95e496820e --- a/fr/starter/basic-routing.md +++ b/fr/starter/basic-routing.md @@ -1,23 +1,23 @@ --- layout: page title: Routage de base Express +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: fr +redirect_from: " " --- # Routage de base -*Routage* fait référence à la détermination de la façon dont une application répond à un +_Routage_ fait référence à la détermination de la façon dont une application répond à un nœud final spécifique, c'est-à-dire un URI (ou chemin) et une méthode de requête HTTP (GET, POST, etc.). Chaque route peut avoir une ou plusieurs fonctions de gestionnaire, qui sont exécutées lorsque la route est mise en correspondance. La définition de la route utilise la structure suivante : -
    -
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` Où : @@ -27,50 +27,43 @@ Où : - `HANDLER` est la fonction exécutée lorsque la route est mise en correspondance.
    -Ce tutoriel suppose qu'une instance d'`express` appelée `app` soit créée et que le serveur soit en cours d'exécution. -Si vous ne savez pas créer et démarrer une application, reportez-vous à l'[exemple Hello world](/{{ page.lang }}/starter/hello-world.html). +Ce tutoriel suppose qu'une instance d'`express` appelée `app` soit créée et que le serveur soit en cours d'exécution. Si vous ne savez pas créer et démarrer une application, reportez-vous à l'[exemple Hello world](/{{ page.lang }}/starter/hello-world.html).
    Les exemples suivants illustrent la définition de routes simples. Réponse `Hello World!` sur la page d'accueil : -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -Réponse à une demande POST sur la route racine (`/`), sur la page d'accueil de l'application : +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` Réponse à une demande PUT sur la route `/user` : -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` Réponse à une demande DELETE sur la route `/user` : -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` Pour plus de détails sur le routage, reportez-vous au [guide de routage](/{{ page.lang }}/guide/routing.html). + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/fr/starter/examples.md b/fr/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/fr/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/fr/starter/faq.md b/fr/starter/faq.md old mode 100755 new mode 100644 index 372aa2e677..d4fed31dfc --- a/fr/starter/faq.md +++ b/fr/starter/faq.md @@ -1,8 +1,9 @@ --- layout: page title: FAQ Express +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: fr +redirect_from: " " --- # FAQ @@ -17,13 +18,13 @@ Les routes et la logique propre à l'application peuvent être opérationnelles que vous le souhaitez, et dans les structures de répertoire que vous préférez. Pour plus d'inspiration, consultez les exemples suivants : -* [Listes de routes](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Feuille de route](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [Contrôleurs de style MVC](https://github.com/expressjs/express/tree/master/examples/mvc) +- [Listes de routes](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [Feuille de route](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [Contrôleurs de style MVC](https://github.com/expressjs/express/tree/master/examples/mvc) Il existe aussi des extensions tiers pour Express, permettant de simplifier certains de ces modèles : -* [Routage ingénieux](https://github.com/expressjs/express-resource) +- [Routage ingénieux](https://github.com/expressjs/express-resource) ## Comment puis-je définir des modèles ? @@ -39,7 +40,6 @@ L'authentification est une autre partie complexe dans laquelle Express ne s'aventure pas. Vous pouvez utiliser tous les schémas d'authentification que vous voulez. Pour un schéma simple de type nom d'utilisateur/mot de passe, voir [cet exemple](https://github.com/expressjs/express/tree/master/examples/auth). - ## Quels moteurs de modèles Express prend-il en charge ? Express prend en charge tous les moteurs de modèles conformes à la signature `(path, locals, callback)`. @@ -47,37 +47,37 @@ Pour normaliser les interfaces de moteur de modèles et la mise en cache, voir l projet [consolidate.js](https://github.com/visionmedia/consolidate.js) pour la prise en charge. Des moteurs de modèles non répertoriés peuvent encore prendre en charge la signature Express. +For more information, see [Using template engines with Express](/{{page.lang}}/guide/using-template-engines.html). + ## Comment puis-je gérer des réponses 404 ? Dans Express, étant donné que les réponses 404 ne sont pas le résultat d'une erreur, le middleware de traitement d'erreurs ne les traite pas. Ce comportement est -dû au fait qu'une réponse 404 indique simplement l'absence d'un travail supplémentaire à effectuer. -En d'autres termes, Express a exécuté toutes les routes et fonctions middleware, +dû au fait qu'une réponse 404 indique simplement l'absence d'un travail supplémentaire à effectuer. En d'autres termes, Express a exécuté toutes les routes et fonctions middleware, et aucune n'a répondu. Tout ce que vous avez à faire est d'ajouter une fonction middleware à la toute fin de la pile (en-dessous de toutes les autres fonctions) pour gérer une réponse 404 : -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` + +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## Comment puis-je configurer un gestionnaire d'erreurs ? Vous pouvez définir un middleware de traitement d'erreurs de la même façon qu'un autre middleware, à l'exception qu'il faudra 4 arguments au lieu de 3 ; et plus particulièrement avec la signature `(err, req, res, next)` : -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Pour plus d'informations, voir [Traitement d'erreurs](/{{ page.lang }}/guide/error-handling.html). @@ -86,3 +86,10 @@ Pour plus d'informations, voir [Traitement d'erreurs](/{{ page.lang }}/guide/err Vous ne pouvez pas ! Il n'est pas nécessaire de "générer" un fichier HTML avec la fonction `res.render()`. Si vous avez un fichier spécifique, utilisez la fonction `res.sendFile()`. Si vous utilisez plusieurs actifs d'un répertoire, utilisez la fonction middleware `express.static()`. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/fr/starter/generator.md b/fr/starter/generator.md old mode 100755 new mode 100644 index 12e85f7217..fdf13765b7 --- a/fr/starter/generator.md +++ b/fr/starter/generator.md @@ -1,29 +1,34 @@ --- layout: page title: Générateur d'applications Express +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: fr +redirect_from: " " --- # Générateur d'applications Express Utilisez l'outil de générateur d'applications, `express`, pour créer rapidement un squelette d'application. -Installez `express` à l'aide de la commande suivante : +You can run the application generator with the `npx` command (available in Node.js 8.2.0). + +```bash +$ npx express-generator +``` -
    -
    -$ npm install express-generator -g
    -
    -
    +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` Affichez les options de commande à l'aide de l'option `-h` : -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -34,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` Par exemple, ce code crée une application Express nomée _myapp_. L'application sera crée dans le dossier _myapp_, lui meme placé dans le repertoir de travail courant. Le moteur de vue sera configuré avec Pug: -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -64,40 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` Ensuite, installez les dépendances : -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` Sous MacOS ou Linux, exécutez l'application à l'aide de la commande suivante : -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` Sous Windows, utilisez la commande suivante : -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` + +Installez `express` à l'aide de la commande suivante : + +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` Ensuite, chargez 'http://hôte_local:3000/' dans votre navigateur pour accéder à l'application. L'application générée possède la structure de répertoire suivante : -
    -
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -117,9 +118,10 @@ L'application générée possède la structure de répertoire suivante :
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    La structure d'application créée par le générateur est l'une des nombreuses manières possibles de structurer les applications Express. Vous avez toute latitude pour l'utiliser ou la modifier en fonction de vos besoins.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/fr/starter/hello-world.md b/fr/starter/hello-world.md old mode 100755 new mode 100644 index 00e0a7abbf..c33abf6c0a --- a/fr/starter/hello-world.md +++ b/fr/starter/hello-world.md @@ -1,8 +1,9 @@ --- layout: page title: Exemple "Hello world" Express +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang : fr +redirect_from: " " --- # Exemple Hello world @@ -12,13 +13,7 @@ Il s'agit de l'application Express la plus simple que vous puissiez créer. Cett [générateur Express](/{{ page.lang }}/starter/generator.html), qui crée l'échafaudage d'une application entière, avec des fichiers JavaScript, des modèles Pug et des sous-répertoires pour divers motifs.
    -Premièrement, créez un répertoire appelé `myapp`, rendez-vous dedans et exécutez la commande `npm init`. -Ensuite, installez `express` en tant que dépendance en suivant les instructions du [guide d'installation](/{{ page.lang }}/starter/installing.html). - -Dans le répertoire `myapp`, créez un fichier appelé `app.js` et ajoutez le code suivant : - -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -28,13 +23,18 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    -
    +``` L'application démarre un serveur et écoute le port 3000 à la recherche de connexions. L'application répond "Hello World!" aux demandes adressées -à l'URL racine (`/`) ou à la *route* racine. Pour tous les autres chemins d'accès, elle répondra par **404 Not Found**. +à l'URL racine (`/`) ou à la _route_ racine. Pour tous les autres chemins d'accès, elle répondra par **404 Not Found**. + +### Running Locally + +Premièrement, créez un répertoire appelé `myapp`, rendez-vous dedans et exécutez la commande `npm init`. Ensuite, installez `express` en tant que dépendance en suivant les instructions du [guide d'installation](/{{ page.lang }}/starter/installing.html). + +Dans le répertoire `myapp`, créez un fichier appelé `app.js` et ajoutez le code suivant :
    Les objets `req` (demande) et `res` (réponse) sont exactement les mêmes que ceux que Node fournit, vous pouvez donc appeler @@ -43,11 +43,10 @@ Les objets `req` (demande) et `res` (réponse) sont exactement les mêmes que ce Exécutez l'application avec la commande suivante : -
    -
    +```bash
     $ node app.js
    -
    -
    +``` Puis chargez [http://localhost:3000/](http://localhost:3000/) dans un navigateur pour consulter le résultat. +### [Previous: Installing ](/{{ page.lang }}/starter/installing.html)    [Next: Express Generator ](/{{ page.lang }}/starter/generator.html) diff --git a/fr/starter/installing.md b/fr/starter/installing.md old mode 100755 new mode 100644 index e60e2fb502..2c49018236 --- a/fr/starter/installing.md +++ b/fr/starter/installing.md @@ -1,59 +1,53 @@ --- layout: page title: Installation d'Express +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: fr +redirect_from: " " --- # Installation En supposant que [Node.js](https://nodejs.org/) est déjà installé, créez un répertoire pour héberger votre application et faites-en votre répertoire de travail. -
    -
    +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher.
    +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher.
    +
    +```bash
     $ mkdir myapp
     $ cd myapp
    -
    -
    +``` Utilisez la commande `npm init` afin de créer un fichier `package.json` pour votre application. Pour plus d'informations sur le fonctionnement du fichier `package.json`, voir [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). -
    -
    +```bash
     $ npm init
    -
    -
    +``` Cette commande vous invite à fournir un certain nombre d'informations, telles que le nom et la version de votre application. Pour le moment, vous pouvez simplement appuyer sur la touche RETURN pour accepter les valeurs par défaut, à l'exception de ce qui suit : -
    -
    +```
     entry point: (index.js)
    -
    -
    +``` Entrez `app.js` ou un nom de votre choix pour le fichier principal. Si vous souhaitez que le nom soit `index.js`, appuyez sur la touche RETURN pour accepter le nom de fichier par défaut suggéré. Installez ensuite Express dans le répertoire `myapp`, puis sauvegardez-le dans la liste des dépendances. Par exemple : -
    -
    -$ npm install express --save
    -
    -
    +```bash +$ npm install express +``` Pour installer Express de façon temporaire et ne pas l'ajouter à la liste des dépendances, omettez l'option `--save` : -
    -
    -$ npm install express
    -
    -
    +```bash +$ npm install express --no-save +```
    -Les modules Node.js installés à l'aide de l'option `--save` sont ajoutés à la liste des dépendances `dependencies`, dans le fichier `package.json`. -Par défaut, depuis la version 5.0, `npm install ` ajoute automatiquement le module Node.js à la liste des dépendances. -Par la suite, l'exécution de `npm install` dans le répertoire de l'application installera automatiquement les modules présents dans la liste des dépendances. +` ajoute automatiquement le module Node.js à la liste des dépendances. Par la suite, l'exécution de `npm install` dans le répertoire de l'application installera automatiquement les modules présents dans la liste des dépendances.
    + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/fr/starter/static-files.md b/fr/starter/static-files.md old mode 100755 new mode 100644 index ad345e5d78..0a2bc4e33d --- a/fr/starter/static-files.md +++ b/fr/starter/static-files.md @@ -1,8 +1,9 @@ --- layout: page title: Servir des fichiers statiques dans Express -menu: démarrage -lang: fr +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. +menu: starter +redirect_from: " " --- # Servir des fichiers statiques dans Express @@ -11,31 +12,33 @@ Pour servir des fichiers statiques tels que les images, les fichiers CSS et les fichiers JavaScript, utilisez la fonction de logiciel intermédiaire intégré `express.static` dans Express. -Passez le nom du répertoire qui contient les actifs -statiques dans la fonction de logiciel intermédiaire -`express.static` afin de commencer à servir -les fichiers directement. Par exemple, utilisez le code suivant pour +The function signature is: + +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +Par exemple, utilisez le code suivant pour servir des images, des fichiers CSS et des fichiers JavaScript dans un répertoire nommé `public` : -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +app.use(express.static('public')) +``` Maintenant, vous pouvez charger les fichiers qui sont dans le répertoire `public` : -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +```
    Express recherche les fichiers relatifs au répertoire statique, donc @@ -46,42 +49,36 @@ Pour utiliser plusieurs répertoires statiques actifs, utilisez la fonction middleware `express.static` plusieurs fois : -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` Express recherche les fichiers dans l'ordre dans lequel vous avez établi les répertoires statiques avec la fonction middleware `express.static`. -Pour créer un préfixe de chemin d'accès virtuel (dans lequel le -chemin d'accès n'existe pas vraiment dans le système de fichiers) -pour les fichiers qui sont servis par la fonction -`express.static`, [indiquez un -chemin de montage](/{{ page.lang }}/4x/api.html#app.use) pour le répertoire statique, comme démontré -ci-dessous : +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` Maintenant, vous pouvez charger les fichiers qui sont dans le répertoire `public` à partir du préfixe de chemin d'accès `/static`. -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` Cependant, le chemin d'accès que vous fournissez à la fonction `express.static` est en rapport avec @@ -90,8 +87,11 @@ vous exécutez l'application express à partir d'un autre répertoire, il est plus sûr d'utiliser le chemin d'accès absolu que vous voulez servir : -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +```js +const path = require('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.html). + +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/fr/support/index.md b/fr/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/fr/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/get-contributing.sh b/get-contributing.sh deleted file mode 100755 index 4b9742254f..0000000000 --- a/get-contributing.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -DEST="en/resources/contributing.md" - -# This script replaces the contents of a section with the contents from -# the annotated source address. - -href='' -level='' -while IFS= read -r line; do - if [[ -n "$href" ]] && [[ "$line" != '#'* || "$line" == "$level"'#'* ]]; then - continue - fi - - href='' - if [[ "$line" == '#'* ]]; then - title=${line##*\#} - level="${line:0:$((${#line} - ${#title}))}" - elif [[ "$line" == ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StrongLoop sponsoredExpress and Node.jsMeetups & Training - -Learn More - diff --git a/images/fork-icon.png b/images/fork-icon.png deleted file mode 100644 index 082c6d22d7..0000000000 Binary files a/images/fork-icon.png and /dev/null differ diff --git a/images/fork-icon@2x.png b/images/fork-icon@2x.png deleted file mode 100644 index 94f9135610..0000000000 Binary files a/images/fork-icon@2x.png and /dev/null differ diff --git a/images/loopback-link.png b/images/loopback-link.png deleted file mode 100644 index 4a2d8545db..0000000000 Binary files a/images/loopback-link.png and /dev/null differ diff --git a/images/loopback-link@2x.png b/images/loopback-link@2x.png deleted file mode 100644 index 0b98cdb72a..0000000000 Binary files a/images/loopback-link@2x.png and /dev/null differ diff --git a/images/node-interactive.png b/images/node-interactive.png deleted file mode 100644 index c5dd872d3f..0000000000 Binary files a/images/node-interactive.png and /dev/null differ diff --git a/images/node-interactive@2x.png b/images/node-interactive@2x.png deleted file mode 100644 index 218872cacf..0000000000 Binary files a/images/node-interactive@2x.png and /dev/null differ diff --git a/images/node_int15.png b/images/node_int15.png deleted file mode 100644 index 83b11e6851..0000000000 Binary files a/images/node_int15.png and /dev/null differ diff --git a/images/og.png b/images/og.png new file mode 100644 index 0000000000..07238428ce Binary files /dev/null and b/images/og.png differ diff --git a/images/sponsor.png b/images/sponsor.png deleted file mode 100644 index 49d3bab884..0000000000 Binary files a/images/sponsor.png and /dev/null differ diff --git a/images/sponsor@2x.png b/images/sponsor@2x.png deleted file mode 100644 index 2b8d342eaf..0000000000 Binary files a/images/sponsor@2x.png and /dev/null differ diff --git a/images/strongloop-logo.png b/images/strongloop-logo.png deleted file mode 100644 index af049aac52..0000000000 Binary files a/images/strongloop-logo.png and /dev/null differ diff --git a/images/strongloop-logo@2x.png b/images/strongloop-logo@2x.png deleted file mode 100644 index 2ef547545a..0000000000 Binary files a/images/strongloop-logo@2x.png and /dev/null differ diff --git a/index.md b/index.md index 357dac19be..e767af3754 100644 --- a/index.md +++ b/index.md @@ -1,43 +1,60 @@ --- layout: home title: Express - Node.js web application framework +description: "Express is a fast, unopinionated, minimalist web framework for Node.js, providing a robust set of features for web and mobile applications." menu: home -lang: en redirect_from: "/en/index.html" --- +
    - {% include header/header-{{ page.lang }}.html %} -
    - - Fast, unopinionated, minimalist web framework for Node.js + +

    Fast, unopinionated, minimalist web framework for Node.js

    -
    $ npm install express --save
    +
    $ npm install express --save
    +
    + +
    + +```javascript +const express = require('express') +const app = express() +const port = 3000 + +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` +
    + +{% if site.announcement %}
    - {% include announcement/announcement-en.md %} + {% include announcement.html %}
    +{% endif %}
    -
    -

    Web Applications

    Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. +

    Web Applications

    Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
    -
    -

    APIs

    With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy. +

    APIs

    With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy.
    -
    -

    Performance

    Express provides a thin layer of fundamental web application features, without obscuring Node.js features that you know and love. +

    Performance

    Express provides a thin layer of fundamental web application features, without obscuring Node.js features that you know and love.
    - -
    -

    Frameworks

    Many popular frameworks are based on Express. +
    +

    Middleware

    + Express is a lightweight and flexible routing framework with minimal core features + meant to be augmented through the use of Express middleware modules.
    -
    diff --git a/it/3x/api.md b/it/3x/api.md old mode 100755 new mode 100644 index 815d430eb3..66255944f9 --- a/it/3x/api.md +++ b/it/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - Riferimento API +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: it +redirect_from: " " --- +
    **Express 3.x NON È PIU' SUPPORTATO** - I problemi noti e non noti relativi alla sicurezza presenti in 3.x non sono stati indirizzati dall'ultimo aggiornamento (1 agosto 2015). Si consiglia di utilizzare l'ultima versione di Express. -
    - -

    API 3.x

    +I problemi noti e non noti relativi alla sicurezza presenti in 3.x non sono stati indirizzati dall'ultimo aggiornamento (1 agosto 2015). Si consiglia di utilizzare l'ultima versione di Express. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
    - - {% include api/en/3x/res.md %} +

    API 3.x

    - - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %}
    diff --git a/it/4x/api.md b/it/4x/api.md old mode 100755 new mode 100644 index 43c0bd1b5b..f316c1c89d --- a/it/4x/api.md +++ b/it/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - Riferimento API +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: it +redirect_from: " " --- +

    API 4.x

    - - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
    diff --git a/it/5x/api.md b/it/5x/api.md new file mode 100644 index 0000000000..a82c7c61a5 --- /dev/null +++ b/it/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - Riferimento API +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
    + +

    5.x API

    + +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
    diff --git a/it/advanced/best-practice-performance.md b/it/advanced/best-practice-performance.md old mode 100755 new mode 100644 index cef013b891..d2a429a77c --- a/it/advanced/best-practice-performance.md +++ b/it/advanced/best-practice-performance.md @@ -1,41 +1,48 @@ --- layout: page title: Best Practice sulle prestazioni utilizzando Express in fase di produzione +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: it +redirect_from: " " --- # Best practice sulla produzione: prestazioni e affidabilità -## Panoramica - In questo articolo vengono descritte le best practice sulle prestazioni e sull'affidabilità per le applicazioni Express implementate per la produzione. Questo argomento entra nel mondo di "devops", coprendo sia le operazioni che lo sviluppo tradizionale. Di conseguenza, le informazioni sono divise in due parti: -* [Operazioni da effettuare nel codice](#code) (la parte dello sviluppo). -* [Operazioni da effettuare nell'ambiente / configurazione](#env) (la parte delle operazioni). - - - -## Operazioni da effettuare nel codice +- Things to do in your code (the dev part): + - Utilizzare la compressione gzip + - [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://web.archive.org/web/20240000000000/https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) + - Gestire in modo appropriato le eccezioni + - [Handle exceptions properly](#handle-exceptions-properly) +- [Operazioni da effettuare nell'ambiente / configurazione](#env) (la parte delle operazioni). + - Impostare NODE_ENV su "produzione" + - Al contrario, utilizzare il middleware [serve-static](https://www.npmjs.com/package/serve-static) (o qualcosa di equivalente), ottimizzato per servire i file per le applicazioni Express. + - Eseguire l'applicazione in un cluster + - + - Utilizzare un servizio di bilanciamento del carico + - Utilizzare un proxy inverso + +## Things to do in your code {#in-code} Di seguito sono elencate alcune operazioni che è possibile effettuare nel codice per migliorare le prestazioni dell'applicazione: -* Utilizzare la compressione gzip -* Non utilizzare funzioni sincrone -* Utilizzare il middleware per servire file statici -* Effettuare correttamente la registrazione -* Gestire in modo appropriato le eccezioni +- Utilizzare la compressione gzip +- [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://web.archive.org/web/20240000000000/https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) +- Gestire in modo appropriato le eccezioni +- [Handle exceptions properly](#handle-exceptions-properly) ### Utilizzare la compressione gzip La compressione gzip è in grado di ridurre notevolmente la dimensione del contenuto della risposta e di conseguenza aumentare la velocità di un'applicazione web. Utilizzare il middleware di [compressione](https://www.npmjs.com/package/compression) per la compressione gzip nell'applicazione Express. Ad esempio: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` @@ -47,19 +54,11 @@ I metodi e le funzioni sincrone ostacolano il processo di esecuzione finché non Poiché Node e molti moduli forniscono versioni sicrone e asincrone delle relative funzioni, utilizzare sempre la versione asincrona nella produzione. L'unico caso in cui l'utilizzo di una funzione sincrona è giustificato, è allo startup iniziale. -Se si sta utilizzando Node.js 4.0+ o io.js 2.1.0+, è possibile utilizzare il flag della riga di comando `--trace-sync-io` per stampare un avviso e un'analisi dello stack ogniqualvolta che un'applicazione utilizza una API sincrona. Naturalmente, non si consiglia di utilizzarlo nella produzione, ma solo per assicurare che il codice sia pronto per la produzione. Consultare l'[aggiornamento settimanale per io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0) per ulteriori informazioni. - -### Utilizzare il middleware per servire file statici - -Nello sviluppo, è possibile utilizzare [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) per servire i file statici. Ma non effettuare questa operazione in fase di produzione, poiché questa funzione deve effettuare un processo di lettura dal file system per ciascuna richiesta file, quindi si verificherà una latenza importante e si andrà a influenzare le prestazioni dell'applicazione. Notare che `res.sendFile()` *non* viene implementato con la chiamata di sistema [sendfile](http://linux.die.net/man/2/sendfile), che lo renderebbe molto più efficiente. - -Al contrario, utilizzare il middleware [serve-static](https://www.npmjs.com/package/serve-static) (o qualcosa di equivalente), ottimizzato per servire i file per le applicazioni Express. - -Un'altra opzione potrebbe essere quella di utilizzare un proxy inverso per servire file statici; consultare [Utilizzare un proxy inverso](#proxy) per ulteriori informazioni. +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. Naturalmente, non si consiglia di utilizzarlo nella produzione, ma solo per assicurare che il codice sia pronto per la produzione. Consultare l'[aggiornamento settimanale per io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0) per ulteriori informazioni. ### Effettuare correttamente la registrazione -Solitamente, esistono due motivi per effettuare la registrazione dall'applicazione: per il debug e la registrazione dell'attività dell'applicazione (sostanzialmente, qualsiasi altra cosa). L'utilizzo di `console.log()` o `console.err()` per stampare i messaggi di log sul terminale, è un'operazione comune nello sviluppo. Ma [queste funzioni sono sincrone](https://nodejs.org/api/console.html#console_console_1) quando la destinazione è un terminale o un file, pertanto non sono adatte per la produzione, a meno che non si indirizzi l'output a un altro programma. +Solitamente, esistono due motivi per effettuare la registrazione dall'applicazione: per il debug e la registrazione dell'attività dell'applicazione (sostanzialmente, qualsiasi altra cosa). L'utilizzo di `console.log()` o `console.err()` per stampare i messaggi di log sul terminale, è un'operazione comune nello sviluppo. 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. #### Per il debug @@ -67,42 +66,27 @@ Se si sta effettuando la registrazione per motivi di debug, allora invece di uti #### Per l'attività dell'applicazione -Se si sta registrando l'attività dell'applicazione (ad esempio, si sta tenendo traccia del traffico e delle chiamate API), invece di utilizzare `console.log()`, utilizzare una libreria di registrazione quale [Winston](https://www.npmjs.com/package/winston) o [Bunyan](https://www.npmjs.com/package/bunyan). Per un confronto dettagliato di queste due librerie, consultare il post del blog di StrongLoop [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). +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. - - -### Gestire in modo appropriato le eccezioni +### Handle exceptions properly Le applicazioni Node danno origine a errori quando riscontrano eccezioni non rilevate. Se tali eccezioni non vengono gestite o se non si effettuano operazioni appropriate, l'applicazione Express si arresterà in modo anomalo. Seguendo i consigli descritti in [Riavvio automatico dell'applicazione](#restart), sarà possibile recuperare l'applicazione dopo un arresto anomalo. Fortunatamente, le applicazioni Express solitamente hanno tempi di avvio molto brevi. Tuttavia, per prima cosa è necessario evitare che si verifichino arresti anomali, e per effettuare ciò, è necessario gestire in modo appropriato le eccezioni. Per essere sicuri di gestire al meglio tutte le eccezioni, utilizzare le seguenti tecniche: -* [Utilizzare try-catch](#try-catch) -* [Utilizzare promises](#promises) +- [Utilizzare try-catch](#try-catch) +- [Utilizzare promises](#promises) Prima di leggere questi argomenti, è necessario avere una conoscenza base della gestione degli errori di Node/Express: utilizzo di error-first callback e diffusione degli errori al middleware. Node utilizza la convenzione "error-first callback" per restituire gli errori da funzioni asincrone, dove il primo parametro per la funzione callback è l'oggetto dell'errore, seguito dai dati nei parametri successivi. Per indicare un errore, indicare null come primo parametro. La funzione callback deve seguire in modo corrispondente la convenzione error-first callback per gestire l'errore in modo significativo. In Express, il miglior modo è quello di utilizzare la funzione next() per diffondere gli errori attraverso la catena middleware. Per ulteriori informazioni sulle nozioni di base della gestione degli errori, consultare: -* [Gestione degli errori in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Come creare applicazioni Node solide: Gestione degli errori](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (blog di StrongLoop) - -#### Cosa non fare - -Una cosa da *non* fare è quella di stare in ascolto per un evento `uncaughtException`, emesso quando un'eccezione si verifica ed è costante nel loop degli eventi. Se si aggiunge un programma di ascolto dell'evento per `uncaughtException` si cambierà il funzionamento predefinito del processo che sta riscontrando un'eccezione; il processo continuerà ad operare malgrado l'eccezione. Questo potrebbe risultare un ottimo modo per prevenire un arresto anomalo dell'applicazione, ma continuare ad utilizzare un'applicazione dopo che si è verificata un'eccezione non rilevata è pericoloso e non è consigliato, poiché lo stato del processo diventa non affidabile e non prevedibile. - -Inoltre, l'utilizzo di `uncaughtException` è ufficialmente riconosciuto come [non conforme](https://nodejs.org/api/process.html#process_event_uncaughtexception) ed esiste una [proposta](https://github.com/nodejs/node-v0.x-archive/issues/2582) per la relativa rimozione dal core. Quindi continuare a visualizzare un evento `uncaughtException` non è un buon segno. Ecco perché consigliamo di usufruire di più processi e supervisori: l'arresto anomalo e il riavvio sono spesso il modo più affidabile per ripristinare una situazione dopo un errore. - -Inoltre, non si consiglia di utilizzare l'opzione [domini](https://nodejs.org/api/domain.html). Solitamente non risolve il problema ed è considerato un modulo obsoleto. - - +- [Gestione degli errori in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### Utilizzare try-catch Try-catch è un linguaggio JavaScript che è possibile utilizzare per rilevare eccezioni in codice sincrono. Ad esempio, utilizzare try-catch, per gestire errori di analisi JSON come mostrato di seguito. -Utilizzare uno strumento come [JSHint](http://jshint.com/) o [JSLint](http://www.jslint.com/) come supporto nel rilevamento di eccezioni implicite quali [errori di riferimento su variabili non definite](http://www.jshint.com/docs/options/#undef). - Di seguito viene riportato un esempio di utilizzo di try-catch per la gestione di un'eccezione che dà origine a un arresto anomalo del processo. Questa funzione middleware accetta un parametro del campo query denominato "params" che è un oggetto JSON. @@ -110,9 +94,9 @@ Questa funzione middleware accetta un parametro del campo query denominato "para app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -123,107 +107,84 @@ app.get('/search', (req, res) => { Tuttavia, try-catch funziona solo per il codice sincrono. Poiché la piattaforma Node è principalmente asincrona (nello specifico in un ambiente di produzione), try-catch non sarà in grado di rilevare molte eccezioni. - - #### Utilizzare promises -Promises gestirà qualsiasi eccezione (sia implicita che esplicita) in blocchi di codice asincrono che utilizzano `then()`. Aggiungere `.catch(next)` alla fine della catena promise. Ad esempio: +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -Ora, tutti gli errori asincroni e sincroni vengono inoltrati al middleware degli errori. - -Tuttavia, esistono due punti a cui prestare attenzione: - -1. Tutto il codice asincrono deve restituire promises (ad eccezione di emettitori). Se una libreria particolare non restituire promises, convertire l'oggetto base utilizzando una funzione di supporto come [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Emettitori evento (come flussi) possono ancora dare origine ad eccezioni non rilevate. Quindi, assicurarsi di gestire l'evento di errore in modo appropriato, ad esempio: +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -Per ulteriori informazioni sulla gestione degli errori mediante l'utilizzo di promises, consultare: +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. + +#### Cosa non fare + +Una cosa da _non_ fare è quella di stare in ascolto per un evento `uncaughtException`, emesso quando un'eccezione si verifica ed è costante nel loop degli eventi. Se si aggiunge un programma di ascolto dell'evento per `uncaughtException` si cambierà il funzionamento predefinito del processo che sta riscontrando un'eccezione; il processo continuerà ad operare malgrado l'eccezione. Questo potrebbe risultare un ottimo modo per prevenire un arresto anomalo dell'applicazione, ma continuare ad utilizzare un'applicazione dopo che si è verificata un'eccezione non rilevata è pericoloso e non è consigliato, poiché lo stato del processo diventa non affidabile e non prevedibile. -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +Inoltre, l'utilizzo di `uncaughtException` è ufficialmente riconosciuto come [non conforme](https://nodejs.org/api/process.html#process_event_uncaughtexception) ed esiste una [proposta](https://github.com/nodejs/node-v0.x-archive/issues/2582) per la relativa rimozione dal core. Quindi continuare a visualizzare un evento `uncaughtException` non è un buon segno. Ecco perché consigliamo di usufruire di più processi e supervisori: l'arresto anomalo e il riavvio sono spesso il modo più affidabile per ripristinare una situazione dopo un errore. - +Inoltre, non si consiglia di utilizzare l'opzione [domini](https://nodejs.org/api/domain.html). Solitamente non risolve il problema ed è considerato un modulo obsoleto. ## Operazioni da effettuare nell'ambiente / configurazione Di seguito sono elencate alcune operazioni che è possibile effettuare nell'ambiente del sistema per migliorare le prestazioni dell'applicazione: -* Impostare NODE_ENV su "produzione" -* Verificare che l'applicazione sia in grado di riavviarsi automaticamente -* Eseguire l'applicazione in un cluster -* Memorizzare in cache i risultati della richiesta -* Utilizzare un servizio di bilanciamento del carico -* Utilizzare un proxy inverso +- Impostare NODE_ENV su "produzione" +- Al contrario, utilizzare il middleware [serve-static](https://www.npmjs.com/package/serve-static) (o qualcosa di equivalente), ottimizzato per servire i file per le applicazioni Express. +- Eseguire l'applicazione in un cluster +- +- Utilizzare un servizio di bilanciamento del carico +- Utilizzare un proxy inverso ### Impostare NODE_ENV su "produzione" -La variabile di ambiente NODE_ENV indica l'ambiente in cui è in esecuzione un'applicazione (solitamente, sviluppo o applicazione). Una delle cose più semplici da fare per migliorare le prestazioni, è impostare NODE_ENV su "produzione." +La variabile di ambiente NODE_ENV indica l'ambiente in cui è in esecuzione un'applicazione (solitamente, sviluppo o applicazione). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. L'impostazione di NODE_ENV su "produzione" consente ad Express di: -* Memorizzare in cache i template di visualizzazione. -* Memorizzare in cache i file CSS generati da stensioni CSS. -* Generare meno messaggi di errore ridondanti. +- Memorizzare in cache i template di visualizzazione. +- Memorizzare in cache i file CSS generati da stensioni CSS. +- Generare meno messaggi di errore ridondanti. -[I test hanno confermato](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) che seguendo queste indicazioni è possibile migliorare le prestazioni dell'applicazione di tre volte! +[Tests indicate](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! Se si ha la necessità di scrivere codice specifico dell'ambiente, è possibile selezionare il valore di NODE_ENV con `process.env.NODE_ENV`. Notare che la selezione del valore di qualsiasi variabile di ambiente influisce sulle prestazioni in modo negativo, quindi questa operazione deve essere effettuata con moderazione. -Nello sviluppo, solitamente si impostano le variabili di ambiente nella shell interattiva, ad esempio utilizzando `export` o il file `.bash_profile`. Ma solitamente non si consiglia di effettuare questa operazione su un server di produzione; al contrario, utilizzare il sistema init del sistema operativo (systemd o Upstart). La sezione successiva fornisce ulteriori dettagli sull'utilizzo in generale del sistema init, però anche impostare NODE_ENV è molto importante per le prestazioni (ed è facile da fare), evidenziato di seguito. - -Con Upstart, utilizzare la parola chiave `env` nel file job. Ad esempio: - -
    -
    -# /etc/init/env.conf
    - env NODE_ENV=production
    -
    -
    - -Per ulteriori informazioni, consultare [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). +Nello sviluppo, solitamente si impostano le variabili di ambiente nella shell interattiva, ad esempio utilizzando `export` o il file `.bash_profile`. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). La sezione successiva fornisce ulteriori dettagli sull'utilizzo in generale del sistema init, però anche impostare NODE_ENV è molto importante per le prestazioni (ed è facile da fare), evidenziato di seguito. Con systemd, utilizzare la direttiva `Environment` nel file unit. Ad esempio: -
    -
    +```sh
     # /etc/systemd/system/myservice.service
     Environment=NODE_ENV=production
    -
    -
    - -Per ulteriori informazioni, consultare [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). +``` -Se si sta utilizzando StrongLoop Process Manager, è inoltre possibile [impostare la variabile di ambiente quando si installa StrongLoop PM as a service](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### Verificare che l'applicazione sia in grado di riavviarsi automaticamente In fase di produzione, l'applicazione non deve mai andare offline. Ciò significa che deve riavviarsi nel caso in cui sia l'applicazione che il server terminino in modo anomalo. Anche se ovviamente si spera che entrambe queste situazioni non si verifichino mai, realisticamente è necessario considerare l'eventualità di: -* Utilizzare un process manager per riavviare l'applicazione (e Node) quando termina in modo anomalo. -* Utilizzare il sistema init fornito dal sistema operativo per riavviare il process manager quando il sistema operativo termina in modo anomalo. È inoltre possibile utilizzare il sistema init senza un process manager. +- Utilizzare un process manager per riavviare l'applicazione (e Node) quando termina in modo anomalo. +- Utilizzare il sistema init fornito dal sistema operativo per riavviare il process manager quando il sistema operativo termina in modo anomalo. È inoltre possibile utilizzare il sistema init senza un process manager. Le applicazioni Node terminano in modo anomalo se riscontrano eccezioni non rilevate. La prima cosa da fare è verificare che l'applicazione sia stata verificata e che sia in grado di gestire tutte le eccezioni (consultare [Gestire in modo appropriato le eccezioni](#exceptions) per dettagli). Come prevenzione, attivare un meccanismo che assicuri che applicazione si riavvii automaticamente in caso di arresto anomalo. @@ -233,55 +194,35 @@ Nello sviluppo, l'applicazione è stata avviata semplicemente dalla riga comandi Oltre a fare in modo di riavviare l'applicazione in caso di arresto anomalo, un process manager consente di: -* Ottenere insight relativi alle prestazioni di runtime e al consumo delle risorse. -* Modificare le impostazioni in modo dinamico per migliorare le prestazioni. -* Controllare il processo di clustering (StrongLoop PM e pm2). - -I process manager più noti per Node sono i seguenti: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) +- Ottenere insight relativi alle prestazioni di runtime e al consumo delle risorse. +- Modificare le impostazioni in modo dinamico per migliorare le prestazioni. +- Control clustering (pm2). -Per un paragone a livello di funzioni dei tre process manager, consultare l'indirizzo [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Per informazioni più dettagliate su tutti e tre i process manager, consultare [Process manager per le applicazioni Express](/{{ page.lang }}/advanced/pm.html). - -L'utilizzo di questi process manager sarà sufficiente per far restare attiva l'applicazione, anche se dovesse capitare che si arresti in modo anomalo. - -Tuttavia, StrongLoop PM dispone di molte funzioni che sono indicate in modo specifico per l'implementazione della produzione. È possibile utilizzarle insieme ai relativi strumenti di StrongLoop per: - -* Creare e confezionare l'applicazione localmente, quindi implementarla in modo sicuro al sistema di produzione. -* Riavviare automaticamente l'applicazione se termina in modo anomalo per qualsiasi motivo. -* Gestire i cluster in modo remoto. -* Visualizzare i profili CPU e accumulare le istantanee per ottimizzare le prestazioni e diagnosticare le perdite di memoria. -* Visualizzare le metriche delle prestazioni per l'applicazione. -* Scalare facilmente a più host con un controllo integrato per il servizio di bilanciamento del carico Nginx. - -Come mostrato di seguito, quando si installa StrongLoop PM come servizio del sistema operativo utilizzando il sistema init, si riavvierà automaticamente quando si riavvia il sistema. Pertanto, consentirà ai processi delle applicazioni e ai cluster di restare sempre attivi. +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. #### Utilizzare un sistema init -Il successivo livello di affidabilità è quello di assicurare che l'applicazione venga riavviata quando si riavvia il server. I sistemi possono ancora arrestarsi per moltissimi motivi. Per fare in modo che l'applicazione si riavvii nel caso in cui un server si arresti in modo anomalo, utilizzare il sistema init integrato al sistema operativo. Oggi, i due sistemi init principali in uso sono [systemd](https://wiki.debian.org/systemd) e [Upstart](http://upstart.ubuntu.com/). +Il successivo livello di affidabilità è quello di assicurare che l'applicazione venga riavviata quando si riavvia il server. I sistemi possono ancora arrestarsi per moltissimi motivi. Per fare in modo che l'applicazione si riavvii nel caso in cui un server si arresti in modo anomalo, utilizzare il sistema init integrato al sistema operativo. The main init system in use today is [systemd](https://wiki.debian.org/systemd). Esistono due modi per utilizzare i sistemi init con l'applicazione Express: -* Far eseguire l'applicazione in un process manager e installare il process manager come servizio con il sistema init. Il process manager riavvierà l'applicazione nel caso in cui termini in modo anomalo e il sistema init riavvierà il process manager quando si riavvia il sistema operativo. Questa è la procedura consigliata. -* Far eseguire l'applicazione (e Node) direttamente con il sistema init. Questa operazione risulta più semplice ma non si hanno gli stessi vantaggi dell'utilizzo di un process manager. +- Far eseguire l'applicazione in un process manager e installare il process manager come servizio con il sistema init. Il process manager riavvierà l'applicazione nel caso in cui termini in modo anomalo e il sistema init riavvierà il process manager quando si riavvia il sistema operativo. Questa è la procedura consigliata. +- Far eseguire l'applicazione (e Node) direttamente con il sistema init. Questa operazione risulta più semplice ma non si hanno gli stessi vantaggi dell'utilizzo di un process manager. ##### Systemd Systemd è un sistema Linux e un service manager. Le più importanti distribuzioni Linux hanno utilizzato systemd come sistema init predefinito. -Un file di configurazione del servizio systemd è denominato *unit file*, con un nome file che termina con .service. Segue un unit file di esempio per gestire un'applicazione Node direttamente (sostituire il testo in grassetto con i valori appropriati per il proprio sistema e applicazione): +Un file di configurazione del servizio systemd è denominato _unit file_, con un nome file che termina con .service. Segue un unit file di esempio per gestire un'applicazione Node direttamente (sostituire il testo in grassetto con i valori appropriati per il proprio sistema e applicazione): Replace the values enclosed in `` for your system and app: -
    -
    +```sh
     [Unit]
    -Description=Awesome Express App
    +Description=
     
     [Service]
     Type=simple
    -ExecStart=/usr/local/bin/node /projects/myapp/index.js
    -WorkingDirectory=/projects/myapp
    +ExecStart=/usr/local/bin/node 
    +WorkingDirectory=
     
     User=nobody
     Group=nogroup
    @@ -302,111 +243,15 @@ Restart=always
     
     [Install]
     WantedBy=multi-user.target
    -
    -
    -Per ulteriori informazioni su systemd, consultare [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM in qualità di servizio systemd - -È possibile installare facilmente StrongLoop Process Manager in qualità di servizio systemd. Dopo l'installazione, quando il server si riavvia, si riavvierà automaticamente StrongLoop PM, il quale riavvierà di conseguenza tutte le applicazioni che sta gestendo. - -Per installare StrongLoop PM in qualità di servizio systemd: - -
    -
    -$ sudo sl-pm-install --systemd
    -
    -
    - -Successivamente, avviare il servizio con: - -
    -
    -$ sudo /usr/bin/systemctl start strong-pm
    -
    -
    - -Per ulteriori informazioni, consultare [Configurazione di un host di produzione (documentazione StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart è uno strumento di sistema disponibile su molte distribuzioni Linux per l'avvio delle attività e dei servizi durante lo startup del sistema, per l'arresto delle stesse durante la fase di shutdown e per il controllo delle stesse. È possibile configurare l'applicazione Express o il process manager in qualità di servizio e successivamente Upstart le riavvierà automaticamente quando terminano in modo anomalo. - -Un servizio Upstart è definito in un file di configurazione del lavoro (anche noto come "lavoro") con un nome file che termina con `.conf`. Il seguente esempio mostra come creare un lavoro denominato "myapp" per un'applicazione denominata "myapp" con il file principale ubicato in `/projects/myapp/index.js`. - -Creare un file denominato `myapp.conf` in `/etc/init/` con il seguente contenuto (sostituire il testo in grassetto con i valori appropriati per il proprio sistema e applicazione): - -
    -
    -# When to start the process
    -start on runlevel [2345]
    -
    -# When to stop the process
    -stop on runlevel [016]
    -
    -# Increase file descriptor limit to be able to handle more requests
    -limit nofile 50000 50000
    -
    -# Use production mode
    -env NODE_ENV=production
    -
    -# Run as www-data
    -setuid www-data
    -setgid www-data
    -
    -# Run from inside the app dir
    -chdir /projects/myapp
    -
    -# The process to start
    -exec /usr/local/bin/node /projects/myapp/index.js
    -
    -# Restart the process if it is down
    -respawn
    -
    -# Limit restart attempt to 10 times within 10 seconds
    -respawn limit 10 10
    -
    -
    - -NOTA: questo script richiede Upstart 1.4 o versione successiva, supportato su Ubuntu 12.04-14.10. - -Poiché il lavoro è configurato per essere eseguito quando si avvia il sistema, l'applicazione verrà avviata insieme al sistema operativo e riavviata automaticamente se l'applicazione termina in modo anomalo o se il sistema si arresta. - -Oltre a riavviare automaticamente l'applicazione, Upstart consente di utilizzare i seguenti comandi: - -* `start myapp` – Avviare l'applicazione -* `restart myapp` – Riavviare l'applicazione -* `stop myapp` – Arrestare l'applicazione. - -Per ulteriori informazioni su Upstart, consultare [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM in qualità di servizio Upstart - -È possibile installare facilmente StrongLoop Process Manager in qualità di servizio Upstart. Dopo l'installazione, quando il server si riavvia, si riavvierà automaticamente StrongLoop PM, il quale riavvierà di conseguenza tutte le applicazioni che sta gestendo. - -Per installare StrongLoop PM in qualità di servizio Upstart 1.4: - -
    -
    -$ sudo sl-pm-install
    -
    -
    - -Successivamente, eseguire il servizio con: - -
    -
    -$ sudo /sbin/initctl start strong-pm
    -
    -
    +``` -NOTA: su sistemi che non supportano Upstart 1.4, i comandi sono leggermente differenti. Consultare [Configurazione di un host di produzione (documentazione StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) per ulteriori informazioni. +Per ulteriori informazioni su systemd, consultare [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). ### Eseguire l'applicazione in un cluster In un sistema multicore, è possibile aumentare le prestazioni di un'applicazione Node di molte volte avviando un cluster di processi. Un cluster esegue molte istanze di un'applicazione, nel caso ideale, un'istanza su ciascun core CPU, quindi, distribuendo il carico e le attività tra le istanze. - +![Balancing between application instances using the cluster API](/images/clustering.png) IMPORTANTE: poiché le istanze dell'applicazione vengono eseguite come processi separati, non condividono lo stesso spazio di memoria. Ossia, gli oggetti sono locali rispetto a ciascuna istanza dell'applicazione. Pertanto, non è possibile conservare lo stato nel codice dell'applicazione. Tuttavia, è possibile utilizzare un datastore in-memory, ad esempio [Redis](http://redis.io/) per memorizzare lo stato e i dati relativi alla sessione. Questa condizione si applica fondamentalmente a tutti i moduli di scaling orizzontale, se il processo di clustering viene effettuato con più processi o più server fisici. @@ -414,45 +259,52 @@ Nelle applicazioni sottoposte a cluster, i processi di lavoro possono ternare in #### Utilizzo del modulo cluster di Node -Il processo di clustering è stato reso possibile con il [cluster module](https://nodejs.org/docs/latest/api/cluster.html) di Node. Ciò consente a un processo principale di dare origine a processi di lavoro e di distribuire le connessioni in entrata tra i processi di lavoro. Tuttavia, invece di utilizzare direttamente questo modulo, è meglio utilizzare uno dei molti strumenti disponibili che svolgono questa attività automaticamente; ad esempio [node-pm](https://www.npmjs.com/package/node-pm) o [cluster-service](https://www.npmjs.com/package/cluster-service). +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). Ciò consente a un processo principale di dare origine a processi di lavoro e di distribuire le connessioni in entrata tra i processi di lavoro. + +#### 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). -#### Utilizzo di StrongLoop PM +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. -Se si implementa l'applicazione a StrongLoop Process Manager (PM), è possibile sfruttare i vantaggi del processo di clustering *senza* dover modificare il codice dell'applicazione. +To enable cluster mode, start your application like so: -Quando StrongLoop Process Manager (PM) esegue un'applicazione, la esegue automaticamente in un cluster con un numero di processi di lavoro equivalente al numero di core CPU presenti sul sistema. È possibile modificare manualmente il numero di processi di lavoro nel cluster utilizzando lo strumento della riga comandi senza arrestare l'applicazione. +```bash +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ 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. -Ad esempio, se l'applicazione è stata implementata su prod.foo.com e StrongLoop PM è in ascolto sulla porta 8701 (quella predefinita), per impostare la dimensione del cluster a otto utilizzando slc: +Once running, the application can be scaled like so: -
    -
    -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
    -
    -
    +```bash +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ pm2 scale my-app 2 +``` -Per ulteriori informazioni sul processo di clustering con StrongLoop PM, consultare [Processo di clustering](https://docs.strongloop.com/display/SLC/Clustering) nella documentazione StrongLoop. +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. ### Memorizzare in cache i risultati della richiesta Un'altra strategia per migliorare le prestazioni in fase di produzione è quella di memorizzare in cache i risultati delle richieste, in modo tale che l'applicazione non debba gestire nuovamente la stessa richiesta. -Utilizzare un server di memorizzazione in cache quale [Varnish](https://www.varnish-cache.org/) o [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (vedere anche [Nginx Caching](https://serversforhackers.com/nginx-caching/)) per migliorare notevolmente la velocità e le prestazioni dell'applicazione. +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### Utilizzare un servizio di bilanciamento del carico A prescindere da quanto sia ottimizzata un'applicazione, una singola istanza è in grado di gestire solo una quantità limitata di carico e traffico. Un modo per scalare un'applicazione è quello di eseguire più delle proprie istanze e distribuire il traffico tramite un servizio di bilanciamento del carico. L'impostazione di un servizio di bilanciamento del carico può migliorare la velocità e le prestazioni dell'applicazione e abilitarla a scalare di più di quanto sia possibile fare con una singola istanza. -Un servizio di bilanciamento del carico è solitamente un proxy inverso che gestisce il traffico a e d più istanze di applicazione e server. È possibile impostare facilmente un servizio di bilanciamento del carico per l'applicazione utilizzando [Nginx](http://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). - -Con il servizio di bilanciamento del carico, è possibile che sia necessario garantire che le richieste associate a un ID sessione particolare si connettano al processo che le ha originate. Questo processo è noto come *affinità sessione* o *sessioni delicate*. Si consiglia di utilizzare un data store, ad esempio Redis, per i dati sessione (a seconda dell'applicazione). Per informazioni, consultare [Utilizzo di più nodi](http://socket.io/docs/using-multiple-nodes/). - -#### Utilizzo di StrongLoop PM con un servizio di bilanciamento del carico Nginx +Un servizio di bilanciamento del carico è solitamente un proxy inverso che gestisce il traffico a e d più istanze di applicazione e server. 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). -[StrongLoop Process Manager](http://strong-pm.io/) si integra con un controller Nginx, rendendo semplice il processo di configurazione di ambienti di produzione multi host. Per ulteriori informazioni, consultare [Processo di scaling su più server](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (documentazione StrongLoop). - +Con il servizio di bilanciamento del carico, è possibile che sia necessario garantire che le richieste associate a un ID sessione particolare si connettano al processo che le ha originate. Questo processo è noto come _affinità sessione_ o _sessioni delicate_. Si consiglia di utilizzare un data store, ad esempio Redis, per i dati sessione (a seconda dell'applicazione). Per informazioni, consultare [Utilizzo di più nodi](https://socket.io/docs/v4/using-multiple-nodes/). ### Utilizzare un proxy inverso Un proxy inverso si trova davanti a un'applicazione web ed esegue le operazioni di supporto sulle richieste, oltre a indirizzare le richieste all'applicazione. Inoltre, è in grado di gestire pagine di errore, compressioni, memorizzazioni in cache e il bilanciamento del carico. -Le attività di gestione che non richiedono la conoscenza dello stato dell'applicazione per un proxy inverso consentono ad Express di eseguire attività dell'applicazione specializzate. Per questo motivo, si consiglia di eseguire Express dietro un proxy inverso come [Nginx](https://www.nginx.com/) o [HAProxy](http://www.haproxy.org/) in fase di produzione. +Le attività di gestione che non richiedono la conoscenza dello stato dell'applicazione per un proxy inverso consentono ad Express di eseguire attività dell'applicazione specializzate. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/it/advanced/best-practice-security.md b/it/advanced/best-practice-security.md old mode 100755 new mode 100644 index b87398943b..d7c9ecba1e --- a/it/advanced/best-practice-security.md +++ b/it/advanced/best-practice-security.md @@ -1,23 +1,49 @@ --- layout: page title: Best Practice sulla sicurezza per Express in fase di produzione +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: it +redirect_from: " " --- # Best Practice sulla produzione: Sicurezza ## Panoramica -Il termine *"produzione"* si riferisce alla fase nel ciclo di vita del software quando un'applicazione o API è solitamente disponibile per gli utenti finali o i consumatori. Al contrario, nella fase *"sviluppo"*, si sta ancora scrivendo e verificando il codice e l'applicazione non è aperta ad accessi esterni. Gli ambienti di sistema corrispondenti sono noti rispettivamente come ambienti di *produzione* e di *sviluppo*. +Il termine _"produzione"_ si riferisce alla fase nel ciclo di vita del software quando un'applicazione o API è solitamente disponibile per gli utenti finali o i consumatori. Al contrario, nella fase _"sviluppo"_, si sta ancora scrivendo e verificando il codice e l'applicazione non è aperta ad accessi esterni. Gli ambienti di sistema corrispondenti sono noti rispettivamente come ambienti di _produzione_ e di _sviluppo_. Gli ambienti di sviluppo e produzione sono solitamente configurati diversamente e hanno requisiti molto differenti. Ciò che potrebbe andare bene nello sviluppo potrebbe non essere accettato nella produzione. Ad esempio, in un ambiente di sviluppo è possibile che si richieda una registrazione degli errori ridondante per il processo di debug, mentre la stessa richiesta in un ambiente di produzione potrebbe mettere a rischio la sicurezza. Inoltre, in un ambiente di sviluppo non è necessario preoccuparsi della scalabilità, dell'affidabilità e delle prestazioni, mentre nella produzione è fondamentale tenerne conto. +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} + In questo articolo vengono descritte alcune best practice sulla sicurezza per le applicazioni Express distribuite per la produzione. +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [hsts](https://github.com/helmetjs/hsts) imposta l'intestazione `Strict-Transport-Security` che rafforza connessioni (HTTP su SSL/TLS) sicure per il server. + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - Se si utilizza `helmet.js`, questa operazione sarà effettuata per conto dell'utente. + - [Reduce fingerprinting](#reduce-fingerprinting) + - [xssFilter](https://github.com/helmetjs/x-xss-protection) imposta `X-XSS-Protection` per abilitare il filtro XSS (Cross-site scripting) nei browser web più recenti. + - [noCache](https://github.com/helmetjs/nocache) imposta le intestazioni `Cache-Control` e Pragma per disabilitare la memorizzazione in cache della parte client. + - [ieNoOpen](https://github.com/helmetjs/ienoopen) imposta `X-Download-Options` per IE8+. + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) + - [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) rimuove l'intestazione `X-Powered-By`. + - [Additional considerations](#additional-considerations) + ## Non utilizzare versioni obsolete o vulnerabili di Express -Express 2.x e 3.x non sono più supportati. I problemi relativi alla sicurezza e alle prestazioni in queste versioni non verranno risolti. Non utilizzare queste versioni! Se non è stato effettuato l'aggiornamento alla versione 4, consultare la [guida alla migrazione](/{{ page.lang }}/guide/migrating-4.html). +Express 2.x e 3.x non sono più supportati. I problemi relativi alla sicurezza e alle prestazioni in queste versioni non verranno risolti. Non utilizzare queste versioni! Se non è stato effettuato l'aggiornamento alla versione 4, consultare la [guida alla migrazione](/{{ page.lang }}/guide/migrating-4.html). Inoltre, assicurarsi che non si stia utilizzando nessuna delle versioni vulnerabili di Express elencate nella [pagina Aggiornamenti sulla sicurezza](/{{ page.lang }}/advanced/security-updates.html). Nel caso si stia utilizzando una di queste versioni, effettuare l'aggiornamento a una versione aggiornata, preferibilmente l'ultima. @@ -25,57 +51,122 @@ Inoltre, assicurarsi che non si stia utilizzando nessuna delle versioni vulnerab Se l'applicazione utilizza o trasmette dati riservati, utilizzare [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) per proteggere la connessione e i dati. Questa tecnologia codifica i dati prima che vengano inviati dal client al server, proteggendo i dati da alcuni attacchi comuni (e facili) da parte di hacker. Anche se le richieste Ajax e POST possono non essere visibili e "nascoste" nei browser, il relativo traffico di rete è vulnerabile agli attacchi [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) e [man-in-the-middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -Sicuramente si conosce la crittografia SSL (Secure Socket Layer). [TLS non è altro che un miglioramento di SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). In altre parole, se prima si utilizzava SSL, considerare l'opportunità di passare a TLS. Consigliamo di utilizzare Nginx per gestire la TLS. Per informazioni su come configurare correttamente TLS su Nginx (e altri server), consultare [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). +Sicuramente si conosce la crittografia SSL (Secure Socket Layer). [TLS non è altro che un miglioramento di SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx). In altre parole, se prima si utilizzava SSL, considerare l'opportunità di passare a TLS. Consigliamo di utilizzare Nginx per gestire la TLS. Per informazioni su come configurare correttamente TLS su Nginx (e altri server), consultare [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). Inoltre, uno strumento molto semplice da utilizzare per ottenere un certificato gratuito TLS è [Let's Encrypt](https://letsencrypt.org/about/), un CA (certificate authority) gratuito, automatizzato e open fornito da [Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/). +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## Utilizzare Helmet [Helmet](https://www.npmjs.com/package/helmet) è utile per proteggere l'applicazione da alcune vulnerabilità web note configurando le intestazioni HTTP in modo appropriato. -Attualmente, Helmet non è altro che una raccolta di nove funzioni middleware più piccole che impostano le intestazioni HTTP relative alla sicurezza: +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* [csp](https://github.com/helmetjs/csp) imposta l'intestazione `Content-Security-Policy` per impedire attacchi XSS (cross-site scripting) e altri attacchi da altri siti. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) rimuove l'intestazione `X-Powered-By`. -* [hsts](https://github.com/helmetjs/hsts) imposta l'intestazione `Strict-Transport-Security` che rafforza connessioni (HTTP su SSL/TLS) sicure per il server. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) imposta `X-Download-Options` per IE8+. -* [noCache](https://github.com/helmetjs/nocache) imposta le intestazioni `Cache-Control` e Pragma per disabilitare la memorizzazione in cache della parte client. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) imposta `X-Content-Type-Options` per impedire ai browser di effettuare l'analisi MIME di una risposta fuori dal contenuto dichiarato. -* [frameguard](https://github.com/helmetjs/frameguard) imposta l'intestazione `X-Frame-Options` per fornire la protezione [clickjacking](https://www.owasp.org/index.php/Clickjacking). -* [xssFilter](https://github.com/helmetjs/x-xss-protection) imposta `X-XSS-Protection` per abilitare il filtro XSS (Cross-site scripting) nei browser web più recenti. +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. Installare Helmet come qualsiasi altro modulo: -
    -
    -$ npm install --save helmet
    -
    -
    +```bash +$ npm install helmet +``` Successivamente, per utilizzarlo nel codice: -
    -
    -...
    -var helmet = require('helmet');
    -app.use(helmet());
    -...
    -
    -
    +```js +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... +``` + +## Reduce fingerprinting + +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. + +By default, Express sends the `X-Powered-By` response header that you can +disable using the `app.disable()` method: + +```js +app.disable('x-powered-by') +``` + +{% capture powered-advisory %} + +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. + +{% endcapture %} -### Disattivare almeno l'intestazione X-Powered-By +{% include admonitions/note.html content=powered-advisory %} -Se non si desidera Helmet, disattivare almeno l'intestazione `X-Powered-By`. Gli hacker possono utilizzare questa intestazione (abilitata per impostazione predefinita) per rilevare le applicazioni su cui è in esecuzione Express e successivamente avviare attacchi indirizzati in modo specifico. +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): -Quindi, la miglior cosa da fare è disattivare l'intestazione con il metodo `app.disable()`: +```js +// last app.use calls right before app.listen(): -
    -
    -app.disable('x-powered-by');
    -
    -
    +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) -Se si utilizza `helmet.js`, questa operazione sarà effettuata per conto dell'utente. +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## Utilizzare i cookie in modo sicuro @@ -83,78 +174,109 @@ Per fare in modo che i cookie non espongano a rischi l'applicazione, non utilizz Esistono due moduli di sessione cookie middleware principali: -* [express-session](https://www.npmjs.com/package/express-session) che sostituisce il middleware `express.session` integrato a Express 3.x. -* [cookie-session](https://www.npmjs.com/package/cookie-session) che sostituisce il middleware `express.cookieSession` integrato a Express 3.x. +- [express-session](https://www.npmjs.com/package/express-session) che sostituisce il middleware `express.session` integrato a Express 3.x. +- [cookie-session](https://www.npmjs.com/package/cookie-session) che sostituisce il middleware `express.cookieSession` integrato a Express 3.x. -La differenza principale tra questi due moduli è nel modo in cui salvano i dati di sessione dei cookie. Il middleware [express-session](https://www.npmjs.com/package/express-session) memorizza i dati di sessione sul server; salva l'ID sessione nello stesso cookie e non nei dati di sessione. Per impostazione predefinita, utilizza il processo di memorizzazione in-memory e non è progettato per un ambiente di produzione. Nella produzione, sarà necessario configurare un processo di memorizzazione della sessione scalabile; consultare l'elenco di [compatible session stores](https://github.com/expressjs/session#compatible-session-stores). +La differenza principale tra questi due moduli è nel modo in cui salvano i dati di sessione dei cookie. Il middleware [express-session](https://www.npmjs.com/package/express-session) memorizza i dati di sessione sul server; salva l'ID sessione nello stesso cookie e non nei dati di sessione. Per impostazione predefinita, utilizza il processo di memorizzazione in-memory e non è progettato per un ambiente di produzione. Nella produzione, sarà necessario configurare un processo di memorizzazione della sessione scalabile; consultare l'elenco di [compatible session stores](https://github.com/expressjs/session#compatible-session-stores). -Al contrario, il middleware [cookie-session](https://www.npmjs.com/package/cookie-session) implementa la memorizzazione di backup dei cookie: suddivide in serie l'intera sessione per il cookie, piuttosto che una chiave di sessione. Utilizzarlo solo quando i dati di sessione sono relativamente piccoli e facilmente codificati come valori primitivi (piuttosto che oggetti). Poiché si presuppone che i browser supportino almeno 4096 byte per cookie, per non superare il limite, non superare la dimensione di 4093 byte per dominio. Inoltre, fare attenzione perché i dati dei cookie saranno visibili al cliente, quindi, se per qualche motivo devono rimanere sicuri o non visibili, la scelta di utilizzare express-session potrebbe essere quella giusta. +Al contrario, il middleware [cookie-session](https://www.npmjs.com/package/cookie-session) implementa la memorizzazione di backup dei cookie: suddivide in serie l'intera sessione per il cookie, piuttosto che una chiave di sessione. Utilizzarlo solo quando i dati di sessione sono relativamente piccoli e facilmente codificati come valori primitivi (piuttosto che oggetti). Poiché si presuppone che i browser supportino almeno 4096 byte per cookie, per non superare il limite, non superare la dimensione di 4093 byte per dominio. Inoltre, fare attenzione perché i dati dei cookie saranno visibili al cliente, quindi, se per qualche motivo devono rimanere sicuri o non visibili, la scelta di utilizzare express-session potrebbe essere quella giusta. ### Non utilizzare il nome del cookie della sessione predefinito -L'utilizzo del nome del cookie della sessione predefinito potrebbe esporre l'applicazione ad attacchi da parte di hacker. Il problema di sicurezza messo in discussione è simile a quello di `X-Powered-By`: un potenziale hacker potrebbe utilizzarlo per individuare il server e indirizzare gli attacchi di conseguenza. +L'utilizzo del nome del cookie della sessione predefinito potrebbe esporre l'applicazione ad attacchi da parte di hacker. Il problema di sicurezza messo in discussione è simile a quello di `X-Powered-By`: un potenziale hacker potrebbe utilizzarlo per individuare il server e indirizzare gli attacchi di conseguenza. Per evitare questo problema, utilizzare i nomi dei cookie predefiniti; ad esempio, utilizzando il middleware [express-session](https://www.npmjs.com/package/express-session): -
    -
    -var session = require('express-session');
    +```js
    +const session = require('express-session')
     app.set('trust proxy', 1) // trust first proxy
    -app.use( session({
    -   secret : 's3Cur3',
    -   name : 'sessionId',
    -  })
    -);
    -
    -
    +app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) +``` ### Impostare le opzioni di sicurezza dei cookie Impostare le seguenti opzioni per i cookie per aumentare la sicurezza: -* `secure` - Assicura che il browser invii il cookie solo tramite HTTPS. -* `httpOnly` - Assicura che il cookie venga inviato solo tramite HTTP, non JavaScript del client, questa procedura consentirà una protezione da attacchi XSS (cross-site scripting). -* `domain` - Indica il dominio del cookie; utilizzarlo per fare un confronto con il dominio del server in cui è stato richiesto l'URL. Se corrispondono, come fase successiva verificare l'attributo del percorso. -* `path` - Indica il percorso del cookie; utilizzarlo per fare un confronto con il percorso di richiesta. Se questo e il dominio corrispondono, inviare il cookie nella richiesta. -* `expires` - Utilizzarlo per impostare la data di scadenza per i cookie permanenti. +- `secure` - Assicura che il browser invii il cookie solo tramite HTTPS. +- `httpOnly` - Assicura che il cookie venga inviato solo tramite HTTP, non JavaScript del client, questa procedura consentirà una protezione da attacchi XSS (cross-site scripting). +- `domain` - Indica il dominio del cookie; utilizzarlo per fare un confronto con il dominio del server in cui è stato richiesto l'URL. Se corrispondono, come fase successiva verificare l'attributo del percorso. +- `path` - Indica il percorso del cookie; utilizzarlo per fare un confronto con il percorso di richiesta. Se questo e il dominio corrispondono, inviare il cookie nella richiesta. +- `expires` - Utilizzarlo per impostare la data di scadenza per i cookie permanenti. Esempio di utilizzo del middleware [cookie-session](https://www.npmjs.com/package/cookie-session): -
    -
    -var session = require('cookie-session');
    -var express = require('express');
    -var app = express();
    +```js
    +const session = require('cookie-session')
    +const express = require('express')
    +const app = express()
     
    -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
    +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
     app.use(session({
       name: 'session',
       keys: ['key1', 'key2'],
    -  cookie: { secure: true,
    -            httpOnly: true,
    -            domain: 'example.com',
    -            path: 'foo/bar',
    -            expires: expiryDate
    -          }
    -  })
    -);
    -
    -
    - -## Ulteriori informazioni - -Ecco alcuni consigli sull'eccellente [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Fare riferimento a quel post del blog per tutti i dettagli su questi consigli: - -* Implementare il limite di intervallo per evitare attacchi pesanti al processo di autenticazione. Un modo per effettuare ciò è quello di utilizzare [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) per rafforzare una policy per il limite di intervallo. In alternativa, è possibile utilizzare il middleware, ad esempio [express-limiter](https://www.npmjs.com/package/express-limiter), ma questo richiede di modificare in parte il codice. -* Utilizzare il middleware [csurf](https://www.npmjs.com/package/csurf) come protezione contro CSRF (cross-site request forgery). -* Filtrare sempre e verificare gli input utente come protezione contro attacchi XSS (cross-site scripting) e command injection. -* Creare una difesa contro attacchi SQL injection utilizzando query con parametri o istruzioni preparate. -* Utilizzare lo strumento [sqlmap](http://sqlmap.org/) open source per rilevare le vulnerabilità SQL injection nell'applicazione. -* Utilizzare gli strumenti [nmap](https://nmap.org/) e [sslyze](https://github.com/nabla-c0d3/sslyze) per verificare la configurazione delle crittografie SSL, delle chiavi e della rinegoziazione come anche la validità del certificato. -* Utilizzare [safe-regex](https://www.npmjs.com/package/safe-regex) per assicurarsi che le espressioni regolari non siano suscettibili ad attacchi [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). - -## Evitare altre vulnerabilità note - -Prestare attenzione alle avvertenze [Node Security Project](https://npmjs.com/advisories) che potrebbero influenzare Express o altri moduli utilizzati dall'applicazione. Solitamente, il Node Security Project è una risorsa eccellente per questioni di apprendimento e per gli strumenti sulla sicurezza di Node. - -Infine, le applicazioni Express, come anche altre applicazioni web, possono essere vulnerabili ad una vasta gamma di attacchi basati su web. Cercare di comprendere al meglio le [vulnerabilità web](https://www.owasp.org/index.php/Top_10_2013-Top_10) note e prendere precauzioni per evitarle. + cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) +``` + +## Prevent brute-force attacks against authorization + +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +1. The number of consecutive failed attempts by the same user name and IP address. +2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) + +## Ensure your dependencies are secure + +Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. + +Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. + +```bash +$ 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: + +```bash +$ npm install -g snyk +$ cd your-app +``` + +Use this command to test your application for vulnerabilities: + +```bash +$ snyk test +``` + +### Evitare altre vulnerabilità note + +Prestare attenzione alle avvertenze [Node Security Project](https://npmjs.com/advisories) che potrebbero influenzare Express o altri moduli utilizzati dall'applicazione. Solitamente, il Node Security Project è una risorsa eccellente per questioni di apprendimento e per gli strumenti sulla sicurezza di Node. + +Infine, le applicazioni Express, come anche altre applicazioni web, possono essere vulnerabili ad una vasta gamma di attacchi basati su web. Cercare di comprendere al meglio le [vulnerabilità web](https://www.owasp.org/www-project-top-ten/) note e prendere precauzioni per evitarle. + +## Additional considerations + +Ecco alcuni consigli sull'eccellente [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Fare riferimento a quel post del blog per tutti i dettagli su questi consigli: + +- Filtrare sempre e verificare gli input utente come protezione contro attacchi XSS (cross-site scripting) e command injection. +- Creare una difesa contro attacchi SQL injection utilizzando query con parametri o istruzioni preparate. +- Utilizzare lo strumento [sqlmap](http://sqlmap.org/) open source per rilevare le vulnerabilità SQL injection nell'applicazione. +- Utilizzare gli strumenti [nmap](https://nmap.org/) e [sslyze](https://github.com/nabla-c0d3/sslyze) per verificare la configurazione delle crittografie SSL, delle chiavi e della rinegoziazione come anche la validità del certificato. +- Utilizzare [safe-regex](https://www.npmjs.com/package/safe-regex) per assicurarsi che le espressioni regolari non siano suscettibili ad attacchi [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). + +[helmet]: https://helmetjs.github.io/ \ No newline at end of file diff --git a/it/advanced/developing-template-engines.md b/it/advanced/developing-template-engines.md old mode 100755 new mode 100644 index f41b090f94..6430a99ad4 --- a/it/advanced/developing-template-engines.md +++ b/it/advanced/developing-template-engines.md @@ -1,8 +1,9 @@ --- layout: page title: Sviluppo dei motori di template per Express +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: it +redirect_from: " " --- # Sviluppo dei motori di template per Express @@ -11,38 +12,35 @@ Utilizzare il metodo `app.engine(ext, callback)` per creare il proprio motore di Il seguente codice è un esempio di implementazione di un motore di template molto semplice per il rendering del file `.ntl`. -
    -
    -var fs = require('fs'); // this engine requires the fs module
    -app.engine('ntl', function (filePath, options, callback) { // define the template engine
    -  fs.readFile(filePath, function (err, content) {
    -    if (err) return callback(new Error(err));
    +```js
    +const fs = require('fs') // this engine requires the fs module
    +app.engine('ntl', (filePath, options, callback) => { // define the template engine
    +  fs.readFile(filePath, (err, content) => {
    +    if (err) return callback(err)
         // this is an extremely simple template engine
    -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
    -    .replace('#message#', '

    '+ options.message +'

    '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
    -
    + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

    ${options.message}

    `) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine +``` L'applicazione sarà ora in grado di effettuare il rendering dei file `.ntl`. Creare un file denominato `index.ntl` nella directory `views` con il seguente contenuto. -
    -
    +```pug
     #title#
     #message#
    -
    -
    +``` + Successivamente, creare il seguente percorso nell'applicazione. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    -Quando si effettua una richiesta per la home page, `index.ntl` verrà visualizzato come HTML. +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` + +Quando si effettua una richiesta per la home page, `index.ntl` verrà visualizzato come HTML. \ No newline at end of file diff --git a/it/advanced/healthcheck-graceful-shutdown.md b/it/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..60ee5f59d9 --- /dev/null +++ b/it/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/it/advanced/pm.md b/it/advanced/pm.md deleted file mode 100755 index 07f6e3f6ac..0000000000 --- a/it/advanced/pm.md +++ /dev/null @@ -1,283 +0,0 @@ ---- -layout: page -title: Process manager per le applicazioni Express -menu: advanced -lang: it ---- - -# Process manager per le applicazioni Express - -Quando si eseguono le applicazioni Express per la produzione, è utile utilizzare un *process manager* per effettuare le seguenti attività: - -- Riavviare l'applicazione automaticamente se termina in modo anomalo. -- Ottenere insight relativi alle prestazioni di runtime e al consumo delle risorse. -- Modificare le impostazioni in modo dinamico per migliorare le prestazioni. -- Controllare il processo di clustering. - -Un process manager è simile a un server delle applicazioni: è un "contenitore" per le applicazioni che facilita lo sviluppo, fornisce un'elevata disponibilità e consente di gestire l'applicazione al momento del runtime. - -I process manager più noti per Express e altre applicazioni Node.js sono i seguenti: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -L'utilizzo di uno di questi tre strumenti può essere molto utile, tuttavia, StrongLoop Process Manager è l'unico strumento che fornisce una soluzione di distribuzione e runtime completa che interessa il ciclo di vita dell'intera applicazione Node.js, con la possibilità di usufruire di strumenti in ciascuna fase prima e dopo la produzione, in un'interfaccia unificata. - -Segue una breve descrizione relativa ad ogni strumento. -Per un confronto dettagliato, consultare [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) è un process manager di produzione per le applicazioni Node.js. StrongLoop PM dispone di servizi di bilanciamento del carico integrati, del servizio di monitoraggio, dell'implementazione multi-host e di una console grafica. -È possibile utilizzare StrongLoop PM per svolgere le seguenti attività: - -- Creare, creare pacchetti e implementare l'applicazione Node.js su un sistema locale o remoto. -- Visualizzare i profili CPU e accumulare le istantanee per ottimizzare le prestazioni e diagnosticare le perdite di memoria. -- Fare in modo che i processi e i cluster siano per sempre attivi. -- Visualizzare le metriche delle prestazioni sull'applicazione. -- Gestire con facilità le implementazioni multi-host con l'integrazione Nginx. -- Unificare più StrongLoop PM a un runtime di microservizi distribuito gestito dall'Arc. - -È possibile gestire StrongLoop PM utilizzando uno strumento di interfaccia della riga comandi avanzato denominato `slc` oppure uno strumento grafico denominato Arc. Arc è open source, con un supporto professionale fornito da StrongLoop. - -Per ulteriori informazioni, consultare [http://strong-pm.io/](http://strong-pm.io/). - -Documentazione completa: - -- [Operating Node apps (documentazione StrongLoop)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Installazione -
    -
    -$ [sudo] npm install -g strongloop
    -
    -
    - -### Utilizzo di base -
    -
    -$ cd my-app
    -$ slc start
    -
    -
    - -Visualizzare lo stato del Process Manager e tutte le applicazioni implementate: - -
    -
    -$ slc ctl
    -Service ID: 1
    -Service Name: my-app
    -Environment variables:
    -  No environment variables defined
    -Instances:
    -    Version  Agent version  Cluster size
    -     4.1.13      1.5.14           4
    -Processes:
    -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
    -    1.1.57692  57692   0
    -    1.1.57693  57693   1     0.0.0.0:3001
    -    1.1.57694  57694   2     0.0.0.0:3001
    -    1.1.57695  57695   3     0.0.0.0:3001
    -    1.1.57696  57696   4     0.0.0.0:3001
    -
    -
    - -Elencare tutte le applicazioni (servizi) sotto la gestione: - -
    -
    -$ slc ctl ls
    -Id          Name         Scale
    - 1          my-app       1
    -
    -
    - -Arrestare un'applicazione: - -
    -
    -$ slc ctl stop my-app
    -
    -
    - -Riavviare un'applicazione: - -
    -
    -$ slc ctl restart my-app
    -
    -
    - -È inoltre possibile effettuare un "avvio a caldo," il quale fornisce ai processi di lavoro un determinato periodo di tempo per chiudere le connessioni e successivamente riavviare l'applicazione corrente: - -
    -
    -$ slc ctl soft-restart my-app
    -
    -
    - -Per rimuovere un'applicazione dalla gestione: - -
    -
    -$ slc ctl remove my-app
    -
    -
    - -## PM2 - -PM2 è un process manager di produzione per le applicazioni Node.js, che dispone di un servizio di bilanciamento del carico integrato. PM2 è utile per consentire alle applicazioni di essere sempre attive e consente di ricaricarle senza interruzione, inoltre faciliterà le attività di gestione del sistema comuni. PM2 inoltre consente di gestire la registrazione dell'applicazione, il monitoraggio e il clustering. - -Per ulteriori informazioni, consultare [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Installazione - -
    -
    -$ [sudo] npm install pm2 -g
    -
    -
    - -### Utilizzo di base - -Quando si avvia un'applicazione utilizzando il comando `pm2`, è necessario specificare il percorso dell'applicazione. Tuttavia, quando si arresta, riavvia o si cancella un'applicazione, è possibile specificare solo il nome o l'ID dell'applicazione. - -
    -
    -$ pm2 start npm --name my-app -- start
    -[PM2] restartProcessId process id 0
    -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
    -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
    -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
    -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
    -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
    - Use the `pm2 show ` command to get more details about an app.
    -
    -
    - -Quando si avvia un'applicazione utilizzando il comando `pm2`, l'applicazione viene immediatamente inviata all'applicazione di background. È possibile controllare l'applicazione di background dalla riga comandi utilizzando diversi comandi `pm2`. - -Dopo che un'applicazione viene avviata tramite il comando `pm2`, viene registrata nell'elenco di processi PM2 con un ID. È possibile quindi gestire le applicazioni con lo stesso nome da directory differenti sul sistema, utilizzando i relativi ID. - -Notare che se più di un'applicazione è in esecuzione con lo stesso nome, i comandi `pm2` saranno relativi a tutte quelle applicazioni. Pertanto, si consiglia di utilizzare gli ID invece dei nomi per gestire applicazioni individuali. - -Elencare tutti i processi in esecuzione: - -
    -
    -$ pm2 list
    -
    -
    - -Arrestare un'applicazione: - -
    -
    -$ pm2 stop 0
    -
    -
    - -Riavviare un'applicazione: - -
    -
    -$ pm2 restart 0
    -
    -
    - -Per visualizzare informazioni dettagliate su un'applicazione: - -
    -
    -$ pm2 show 0
    -
    -
    - -Per rimuovere un'applicazione dal registro di PM2: - -
    -
    -$ pm2 delete 0
    -
    -
    - - -## Forever - -Forever è uno strumento di interfaccia della riga comandi semplice che assicura che uno script fornito sia in esecuzione continua (forever). L'interfaccia semplice Forever è ideale per l'esecuzione di piccole distribuzioni degli script e applicazioni di Node.js. - -Per ulteriori informazioni, consultare [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Installazione - -
    -
    -$ [sudo] npm install forever -g
    -
    -
    - -### Utilizzo di base - -Per avviare uno script, utilizzare il comando `forever start` e specificare il percorso dello script: - -
    -
    -$ forever start script.js
    -
    -
    - -Questo comando consentirà l'esecuzione dello script in modalità daemon (in background). - -Per eseguire lo script in modo tale che sia visualizzato sul terminale, omettere `start`: - -
    -
    -$ forever script.js
    -
    -
    - -Si consiglia di registrare l'output dallo strumento Forever e lo script utilizzando le opzioni di registrazione `-l`, `-o` e `-e`, come mostrato nel seguente esempio: - -
    -
    -$ forever start -l forever.log -o out.log -e err.log script.js
    -
    -
    - -Per visualizzare l'elenco di script avviati da Forever: - -
    -
    -$ forever list
    -
    -
    - -Per arrestare uno script che era stato avviato da Forever, utilizzare il comando `forever stop` e specificare l'indice del processo (come elencato dal comando `forever list`). - -
    -
    -$ forever stop 1
    -
    -
    - -In alternativa, specificare il percorso del file: - -
    -
    -$ forever stop script.js
    -
    -
    - -Per arrestare tutti gli script avviati da Forever: - -
    -
    -$ forever stopall
    -
    -
    - -Forever dispone di molte più opzioni e fornisce inoltre un'API programmatica. diff --git a/it/advanced/security-updates.md b/it/advanced/security-updates.md old mode 100755 new mode 100644 index 4b054892d1..a46ba4c164 --- a/it/advanced/security-updates.md +++ b/it/advanced/security-updates.md @@ -1,44 +1,87 @@ --- layout: page title: Aggiornamenti sulla sicurezza Express +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: it +redirect_from: " " --- # Aggiornamenti sulla sicurezza
    -Le vulnerabilità di Node.js influenzano direttamente Express. Pertanto, [verificare sempre le vulnerabilità Node.js](http://blog.nodejs.org/vulnerability/) e assicurarsi di utilizzare l'ultima versione corretta di Node.js. +Le vulnerabilità di Node.js influenzano direttamente Express. Pertanto, [verificare sempre le vulnerabilità Node.js](https://nodejs.org +/en/blog/vulnerability/) e assicurarsi di utilizzare l'ultima versione corretta di Node.js.
    L'elenco seguente mostra le vulnerabilità di Express che sono state corrette nell'aggiornamento della versione specificato. +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} + ## 4.x - * 4.11.1 - * Risolta la vulnerabilità del rilevamento del percorso root in `express.static`, `res.sendfile` e `res.sendFile` - * 4.10.7 - * Risolta la vulnerabilità del reindirizzamento aperto in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 4.8.8 - * Risolte le vulnerabilità trasversali della directory 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 può portare alla perdita di `fd` in determinate situazioni che influenzano `express.static` e `res.sendfile`. Le richieste sospette potrebbero causare una perdita di `fd` ed eventualmente il verificarsi di errori `EMFILE` e risposte mancate del server. - * 4.8.0 - * Le matrici sparse che dispongono di indici estremamente elevati nella stringa di query potrebbero causare errori di memoria nel processo e una chiusura anomala del server. - * Gli oggetti di stringa query molto nidificati potrebbero causare un blocco del processo e una mancata risposta da parte del server. +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. + - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. +- 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +- 4.15.2 + - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - Risolta la vulnerabilità del rilevamento del percorso root in `express.static`, `res.sendfile` e `res.sendFile` +- 4.10.7 + - Risolta la vulnerabilità del reindirizzamento aperto in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 4.8.8 + - Risolte le vulnerabilità trasversali della directory 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 può portare alla perdita di `fd` in determinate situazioni che influenzano `express.static` e `res.sendfile`. Le richieste sospette potrebbero causare una perdita di `fd` ed eventualmente il verificarsi di errori `EMFILE` e risposte mancate del server. +- 4.8.0 + - Le matrici sparse che dispongono di indici estremamente elevati nella stringa di query potrebbero causare errori di memoria nel processo e una chiusura anomala del server. + - Gli oggetti di stringa query molto nidificati potrebbero causare un blocco del processo e una mancata risposta da parte del server. ## 3.x - * 3.19.1 - * Risolta la vulnerabilità del rilevamento del percorso root in `express.static`, `res.sendfile` e `res.sendFile` - * 3.19.0 - * Risolta la vulnerabilità del reindirizzamento aperto in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Risolte le vulnerabilità trasversali della directory in `express.static`. - * 3.16.6 - * Node.js 0.10 può portare alla perdita di `fd` in determinate situazioni che influenzano `express.static` e `res.sendfile`. Le richieste sospette potrebbero causare una perdita di `fd` ed eventualmente il verificarsi di errori `EMFILE` e risposte mancate del server. - * 3.16.0 - * Le matrici sparse che dispongono di indici estremamente elevati nella stringa di query potrebbero causare errori di memoria nel processo e una chiusura anomala del server. - * Gli oggetti di stringa query molto nidificati potrebbero causare un blocco del processo e una mancata risposta da parte del server. - * 3.3.0 - * La risposta 404 di un metodo non supportato sovrascrive un tentativo suscettibili in precedenza ad attacchi XSS (cross-site scripting). +
    + **Express 3.x NON È PIU' SUPPORTATO** + +I problemi noti e non noti relativi alla sicurezza presenti in 3.x non sono stati indirizzati dall'ultimo aggiornamento (1 agosto 2015). Si consiglia di utilizzare l'ultima versione di Express. + +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). + +
    + +- 3.19.1 + - Risolta la vulnerabilità del rilevamento del percorso root in `express.static`, `res.sendfile` e `res.sendFile` +- 3.19.0 + - Risolta la vulnerabilità del reindirizzamento aperto in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 3.16.10 + - Risolte le vulnerabilità trasversali della directory in `express.static`. +- 3.16.6 + - Node.js 0.10 può portare alla perdita di `fd` in determinate situazioni che influenzano `express.static` e `res.sendfile`. Le richieste sospette potrebbero causare una perdita di `fd` ed eventualmente il verificarsi di errori `EMFILE` e risposte mancate del server. +- 3.16.0 + - Le matrici sparse che dispongono di indici estremamente elevati nella stringa di query potrebbero causare errori di memoria nel processo e una chiusura anomala del server. + - Gli oggetti di stringa query molto nidificati potrebbero causare un blocco del processo e una mancata risposta da parte del server. +- 3.3.0 + - La risposta 404 di un metodo non supportato sovrascrive un tentativo suscettibili in precedenza ad attacchi XSS (cross-site scripting). \ No newline at end of file diff --git a/it/api.md b/it/api.md old mode 100755 new mode 100644 index 2e20facf78..bc6a90eb05 --- a/it/api.md +++ b/it/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - Riferimento API -lang: it +layout: api +version: 5x +title: Express 5.x - Riferimento API +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api +redirect_from: " " --- -
    - -

    API 4.x

    - - - {% include api/en/4x/express.md %} +
    +

    5.x API

    + {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
    diff --git a/it/changelog/index.md b/it/changelog/index.md new file mode 100644 index 0000000000..2456265b18 --- /dev/null +++ b/it/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/it/guide/behind-proxies.md b/it/guide/behind-proxies.md old mode 100755 new mode 100644 index 0e860b310e..87864eb5b0 --- a/it/guide/behind-proxies.md +++ b/it/guide/behind-proxies.md @@ -1,18 +1,21 @@ --- layout: page title: Express con i proxy +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: it +redirect_from: " " --- # Express con i proxy -Quando si esegue un'applicazione Express con un proxy, impostare (utilizzando [app.set()](/{{ page.lang }}/4x/api.html#app.set)) la variabile dell'applicazione `trust proxy` su uno dei valori elencati nella seguente tabella. +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
    -Anche se l'applicazione non presenterà errori nell'esecuzione se la variabile dell'applicazione `trust proxy` non è impostata, registrerà comunque in modo errato l'indirizzo IP del proxy come indirizzo IP del client a meno che non venga configurato `trust proxy`. +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
    +Quando si esegue un'applicazione Express con un proxy, impostare (utilizzando [app.set()](/{{ page.lang }}/4x/api.html#app.set)) la variabile dell'applicazione `trust proxy` su uno dei valori elencati nella seguente tabella. + @@ -22,51 +25,62 @@ Anche se l'applicazione non presenterà errori nell'esecuzione se la variabile d Se impostato su `true`, l'indirizzo IP del client viene considerato come la voce a sinistra dell'intestazione `X-Forwarded-*`. Se impostato su `false`, significa che l'applicazione abbia una connessione diretta a Internet e l'indirizzo IP del client sia arrivato da `req.connection.remoteAddress`. Questa è l'impostazione predefinita. + +
    +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
    - + - +
    TipoValore
    Indirizzi IPIP addresses -Un indirizzo IP, una subnet o un array di indirizzi IP e subnet a cui fornire attendibilità. Il seguente elenco mostra i nomi di subnet preconfigurate: +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` +- loopback - `127.0.0.1/8`, `::1/128` +- linklocal - `169.254.0.0/16`, `fe80::/10` +- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` È possibile impostare gli indirizzi IP in uno dei seguenti modi: -
    -app.set('trust proxy', 'loopback') // specify a single subnet
    +```js
    +app.set('trust proxy', 'loopback') // specify a single subnet
     app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
     app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
    -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
    -
    +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` + +Quando specificati, gli indirizzi IP o le subnet vengono esclusi dal processo di determinazione dell'indirizzo e l'indirizzo IP non attendibile più vicino al server delle applicazioni viene considerato come indirizzo IP del client. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. -Quando specificati, gli indirizzi IP o le subnet vengono esclusi dal processo di determinazione dell'indirizzo e l'indirizzo IP non attendibile più vicino al server delle applicazioni viene considerato come indirizzo IP del client.
    Numero -Considerare attendibile una parte del percorso `n`th dal server proxy principale come client. +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. + +
    +When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
    FunzioneFunction -Implementazione attendibilità personalizzata. Questa funzione deve essere utilizzata solo da esperti. -
    -app.set('trust proxy', function (ip) {
    -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
    -  else return false;
    -});
    -
    +Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
    -Se si imposta un valore non `false` `trust proxy` si verificano tre importanti cambiamenti: +Enabling `trust proxy` will have the following impact:
    • Il valore di [req.hostname](/{{ page.lang }}/api.html#req.hostname) viene rilevato dalla serie di valori nell'intestazione `X-Forwarded-Host`, la quale può essere impostata dal client o dal proxy. diff --git a/it/guide/database-integration.md b/it/guide/database-integration.md old mode 100755 new mode 100644 index f6dd52a6d8..942d1912b4 --- a/it/guide/database-integration.md +++ b/it/guide/database-integration.md @@ -1,242 +1,285 @@ --- layout: page title: Integrazione database Express +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: it +redirect_from: " " --- # Integrazione database L'aggiunta della funzionalità che consente di connettere i database alle applicazioni Express è solo un modo per caricare un driver Node.js appropriato per il database nell'applicazione. Questo documento spiega brevemente come aggiungere e utilizzare alcuni dei moduli Node.js più noti per i sistemi database nell'applicazione Express: -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongo) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgres) +- [Redis](#redis) +- +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
      -Questi driver di database sono tra quelli più disponibili. Per altre opzioni, +Questi driver di database sono tra quelli più disponibili. Per altre opzioni, effettuare una ricerca nel sito [npm](https://www.npmjs.com/).
      - - ## Cassandra **Modulo**: **Installazione** [cassandra-driver](https://github.com/datastax/nodejs-driver) +### -
      -
      +```bash
       $ npm install cassandra-driver
      -
      -
      +``` -**Esempio** +### Esempio -
      -
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      +```js
      +const cassandra = require('cassandra-driver')
      +const client = new cassandra.Client({ contactPoints: ['localhost'] })
      +
      +client.execute('select key from system.local', (err, result) => {
      +  if (err) throw err
      +  console.log(result.rows[0])
      +})
      +```
      +
      +## Couchbase
       
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      -
      +**Module**: [couchnode](https://github.com/couchbase/couchnode) - +### + +```bash +$ npm install couchbase +``` + +### Esempio + +```js +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') + +// add a document to a bucket +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) + +// get all documents with shoe size 13 +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) +``` ## CouchDB **Modulo**: **Installazione** [nano](https://github.com/dscape/nano) +### -
      -
      +```bash
       $ npm install nano
      -
      -
      +``` -**Esempio** +### Esempio -
      -
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      -
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      -  }
      -});
      +```js
      +const nano = require('nano')('http://localhost:5984')
      +nano.db.create('books')
      +const books = nano.db.use('books')
       
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      -
      +// Insert a book document in the books database +books.insert({ name: 'The Art of war' }, null, (err, body) => { + if (err) { + console.log(err) + } else { + console.log(body) + } +}) - +// Get a list of all books +books.list((err, body) => { + if (err) { + console.log(err) + } else { + console.log(body.rows) + } +}) +``` ## LevelDB **Modulo**: **Installazione** [levelup](https://github.com/rvagg/node-levelup) +### -
      -
      +```bash
       $ npm install level levelup leveldown
      -
      -
      - -**Esempio** +``` -
      -
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      +### Esempio
       
      -db.put('name', 'LevelUP', function (err) {
      +```js
      +const levelup = require('levelup')
      +const db = levelup('./mydb')
       
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      +db.put('name', 'LevelUP', (err) => {
      +  if (err) return console.log('Ooops!', err)
       
      -});
      -
      -
      + db.get('name', (err, value) => { + if (err) return console.log('Ooops!', err) - + console.log(`name=${value}`) + }) +}) +``` ## MySQL **Modulo**: **Installazione** [mysql](https://github.com/felixge/node-mysql/) +### -
      -
      +```bash
       $ npm install mysql
      -
      -
      +``` -**Esempio** +### Esempio -
      -
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      +```js
      +const mysql = require('mysql')
      +const connection = mysql.createConnection({
      +  host: 'localhost',
      +  user: 'dbuser',
      +  password: 's3kreee7',
      +  database: 'my_db'
      +})
       
      -connection.connect();
      +connection.connect()
       
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
      +  if (err) throw err
       
      -connection.end();
      -
      -
      + console.log('The solution is: ', rows[0].solution) +}) - +connection.end() +``` ## MongoDB **Modulo**: **Installazione** [mongodb](https://github.com/mongodb/node-mongodb-native) +### -
      -
      +```bash
       $ npm install mongodb
      -
      -
      +``` -**Esempio** +### Example (v2.\*) -
      -
      -var MongoClient = require('mongodb').MongoClient;
      +```js
      +const MongoClient = require('mongodb').MongoClient
       
      -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
      -  if (err) {
      -    throw err;
      -  }
      -  db.collection('mammals').find().toArray(function(err, result) {
      -    if (err) {
      -      throw err;
      -    }
      -    console.log(result);
      -  });
      -});
      -
      -
      +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { + if (err) throw err -Se si desidera un driver del modello oggetto per MongoDB, consultare [Mongoose](https://github.com/LearnBoost/mongoose). + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err - + console.log(result) + }) +}) +``` -## Neo4j +### Example (v3.\*) -**Modulo**: **Installazione** -[apoc](https://github.com/hacksparrow/apoc) +```js +const MongoClient = require('mongodb').MongoClient +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { + if (err) throw err -
      -
      -$ npm install apoc
      -
      -
      + const db = client.db('animals') -**Esempio** + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +Se si desidera un driver del modello oggetto per MongoDB, consultare [Mongoose](https://github.com/LearnBoost/mongoose). + +## Neo4j -
       
      -var apoc = require('apoc');
      -
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      -  }
      -);
      -
      -
      +var apoc = require('apoc');apoc.query('match (n) return n').exec().then( +function (response) { +console.log(response); +}, +function (fail) { +console.log(fail); +} +); - +### + +```bash +$ npm install neo4j-driver +``` + +### Esempio + +```js +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) + +const session = driver.session() + +session.readTransaction((tx) => { + return tx.run('MATCH (n) RETURN count(n) AS count') + .then((res) => { + console.log(res.records[0].get('count')) + }) + .catch((error) => { + console.log(error) + }) +}) +``` ## Oracle **Modulo**: [oracledb](https://github.com/oracle/node-oracledb) -### Installazione +### - NOTA: [Vedi i prerequisiti di installazione](https://github.com/oracle/node-oracledb#-installation). +NOTA: [Vedi i prerequisiti di installazione](https://github.com/oracle/node-oracledb#-installation). -```sh +```bash $ npm install oracledb ``` @@ -274,148 +317,181 @@ async function getEmployee (empId) { getEmployee(101) ``` - - ## PostgreSQL -**Modulo**: **Installazione** -[pg](https://github.com/brianc/node-postgres) - - -
      -
      -$ npm install pg
      -
      -
      - -**Esempio** +**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise) -
      -
      -var pg = require('pg');
      -var conString = "postgres://username:password@localhost/database";
      -
      -pg.connect(conString, function(err, client, done) {
      +### 
       
      -  if (err) {
      -    return console.error('error fetching client from pool', err);
      -  }
      -  client.query('SELECT $1::int AS number', ['1'], function(err, result) {
      -    done();
      -    if (err) {
      -      return console.error('error running query', err);
      -    }
      -    console.log(result.rows[0].number);
      -  });
      +```bash
      +$ npm install pg-promise
      +```
       
      -});
      -
      -
      +### Esempio - +```js +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') + +db.one('SELECT $1 AS value', 123) + .then((data) => { + console.log('DATA:', data.value) + }) + .catch((error) => { + console.log('ERROR:', error) + }) +``` ## Redis **Modulo**: **Installazione** [redis](https://github.com/mranney/node_redis) +### -
      -
      +```bash
       $ npm install redis
      -
      -
      +``` -**Esempio** +### Esempio -
      -
      -var client = require('redis').createClient();
      +```js
      +const redis = require('redis')
      +const client = redis.createClient()
      +
      +client.on('error', (err) => {
      +  console.log(`Error ${err}`)
      +})
      +
      +client.set('string key', 'string val', redis.print)
      +client.hset('hash key', 'hashtest 1', 'some value', redis.print)
      +client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
      +
      +client.hkeys('hash key', (err, replies) => {
      +  console.log(`${replies.length} replies:`)
      +
      +  replies.forEach((reply, i) => {
      +    console.log(`    ${i}: ${reply}`)
      +  })
      +
      +  client.quit()
      +})
      +```
      +
      +## SQL Server
      +
      +**Module**: [tedious](https://github.com/tediousjs/tedious)
      +
      +### 
       
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      +```bash
      +$ npm install tedious
      +```
       
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      +### Esempio
       
      -client.hkeys('hash key', function (err, replies) {
      +```js
      +const Connection = require('tedious').Connection
      +const Request = require('tedious').Request
       
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      +const config = {
      +  server: 'localhost',
      +  authentication: {
      +    type: 'default',
      +    options: {
      +      userName: 'your_username', // update me
      +      password: 'your_password' // update me
      +    }
      +  }
      +}
       
      -  client.quit();
      +const connection = new Connection(config)
       
      -});
      -
      -
      +connection.on('connect', (err) => { + if (err) { + console.log(err) + } else { + executeStatement() + } +}) - +function executeStatement () { + request = new Request("select 123, 'hello world'", (err, rowCount) => { + if (err) { + console.log(err) + } else { + console.log(`${rowCount} rows`) + } + connection.close() + }) + + request.on('row', (columns) => { + columns.forEach((column) => { + if (column.value === null) { + console.log('NULL') + } else { + console.log(column.value) + } + }) + }) + + connection.execSql(request) +} +``` ## SQLite **Modulo**: **Installazione** [sqlite3](https://github.com/mapbox/node-sqlite3) +### -
      -
      +```bash
       $ npm install sqlite3
      -
      -
      - -**Esempio** +``` -
      -
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      +### Esempio
       
      -db.serialize(function() {
      +```js
      +const sqlite3 = require('sqlite3').verbose()
      +const db = new sqlite3.Database(':memory:')
       
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      +db.serialize(() => {
      +  db.run('CREATE TABLE lorem (info TEXT)')
      +  const stmt = db.prepare('INSERT INTO lorem VALUES (?)')
       
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      +  for (let i = 0; i < 10; i++) {
      +    stmt.run(`Ipsum ${i}`)
         }
       
      -  stmt.finalize();
      +  stmt.finalize()
       
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      +  db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
      +    console.log(`${row.id}: ${row.info}`)
      +  })
      +})
       
      -db.close();
      -
      -
      - - +db.close() +``` ## ElasticSearch **Modulo**: **Installazione** [elasticsearch](https://github.com/elastic/elasticsearch-js) +### -
      -
      +```bash
       $ npm install elasticsearch
      -
      -
      +``` -**Esempio** +### Esempio -
      -
      -var elasticsearch = require('elasticsearch');
      -var client = elasticsearch.Client({
      +```js
      +const elasticsearch = require('elasticsearch')
      +const client = elasticsearch.Client({
         host: 'localhost:9200'
      -});
      +})
       
       client.search({
         index: 'books',
      @@ -428,10 +504,9 @@ client.search({
             }
           }
         }
      -}).then(function(response) {
      -  var hits = response.hits.hits;
      -}, function(error) {
      -  console.trace(error.message);
      -});
      -
      -
      +}).then((response) => { + const hits = response.hits.hits +}, (error) => { + console.trace(error.message) +}) +``` diff --git a/it/guide/debugging.md b/it/guide/debugging.md old mode 100755 new mode 100644 index e71ee1ff99..9e4be0bf88 --- a/it/guide/debugging.md +++ b/it/guide/debugging.md @@ -1,42 +1,29 @@ --- layout: page title: Debug di Express +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: it +redirect_from: " " --- # Debug di Express -Express utilizza il modulo [debug](https://www.npmjs.com/package/debug) -internamente per registrare le informazioni sulle corrispondenze route, le funzioni middleware in uso, la modalità dell'applicazione -e il flusso del ciclo richiesta/risposta. - -
      -`debug` corrisponde a una versione estesa di `console.log`, ma diversamente da `console.log`, non è necessario -creare commenti per i log `debug` nel codice di produzione. Il processo di registrazione è disattivato per impostazione predefinita e può essere attivato utilizzando la variabile di ambiente `DEBUG`. -
      - Per visualizzare tutti i log interni utilizzati in Express, impostare la variabile di ambiente `DEBUG` su `express:*` quando si avvia l'applicazione. -
      -
      +```bash
       $ DEBUG=express:* node index.js
      -
      -
      +``` Su Windows, utilizzare il comando corrispondente. -
      -
      -> set DEBUG=express:* & node index.js
      -
      -
      +```bash +> $env:DEBUG = "express:*"; node index.js +``` L'esecuzione di questo comando sull'applicazione predefinita generata da [Programma di creazione express](/{{ page.lang }}/starter/generator.html) consentirà di stampare il seguente output: -
      -
      +```bash
       $ DEBUG=express:* node ./bin/www
         express:router:route new / +0ms
         express:router:layer new / +1ms
      @@ -72,19 +59,17 @@ $ DEBUG=express:* node ./bin/www
         express:router:layer new / +1ms
         express:router use /users router +0ms
         express:router:layer new /users +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -
      -
      +``` Quando successivamente viene effettuata una richiesta all'applicazione, verranno visualizzati i log specificati nel codice Express: -
      -
      +```bash
         express:router dispatching GET / +4h
         express:router query  : / +2ms
         express:router expressInit  : / +0ms
      @@ -100,8 +85,7 @@ Quando successivamente viene effettuata una richiesta all'applicazione, verranno
         express:view lookup "index.pug" +338ms
         express:view stat "/projects/example/views/index.pug" +0ms
         express:view render "/projects/example/views/index.pug" +1ms
      -
      -
      +``` Per visualizzare i log solo dall'implementazione router impostare il valore `DEBUG` su `express:router`. In modo simile, per visualizzare i log solo dall'implementazione dell'applicazione impostare il valore `DEBUG` su `express:application` e così via. @@ -111,18 +95,36 @@ Un'applicazione generata dal comando `express` utilizza inoltre il modulo `debug Ad esempio, se l'applicazione è stata generata con `$ express sample-app`, è possibile abilitare le istruzioni di debug con il seguente comando: -
      -
      +```bash
       $ DEBUG=sample-app:* node ./bin/www
      -
      -
      +``` È possibile specificare più di uno spazio dei nomi di debug assegnando un elenco di nomi separati da virgola: -
      -
      +```bash
       $ DEBUG=http,mail,express:* node index.js
      -
      -
      +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -Per ulteriori informazioni su `debug`, consultare [debug](https://www.npmjs.com/package/debug). +{% include admonitions/note.html content=debug-text %} diff --git a/it/guide/error-handling.md b/it/guide/error-handling.md old mode 100755 new mode 100644 index 198c65cb3c..84dfe10f72 --- a/it/guide/error-handling.md +++ b/it/guide/error-handling.md @@ -1,124 +1,145 @@ --- layout: page title: Gestione degli errori di Express +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: it +redirect_from: " " --- # Gestione degli errori -Definire le funzioni middleware di gestione degli errori nello stesso modo in cui si definiscono altre funzioni middleware, -ad eccezione delle funzioni di gestione degli errori che hanno quattro argomenti invece di tre: -`(err, req, res, next)`. Ad esempio: +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      +## Catching Errors -Si definisce il middleware di gestione degli errori per ultimo, successivamente `app.use()` e altre chiamate route; ad esempio: +It's important to ensure that Express catches all errors that occur while +running route handlers and middleware. -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +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. Ad esempio:
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      -  // logic
      -});
      -
      -
      +```js +app.get('/', (req, res) => { + throw new Error('BROKEN') // Express will catch this on its own. +}) +``` -Le risposte dall'interno delle funzione middleware possono essere in qualsiasi formato desiderato, ad esempio una pagina di errore HTML, un messaggio semplice o una stringa JSON. +Definire le funzioni middleware di gestione degli errori nello stesso modo in cui si definiscono altre funzioni middleware, +ad eccezione delle funzioni di gestione degli errori che hanno quattro argomenti invece di tre: +`(err, req, res, next)`. Ad esempio: -Per motivi organizzativi (e framework di livello più alto), è possibile definire -diverse funzioni middleware di gestione degli errori, come solitamente si fa con -le funzioni middleware normali. Ad esempio, se si desidera definire un programma di gestione errori per le richieste -effettuate utilizzando `XHR` e quelle senza, è necessario utilizzare i seguenti comandi: +```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) + } + }) +}) +``` -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +Se si dispone di un gestore route con più funzioni di callback, è possibile utilizzare il parametro `route` per passare al successivo gestore route.
      +Ad esempio:
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      -
      +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` -In questo esempio, il `logErrors` generico potrebbe scrivere le richieste e le informazioni sull'errore -su `stderr`, ad esempio: +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. -
      -
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      -
      +Se si trasmette qualsiasi cosa alla funzione `next()` (ad eccezione della stringa `'route'`), Express considera la richiesta corrente come se contenesse errori e ignorerà qualsiasi altra funzione middleware e routing di non gestione degli errori restante. -Inoltre, in questo esempio, `clientErrorHandler` viene definito come segue; in questo caso, l'errore viene chiaramente tramandato al successivo: +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: -
      -
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      -  } else {
      -    next(err);
      +```js
      +app.get('/', [
      +  function (req, res, next) {
      +    fs.writeFile('/inaccessible-path', 'data', next)
      +  },
      +  function (req, res) {
      +    res.send('OK')
         }
      -}
      -
      -
      +]) +``` -La funzione "catch-all" `errorHandler` potrebbe essere implementata come segue: +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. -
      -
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      +You must catch errors that occur in asynchronous code invoked by route handlers or +middleware and pass them to Express for processing. Ad esempio: -Se si trasmette qualsiasi cosa alla funzione `next()` (ad eccezione della stringa `'route'`), Express considera la richiesta corrente come se contenesse errori e ignorerà qualsiasi altra funzione middleware e routing di non gestione degli errori restante. Se si desidera gestire quell'errore in qualche modo, sarà necessario creare una route di gestione degli errori come descritto nella sezione successiva. +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN') + } catch (err) { + next(err) + } + }, 100) +}) +``` -Se si dispone di un gestore route con più funzioni di callback, è possibile utilizzare il parametro `route` per passare al successivo gestore route. Ad esempio: +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. -
      -
      -app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      +Use promises to avoid the overhead of the `try...catch` block or when using functions
      +that return promises.  Ad esempio:
       
      -      // continue handling this request
      -      next('route');
      -    }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      -
      +```js +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { + throw new Error('BROKEN') + }).catch(next) // Errors will be passed to Express. +}) +``` -In questo esempio, il gestore `getPaidContent` verrà ignorato ma qualsiasi altro gestore rimanente in `app` per `/a_route_behind_paywall` verrà eseguito senza interruzione. +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. -
      -Le chiamate a `next()` e `next(err)` indicano che il gestore corrente è completo e in che stato si trova. `next(err)` ignorerà tutti gli handler rimanenti nella catena ad eccezione degli handler configurati per gestire gli errori come descritto sopra. -
      +You could also use a chain of handlers to rely on synchronous error +catching, by reducing the asynchronous code to something trivial. Ad esempio: + +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +The above example has a couple of trivial statements from 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 +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. + +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. ## Il gestore errori predefinito @@ -132,6 +153,16 @@ stack. La traccia stack non viene inclusa nell'ambiente di produzione. Impostare la variabile di ambiente `NODE_ENV` su `production`, per eseguire l'applicazione nella modalità di produzione.
    +When an error is written, the following information is added to the +response: + +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. + Se si chiama `next()` con un errore dopo che si è iniziato a scrivere la risposta (ad esempio, se si riscontra un errore mentre si esegue lo streaming della risposta al client) il gestore degli errori predefinito di Express chiude la connessione @@ -141,14 +172,125 @@ Pertanto, quando si aggiunge un gestore degli errori personalizzato, si consigli di gestione degli errori predefinito in Express, quando le intestazioni sono state già inviate al client: -
    -
    -function errorHandler(err, req, res, next) {
    +```js
    +function errorHandler (err, req, res, next) {
       if (res.headersSent) {
    -    return next(err);
    +    return next(err)
    +  }
    +  res.status(500)
    +  res.render('error', { error: err })
    +}
    +```
    +
    +Note that the default error handler can get triggered if you call `next()` with an error
    +in your code more than once, even if custom error handling middleware is in place.
    +
    +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html).
    +
    +## Writing error handlers
    +
    +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)`. Ad esempio:
    +
    +```js
    +app.use((err, req, res, next) => {
    +  console.error(err.stack)
    +  res.status(500).send('Something broke!')
    +})
    +```
    +
    +Si definisce il middleware di gestione degli errori per ultimo, successivamente `app.use()` e altre chiamate route; ad esempio:
    +
    +```js
    +const bodyParser = require('body-parser')
    +const methodOverride = require('method-override')
    +
    +app.use(bodyParser.urlencoded({
    +  extended: true
    +}))
    +app.use(bodyParser.json())
    +app.use(methodOverride())
    +app.use((err, req, res, next) => {
    +  // logic
    +})
    +```
    +
    +Le risposte dall'interno delle funzione middleware possono essere in qualsiasi formato desiderato, ad esempio una pagina di errore HTML, un messaggio semplice o una stringa JSON.
    +
    +Per motivi organizzativi (e framework di livello più alto), è possibile definire
    +diverse funzioni middleware di gestione degli errori, come solitamente si fa con
    +le funzioni middleware normali. Ad esempio, se si desidera definire un programma di gestione errori per le richieste
    +effettuate utilizzando `XHR` e quelle senza, è necessario utilizzare i seguenti comandi:
    +
    +```js
    +const bodyParser = require('body-parser')
    +const methodOverride = require('method-override')
    +
    +app.use(bodyParser.urlencoded({
    +  extended: true
    +}))
    +app.use(bodyParser.json())
    +app.use(methodOverride())
    +app.use(logErrors)
    +app.use(clientErrorHandler)
    +app.use(errorHandler)
    +```
    +
    +In questo esempio, il `logErrors` generico potrebbe scrivere le richieste e le informazioni sull'errore
    +su `stderr`, ad esempio:
    +
    +```js
    +function logErrors (err, req, res, next) {
    +  console.error(err.stack)
    +  next(err)
    +}
    +```
    +
    +Inoltre, in questo esempio, `clientErrorHandler` viene definito come segue; in questo caso, l'errore viene chiaramente tramandato al successivo:
    +
    +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.
    +
    +```js
    +function clientErrorHandler (err, req, res, next) {
    +  if (req.xhr) {
    +    res.status(500).send({ error: 'Something failed!' })
    +  } else {
    +    next(err)
       }
    -  res.status(500);
    -  res.render('error', { error: err });
     }
    -
    -
    +``` + +La funzione "catch-all" `errorHandler` potrebbe essere implementata come segue: + +```js +function errorHandler (err, req, res, next) { + res.status(500) + res.render('error', { error: err }) +} +``` + +If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. Ad esempio: + +```js +app.get('/a_route_behind_paywall', + (req, res, next) => { + if (!req.user.hasPaid) { + // continue handling this request + next('route') + } else { + next() + } + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` + +In questo esempio, il gestore `getPaidContent` verrà ignorato ma qualsiasi altro gestore rimanente in `app` per `/a_route_behind_paywall` verrà eseguito senza interruzione. + +
    +Le chiamate a `next()` e `next(err)` indicano che il gestore corrente è completo e in che stato si trova. `next(err)` ignorerà tutti gli handler rimanenti nella catena ad eccezione degli handler configurati per gestire gli errori come descritto sopra. +
    diff --git a/it/guide/migrating-4.md b/it/guide/migrating-4.md old mode 100755 new mode 100644 index b6307ff080..61967ece95 --- a/it/guide/migrating-4.md +++ b/it/guide/migrating-4.md @@ -1,8 +1,9 @@ --- layout: page title: Migrazione a Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: it +redirect_from: " " --- # Passaggio a Express 4 @@ -24,7 +25,7 @@ Argomenti di questo articolo: Sono state apportate diverse modifiche importanti alla versione Express 4:
      -
    • Modifiche al sistema middleware e al core di Express. Le dipendenze su Connect e il middleware integrato sono state rimosse, pertanto è necessario aggiungere il middleware manualmente. +
    • Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
    • Modifiche al sistema di routing.
    • Altre modifiche.
    • @@ -32,8 +33,8 @@ Sono state apportate diverse modifiche importanti alla versione Express 4: Consultare inoltre: -* [Nuove funzioni in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrazione da 3.x a 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [Nuove funzioni in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [Migrazione da 3.x a 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

      Modifiche al sistema middleware e al core di Express @@ -54,7 +55,7 @@ middleware richiesto per eseguire l'applicazione. Seguire semplicemente questi p La seguente tabella elenca il middleware Express 3 e le relative controparti in Express 4. - + @@ -86,7 +87,7 @@ La seguente tabella elenca il middleware Express 3 e le relative controparti in -
      Express 3Express 4
      Express 3Express 4
      express.bodyParser body-parser + multer
      serve-index
      express.static serve-static
      +

    Segue l'[elenco completo](https://github.com/senchalabs/connect#middleware) di middleware Express 4. @@ -99,14 +100,13 @@ GitHub. Nella versione 4 è possibile utilizzare un parametro di variabile per definire il percorso in cui vengono caricate le funzioni middleware, quindi leggere il valore del parametro dal programma di gestione route. Ad esempio: -
    -
    -app.use('/book/:id', function(req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -});
    -
    -
    +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` +

    Il sistema di routing

    @@ -119,8 +119,9 @@ Il modo in cui viene definita la route non è cambiato ma il sistema di routing funzioni utili per organizzare le route: {: .doclist } -* Un nuovo metodo, `app.route()`, per creare handler di route a catena per un percorso route. -* Un nuova classe, `express.Router`, per creare handler di route assemblabili in modo modulare. + +- Un nuovo metodo, `app.route()`, per creare handler di route a catena per un percorso route. +- Un nuova classe, `express.Router`, per creare handler di route assemblabili in modo modulare.

    Metodo app.route()

    @@ -130,20 +131,18 @@ sulle route, consultare la documentazione [`Router()`](/{{ page.lang }}/4x/api.h Segue un esempio di handler di route a catena definiti utilizzando la funzione `app.route()`. -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
    +  })
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .put((req, res) => {
    +    res.send('Update the book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    +```

    Classe express.Router

    @@ -157,38 +156,36 @@ si definiscono alcune route e si caricano su un percorso nell'applicazione princ Ad esempio, creare un file router denominato `birds.js` nella directory dell'applicazione, con i seguenti contenuti: -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +var express = require('express')
    +var router = express.Router()
     
     // middleware specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +})
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` Successivamente, caricare il modulo router nell'applicazione: -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` L'applicazione sarà ora in grado di gestire le richieste per i percorsi `/birds` e `/birds/about` e chiamerà il middleware `timeLog` @@ -201,7 +198,7 @@ Altre modifiche La seguente tabella elenca altre piccole ma importanti modifiche applicate a Express 4: - + @@ -311,7 +308,7 @@ La funzionalità ora è limitata alla sola impostazione del valore cookie di bas `res.cookie()` per aggiungere altre funzionalità. -
    Oggetto Descrizione
    +

    Esempio di migrazione dell'applicazione

    @@ -326,49 +323,46 @@ Applicazione con la versione 3 Prendere in considerazione l'applicazione Express v.3 con il seguente file `app.js`: -
    -
    -var express = require('express');
    -var routes = require('./routes');
    -var user = require('./routes/user');
    -var http = require('http');
    -var path = require('path');
    +```js
    +var express = require('express')
    +var routes = require('./routes')
    +var user = require('./routes/user')
    +var http = require('http')
    +var path = require('path')
     
    -var app = express();
    +var app = express()
     
     // all environments
    -app.set('port', process.env.PORT || 3000);
    -app.set('views', path.join(__dirname, 'views'));
    -app.set('view engine', 'pug');
    -app.use(express.favicon());
    -app.use(express.logger('dev'));
    -app.use(express.methodOverride());
    -app.use(express.session({ secret: 'your secret here' }));
    -app.use(express.bodyParser());
    -app.use(app.router);
    -app.use(express.static(path.join(__dirname, 'public')));
    +app.set('port', process.env.PORT || 3000)
    +app.set('views', path.join(__dirname, 'views'))
    +app.set('view engine', 'pug')
    +app.use(express.favicon())
    +app.use(express.logger('dev'))
    +app.use(express.methodOverride())
    +app.use(express.session({ secret: 'your secret here' }))
    +app.use(express.bodyParser())
    +app.use(app.router)
    +app.use(express.static(path.join(__dirname, 'public')))
     
     // development only
    -if ('development' == app.get('env')) {
    -  app.use(express.errorHandler());
    +if (app.get('env') === 'development') {
    +  app.use(express.errorHandler())
     }
     
    -app.get('/', routes.index);
    -app.get('/users', user.list);
    +app.get('/', routes.index)
    +app.get('/users', user.list)
     
    -http.createServer(app).listen(app.get('port'), function(){
    -  console.log('Express server listening on port ' + app.get('port'));
    -});
    -
    -
    +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

    package.json

    Il file `package.json` della versione 3 associata deve apparire come segue: -
    -
    +```json
     {
       "name": "application-name",
       "version": "0.0.1",
    @@ -381,8 +375,7 @@ apparire come segue:
         "pug": "*"
       }
     }
    -
    -
    +```

    Processo @@ -392,24 +385,22 @@ Iniziare il processo di migrazione installando il middleware richiesto per l'app Express 4 e aggiornando Express e Pug alla versione aggiornata con il seguente comando: -
    -
    +```bash
     $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
    -
    -
    +``` Apportare le seguenti modifiche a `app.js`: 1. Le funzioni middleware di Express integrate `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` e - `express.errorHandler` non sono più disponibili nell'oggetto - `express`. È necessario installare le funzioni alternative - manualmente e caricarle sull'applicazione. + `express.logger`, `express.methodOverride`, + `express.session`, `express.bodyParser` e + `express.errorHandler` non sono più disponibili nell'oggetto + `express`. È necessario installare le funzioni alternative + manualmente e caricarle sull'applicazione. 2. Non è più necessario caricare la funzione `app.router`. - Non è un oggetto applicazione Express 4 valido, pertanto rimuovere il codice - `app.use(app.router);`. + Non è un oggetto applicazione Express 4 valido, pertanto rimuovere il codice + `app.use(app.router);`. 3. Assicurarsi che le funzioni middleware siano state caricate nell'ordine corretto - caricare `errorHandler` dopo aver caricato le route dell'applicazione. @@ -419,8 +410,7 @@ Apportare le seguenti modifiche a `app.js`: L'esecuzione del comando `npm` aggiornerà `package.json` come segue: -
    -
    +```json
     {
       "name": "application-name",
       "version": "0.0.1",
    @@ -433,76 +423,77 @@ L'esecuzione del comando `npm` aggiornerà `package.json` come segue:
         "errorhandler": "^1.1.1",
         "express": "^4.8.0",
         "express-session": "^1.7.2",
    -    "pug": "^2.0.0-beta6",
    +    "pug": "^2.0.0",
         "method-override": "^2.1.2",
         "morgan": "^1.2.2",
         "multer": "^0.1.3",
         "serve-favicon": "^2.0.1"
       }
     }
    -
    -
    +```

    app.js

    Successivamente, rimuovere il codice non valido, caricare il middleware richiesto e apportare le modifiche necessarie. Il file `app.js` apparirà come segue: -
    -
    -var http = require('http');
    -var express = require('express');
    -var routes = require('./routes');
    -var user = require('./routes/user');
    -var path = require('path');
    +```js
    +var http = require('http')
    +var express = require('express')
    +var routes = require('./routes')
    +var user = require('./routes/user')
    +var path = require('path')
     
    -var favicon = require('serve-favicon');
    -var logger = require('morgan');
    -var methodOverride = require('method-override');
    -var session = require('express-session');
    -var bodyParser = require('body-parser');
    -var multer = require('multer');
    -var errorHandler = require('errorhandler');
    +var favicon = require('serve-favicon')
    +var logger = require('morgan')
    +var methodOverride = require('method-override')
    +var session = require('express-session')
    +var bodyParser = require('body-parser')
    +var multer = require('multer')
    +var errorHandler = require('errorhandler')
     
    -var app = express();
    +var app = express()
     
     // all environments
    -app.set('port', process.env.PORT || 3000);
    -app.set('views', path.join(__dirname, 'views'));
    -app.set('view engine', 'pug');
    -app.use(favicon(__dirname + '/public/favicon.ico'));
    -app.use(logger('dev'));
    -app.use(methodOverride());
    -app.use(session({ resave: true,
    -                  saveUninitialized: true,
    -                  secret: 'uwotm8' }));
    -app.use(bodyParser.json());
    -app.use(bodyParser.urlencoded({ extended: true }));
    -app.use(multer());
    -app.use(express.static(path.join(__dirname, 'public')));
    -
    -app.get('/', routes.index);
    -app.get('/users', user.list);
    +app.set('port', process.env.PORT || 3000)
    +app.set('views', path.join(__dirname, 'views'))
    +app.set('view engine', 'pug')
    +app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
    +app.use(logger('dev'))
    +app.use(methodOverride())
    +app.use(session({
    +  resave: true,
    +  saveUninitialized: true,
    +  secret: 'uwotm8'
    +}))
    +app.use(bodyParser.json())
    +app.use(bodyParser.urlencoded({ extended: true }))
    +app.use(multer())
    +app.use(express.static(path.join(__dirname, 'public')))
    +
    +app.get('/', routes.index)
    +app.get('/users', user.list)
     
     // error handling middleware should be loaded after the loading the routes
    -if ('development' == app.get('env')) {
    -  app.use(errorHandler());
    +if (app.get('env') === 'development') {
    +  app.use(errorHandler())
     }
     
    -var server = http.createServer(app);
    -server.listen(app.get('port'), function(){
    -  console.log('Express server listening on port ' + app.get('port'));
    -});
    -
    -
    +var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```
    A meno che non sia necessario gestire direttamente il modulo `http` (socket.io/SPDY/HTTPS), il relativo caricamento non è richiesto e l'applicazione può essere avviata semplicemente come segue: -
    -app.listen(app.get('port'), function(){
    -  console.log('Express server listening on port ' + app.get('port'));
    -});
    -
    + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +

    Eseguire l'applicazione

    @@ -510,42 +501,37 @@ A meno che non sia necessario gestire direttamente il modulo `http` (socket.io/S Il processo di migrazione è stato completato e ora l'applicazione è stata aggiornata a Express 4. Per confermare, avviare l'applicazione utilizzando il seguente comando: -
    -
    +```bash
     $ node .
    -
    -
    +``` Caricare [http://localhost:3000](http://localhost:3000) - e visualizzare la home page sottoposta a rendering da Express 4. +e visualizzare la home page sottoposta a rendering da Express 4.

    Aggiornamento al programma di creazione dell'applicazione Express 4

    Lo strumento della riga comandi per generare un'applicazione Express è sempre - `express` ma per effettuare l'aggiornamento alla nuova versione è necessario disinstallare - il programma di creazione dell'applicazione di Express 3 e successivamente installare il nuovo - `express-generator`. +`express` ma per effettuare l'aggiornamento alla nuova versione è necessario disinstallare +il programma di creazione dell'applicazione di Express 3 e successivamente installare il nuovo +`express-generator`.

    Installazione

    Se il programma di creazione dell'applicazione di Express 3 è già installato sul sistema, è necessario disinstallarlo: -
    -
    +```bash
     $ npm uninstall -g express
    -
    -
    +``` + A seconda di come sono configurati i privilegi del file e della directory, potrebbe essere necessario eseguire questo comando con `sudo`. Ora, installare il nuovo programma di creazione: -
    -
    +```bash
     $ npm install -g express-generator
    -
    -
    +``` A seconda di come sono configurati i privilegi del file e della directory, potrebbe essere necessario eseguire questo comando con `sudo`. @@ -558,19 +544,18 @@ di Express 4. L'utilizzo e le opzioni del comando sono rimaste quasi gli stessi, con le seguenti eccezioni: {: .doclist } -* È stata rimossa l'opzione `--sessions`. -* È stata rimossa l'opzione `--jshtml`. -* È stata aggiunta l'opzione `--hogan` per supportare [Hogan.js](http://twitter.github.io/hogan.js/). + +- È stata rimossa l'opzione `--sessions`. +- È stata rimossa l'opzione `--jshtml`. +- È stata aggiunta l'opzione `--hogan` per supportare [Hogan.js](http://twitter.github.io/hogan.js/).

    Esempio

    Eseguire il seguente comando per creare un'applicazione Express 4: -
    -
    +```bash
     $ express app4
    -
    -
    +``` Se si visualizzano i contenuti del file `app4/app.js`, si noterà che tutte le funzioni middleware (ad eccezione di `express.static`) richieste per l'applicazione, @@ -581,11 +566,9 @@ Si noterà inoltre che il file `app.js` è ora un modulo Node.js, diversamente d Dopo aver installato le dipendenze, avviare l'applicazione utilizzando il seguente comando: -
    -
    +```bash
     $ npm start
    -
    -
    +``` Se si visualizza lo script di avvio npm nel file `package.json`, si noterà che il comando effettivo che avvia l'applicazione è @@ -607,27 +590,23 @@ Per rimuovere la directory `www` e conservare le cose "come farebbe Express 3", cancellare la riga in cui viene riportata la dicitura `module.exports = app;` alla fine del file `app.js`, quindi incollare il seguente codice al proprio posto: -
    -
    -app.set('port', process.env.PORT || 3000);
    +```js
    +app.set('port', process.env.PORT || 3000)
     
    -var server = app.listen(app.get('port'), function() {
    -  debug('Express server listening on port ' + server.address().port);
    -});
    -
    -
    +var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` Assicurarsi di caricare il modulo `debug` all'inizio del file `app.js` utilizzando il seguente codice: -
    -
    -var debug = require('debug')('app4');
    -
    -
    +```js +var debug = require('debug')('app4') +``` Successivamente, modificare `"start": "node ./bin/www"` nel file `package.json` in `"start": "node app.js"`. È stata spostata la funzionalità di `./bin/www` di nuovo in -`app.js`. Questa modifica non è consigliata, ma questa prova consente di comprendere in che modo funziona +`app.js`. Questa modifica non è consigliata, ma questa prova consente di comprendere in che modo funziona il file `./bin/www` e perché il file `app.js` non si avvia più in modo autonomo. diff --git a/it/guide/migrating-5.md b/it/guide/migrating-5.md old mode 100755 new mode 100644 index b42a49a90f..00522c1c33 --- a/it/guide/migrating-5.md +++ b/it/guide/migrating-5.md @@ -1,32 +1,44 @@ --- layout: page title: Migrazione a Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: it +redirect_from: " " --- # Passaggio a Express 5

    Panoramica

    -Express 5.0 si trova ancora nella fase di release alfa, ma di seguito vengono mostrate le modifiche che verranno riportate nel release e come migrare l'applicazione Express 4 a Express 5. +Express 5 non è molto differente da Express 4: le modifiche all'API non sono così importanti come quelle che sono state effettuate nel passaggio dalla 3.0 alla 4.0. Anche se le API di base sono le stesse, ci sono comunque delle modifiche importanti; in altre parole, un programma Express 4 esistente potrebbe non funzionare se lo si aggiorna per utilizzare Express 5. -Express 5 non è molto differente da Express 4: le modifiche all'API non sono così importanti come quelle che sono state effettuate nel passaggio dalla 3.0 alla 4.0. Anche se le API di base sono le stesse, ci sono comunque delle modifiche importanti; in altre parole, un programma Express 4 esistente potrebbe non funzionare se lo si aggiorna per utilizzare Express 5. +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -Per installare l'ultima alfa e per vedere in anteprima Express 5, immettere il seguente comando nella directory root dell'applicazione: - -
    -
    -$ npm install express@5.0.0-alpha.2 --save
    -
    -
    +```sh +npm install "express@5" +``` È quindi possibile eseguire i test automatizzati per trovare errori e correggere i problemi in base agli aggiornamenti elencati di seguito. Dopo aver gestito gli errori del test, avviare l'applicazione per verificare gli errori. Si noterà subito se l'applicazione utilizza qualsiasi metodo o proprietà non supportati. -

    Modifiche in Express 5

    +## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: + +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). -Di seguito viene riportato l'elenco di modifiche (a partire dal release alfa) che influenzeranno gli utenti di Express. -Consultare [pull request](https://github.com/expressjs/express/pull/2237) per un elenco di funzioni pianificate. +

    Modifiche in Express 5

    **Proprietà e metodi rimossi** @@ -38,96 +50,497 @@ Consultare [pull request](https://github.com/expressjs/express/pull/2237) per un
  • req.param(name)
  • res.json(obj, status)
  • res.jsonp(obj, status)
  • +
  • res.redirect('back') and res.location('back')
  • +
  • res.redirect(url, status)
  • res.send(body, status)
  • res.send(status)
  • res.sendfile()
  • +
  • router.param(fn)
  • +
  • express.static.mime
  • +
  • express:router debug logs
  • -**Modificato** +**Miglioramenti** -**Miglioramenti** +**Modificato** -

    Proprietà e metodi rimossi

    +## Proprietà e metodi rimossi Se si utilizza uno dei seguenti metodi o proprietà nell'applicazione, quest'ultima si chiuderà in modo anomalo. Quindi, sarà necessario modificare l'applicazione dopo aver effettuato l'aggiornamento alla versione 5. -

    app.del()

    +

    app.del()

    Express 5 non supporta più la funzione `app.del()`. Se si utilizza questa funzione verrà generato un errore. Per registrare le route HTTP DELETE, utilizzare al contrario la funzione `app.delete()`. -Inizialmente era stato utilizzato il comando `del` al posto di `delete`, perché `delete` è una parola chiave riservata in JavaScript. Tuttavia, a partire da ECMAScript 6, `delete` e altre parole chiave riservate possono essere utilizzate liberamente come nomi di proprietà. È possibile leggere la documentazione in cui viene descritto come si è arrivati alla deprecazione della funzione `app.del` qui. +Inizialmente era stato utilizzato il comando `del` al posto di `delete`, perché `delete` è una parola chiave riservata in JavaScript. Tuttavia, a partire da ECMAScript 6, `delete` e altre parole chiave riservate possono essere utilizzate liberamente come nomi di proprietà. + +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` + +{% endcapture %} -

    app.param(fn)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) + +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

    app.param(fn)

    La firma `app.param(fn)` è stata utilizzata per modificare la funzionalità della funzione `app.param(name, fn)`. È stata considerata obsoleta a partire dalla v4.11.0 e non è più supportata in Express 5. -

    Nomi di metodi al plurale

    +

    Nomi di metodi al plurale

    + +I seguenti nomi di metodi sono stati messi al plurale. In Express 4, l'utilizzo di vecchi metodi ha dato origine ad avvisi di deprecazione. Express 5 non li supporta più in alcun modo: -I seguenti nomi di metodi sono stati messi al plurale. In Express 4, l'utilizzo di vecchi metodi ha dato origine ad avvisi di deprecazione. Express 5 non li supporta più in alcun modo: +`req.acceptsLanguage()` è stato sostituito con `req.acceptsLanguages()`. `req.acceptsCharset()` è stato sostituito con `req.acceptsCharsets()`. `req.acceptsEncoding()` è stato sostituito con `req.acceptsEncodings()`. -`req.acceptsLanguage()` è stato sostituito con `req.acceptsLanguages()`. +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} -

    Due punti (:) nel nome per app.param(name, fn)

    +{% include admonitions/note.html content=codemod-pluralized-methods %} + +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    Due punti (:) nel nome per app.param(name, fn)

    I due punti (:) nel nome della funzione `app.param(name, fn)` è una eredità di Express 3 e per il bene della compatibilità con le versioni precedenti, Express 4 supporta questa condizione ma comunque fornendo un messaggio di avviso di deprecazione. Express 5 lo ignorerà senza avvisi e utilizzerà il parametro nome senza inserire i due punti. Questa procedura non dovrebbe influenzare il codice se si segue correttamente la documentazione di Express 4 di [app.param](/{{ page.lang }}/4x/api.html#app.param), poiché non si parla dei due punti. -

    req.param(name)

    +

    req.param(name)

    Questo metodo poco chiaro e molto pericoloso che si utilizzava per richiamare i dati del modulo è stato rimosso. Ora sarà necessario ricercare il nome del parametro inviato nell'oggetto `req.params`, `req.body` o `req.query`. -

    res.json(obj, status)

    +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    Express 5 non supporta più la firma `res.json(obj, status)`. Al contrario, impostare lo stato e successivamente associarlo al metodo `res.json()` come segue: `res.status(status).json(obj)`. -

    res.jsonp(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    Express 5 non supporta più la firma `res.jsonp(obj, status)`. Al contrario, impostare lo stato e successivamente associarlo al metodo `res.jsonp()` come segue: `res.status(status).jsonp(obj)`. -

    res.send(body, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    Express 5 non supporta più la firma `res.send(obj, status)`. Al contrario, impostare lo stato e successivamente associarlo al metodo `res.send()` come segue: `res.status(status).send(obj)`. -

    res.send(status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    -Express 5 non supporta più la firma res.send(status), dove *`status`* è un numero. Al contrario, utilizzare la funzione `res.sendStatus(statusCode)`, la quale imposta il codice di stato dell'intestazione della risposta HTTP e invia la versione di testo del codice: "Non trovato", "Errore interno del server" e così via. +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    + +Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) + +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` + +

    res.send(status)

    + +Express 5 non supporta più la firma res.send(status), dove _`status`_ è un numero. Al contrario, utilizzare la funzione `res.sendStatus(statusCode)`, la quale imposta il codice di stato dell'intestazione della risposta HTTP e invia la versione di testo del codice: "Non trovato", "Errore interno del server" e così via. Se è necessario inviare un numero utilizzando la funzione `res.send()`, citare il numero per convertirlo in una stringa, in modo tale che Express non lo interpreti come un tentativo di utilizzo di una firma vecchia non supportata. -

    res.sendfile()

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) + +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

    res.sendfile()

    La funzione `res.sendfile()` è stata sostituita da una versione in cui ogni frase composta inizia con una lettera maiuscola che utilizza ad esempio `res.sendFile()` in Express 5. -

    Modificato

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. È stata considerata obsoleta a partire dalla v4.11.0 e non è più supportata in Express 5. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## Modificato + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. Ad esempio: -

    app.router

    +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +Ad esempio: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    L'oggetto `app.router`, che era stato rimosso in Express 4, è ritornato in Express 5. Nella nuova versione, questo oggetto è solo un riferimento al router Express di base, diversamente da Express 3, in cui un'applicazione aveva il compito esplicito di caricarlo. -

    req.host

    +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    In Express 4, la funzione `req.host` andava a rimuovere in modo non corretto il numero porta nel caso fosse stato presente. In Express 5 il numero porta viene conservato. -

    req.query

    +

    req.query

    + +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -In Express 4.7 e da Express 5 in avanti, l'opzione parser query può accettare `false` per disabilitare l'analisi della stringa query quando si desidera utilizzare la propria funzione per la logica di analisi della stringa query. +

    res.clearCookie

    -

    Miglioramenti

    +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. -

    res.render()

    +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## Miglioramenti + +

    res.render()

    Questo metodo ora potenzia i funzionamenti asincroni per tutti i motori di visualizzazione, evitando i bug causati dai motori di visualizzazione con un'implementazione sincrona e che violavano l'interfaccia consigliata. + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/it/guide/overriding-express-api.md b/it/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/it/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/it/guide/routing.md b/it/guide/routing.md old mode 100755 new mode 100644 index 362a17e477..04f96716d1 --- a/it/guide/routing.md +++ b/it/guide/routing.md @@ -1,28 +1,38 @@ --- layout: page title: Routing Express +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: it +redirect_from: " " --- # Routing -*Routing* fa riferimento alla definizione di endpoint dell'applicazione (URI) e alla loro modalità di risposta alle richieste del client. +_Routing_ fa riferimento alla definizione di endpoint dell'applicazione (URI) e alla loro modalità di risposta alle richieste del client. Per un'introduzione al concetto di routing, consultare la sezione [Routing di base](/{{ page.lang }}/starter/basic-routing.html). +You define routing using methods of the Express `app` object that correspond to HTTP methods; +for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). + +These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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 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 +to the next callback. + Il codice seguente è un esempio di una route veramente di base. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
     // respond with "hello world" when a GET request is made to the homepage
    -app.get('/', function(req, res) {
    -  res.send('hello world');
    -});
    -
    -
    +app.get('/', (req, res) => { + res.send('hello world') +}) +```

    Metodi di route

    @@ -30,151 +40,207 @@ Un metodo di route deriva da uno dei metodi HTTP ed è collegato ad un'istanza d Il codice seguente è un esempio di route definite per i metodi GET e POST nella root dell'app. -
    -
    +```js
     // GET method route
    -app.get('/', function (req, res) {
    -  res.send('GET request to the homepage');
    -});
    +app.get('/', (req, res) => {
    +  res.send('GET request to the homepage')
    +})
     
     // POST method route
    -app.post('/', function (req, res) {
    -  res.send('POST request to the homepage');
    -});
    -
    -
    +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` -Express supporta i seguenti metodi di routing che corrispondono a metodi HTTP: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search` e `connect`. - -
    -In metodi di route che si convertono in nomi di variabili JavaScript non validi, utilizzare la notazione tra parentesi. Ad esempio, -`app['m-search']('/', function ...` -
    +Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). Esiste un metodo di routing speciale, `app.all()`, che non deriva da alcun metodo HTTP. Questo metodo viene utilizzato per caricare funzioni middleware in un percorso per tutti i metodi di richiesta. -Nell'esempio seguente, l'handler verrà eseguito per richieste a "/secret" se si stanno utilizzando GET, POST, PUT, DELETE, o qualsiasi altro metodo di richiesta HTTP supportato nel [modulo http](https://nodejs.org/api/http.html#http_http_methods). - -
    -
    -app.all('/secret', function (req, res, next) {
    -  console.log('Accessing the secret section ...');
    -  next(); // pass control to the next handler
    -});
    -
    -
    +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +```

    Percorsi di route

    I percorsi di route, in combinazione con un metodo di richiesta, definiscono gli endpoint a cui possono essere rivolte richieste. I percorsi di route possono essere stringhe, modelli di stringa o espressioni regolari. -
    - Express utilizza [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) per la corrispondenza dei percorsi di route; consultare la documentazione relativa a path-to-regexp per tutte le possibilità di definizione di percorsi di route. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) è uno strumento utile per il test delle route Express di base, anche se non supporta la corrispondenza di modelli. -
    +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
    -Le stringhe di query non fanno parte del percorso di route. -
    +{% include admonitions/caution.html content=caution-character %} + +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} + +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) è uno strumento utile per il test delle route Express di base, anche se non supporta la corrispondenza di modelli. + +{% endcapture %} -Ecco alcuni esempi di percorsi di route basati su stringhe. +{% include admonitions/note.html content=note-path-to-regexp %} + +{% capture query-string-note %} + +Query strings are not part of the route path. + +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### Ecco alcuni esempi di percorsi di route basati su stringhe. Questo percorso di route corrisponderà a richieste nella route root, `/`. -
    -
    -app.get('/', function (req, res) {
    -  res.send('root');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` Questo percorso di route corrisponderà a richieste in `/about`. -
    -
    -app.get('/about', function (req, res) {
    -  res.send('about');
    -});
    -
    -
    +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` Questo percorso di route corrisponderà a richieste in `/random.text`. -
    -
    -app.get('/random.text', function (req, res) {
    -  res.send('random.text');
    -});
    -
    -
    +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` + +### Ecco alcuni esempi di percorsi di route basati su modelli di stringa. + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -Ecco alcuni esempi di percorsi di route basati su modelli di stringa. +{% include admonitions/caution.html content=caution-string-patterns %} Questo percorso di route corrisponderà a `acd` e `abcd`. -
    -
    -app.get('/ab?cd', function(req, res) {
    -  res.send('ab?cd');
    -});
    -
    -
    +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` Questo percorso di route corrisponderà a `abcd`, `abbcd`, `abbbcd` e così via. -
    -
    -app.get('/ab+cd', function(req, res) {
    -  res.send('ab+cd');
    -});
    -
    -
    +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` Questo percorso di route corrisponderà a `abcd`, `abxcd`, `abRABDOMcd`, `ab123cd` e così via. -
    -
    -app.get('/ab*cd', function(req, res) {
    -  res.send('ab*cd');
    -});
    -
    -
    +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` Questo percorso di route corrisponderà a `/abe` e `/abcde`. -
    -
    -app.get('/ab(cd)?e', function(req, res) {
    - res.send('ab(cd)?e');
    -});
    -
    -
    +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` -
    -I caratteri ?, +, * e () sono sottoinsiemi delle rispettive controparti di espressioni regolari. Trattino (-) e punto (.) vengono interpretati letteralmente da percorsi basati su stringhe. -
    - -Esempi di percorsi di route basati su espressioni regolari: +### Esempi di percorsi di route basati su espressioni regolari: Questo percorso di route corrisponderà a qualsiasi elemento con "a" nel nome route. -
    -
    -app.get(/a/, function(req, res) {
    -  res.send('/a/');
    -});
    -
    -
    +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` Questo percorso di route corrisponderà a `butterfly` e `dragonfly`, ma non a `butterflyman`, `dragonfly man` e così via. -
    -
    -app.get(/.*fly$/, function(req, res) {
    -  res.send('/.*fly$/');
    -});
    -
    -
    +```js +app.get(/.*fly$/, (req, res) => { + res.send('/.*fly$/') +}) +``` + +

    +Le stringhe di query non fanno parte del percorso di route. +

    + +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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
    +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +
    + +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. + +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` + +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` + +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): + +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` + +{% capture escape-advisory %} + +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %}

    Handler di route

    @@ -182,89 +248,81 @@ app.get(/.*fly$/, function(req, res) { Gli handler di route possono avere il formato di una funzione, di un array di funzioni o di combinazioni di entrambi, come illustrato nei seguenti esempi. -Una singola funzione di callback può gestire una route. Ad esempio: +Una singola funzione di callback può gestire una route. Ad esempio: -
    -
    -app.get('/example/a', function (req, res) {
    -  res.send('Hello from A!');
    -});
    -
    -
    +```js +app.get('/example/a', (req, res) => { + res.send('Hello from A!') +}) +``` Più funzioni di callback possono gestire una route (assicurarsi di specificare l'oggetto `next`). Ad esempio: -
    -
    -app.get('/example/b', function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from B!');
    -});
    -
    -
    - -Un array di funzioni callback possono gestire una route. Ad esempio: - -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +app.get('/example/b', (req, res, next) => {
    +  console.log('the response will be sent by the next function ...')
    +  next()
    +}, (req, res) => {
    +  res.send('Hello from B!')
    +})
    +```
    +
    +Un array di funzioni callback possono gestire una route. Ad esempio:
    +
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -var cb2 = function (req, res) {
    -  res.send('Hello from C!');
    +const cb2 = function (req, res) {
    +  res.send('Hello from C!')
     }
     
    -app.get('/example/c', [cb0, cb1, cb2]);
    -
    -
    +app.get('/example/c', [cb0, cb1, cb2]) +``` -Una combinazione di funzioni indipendenti e array di funzioni può gestire una route. Ad esempio: +Una combinazione di funzioni indipendenti e array di funzioni può gestire una route. Ad esempio: -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/d', [cb0, cb1], function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from D!');
    -});
    -
    -
    +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +```

    Metodi di risposta

    I metodi sull'oggetto risposta (`res`) nella seguente tabella possono inviare una risposta al client e terminare il ciclo richiesta-risposta. Se nessuno di questi metodi viene richiamato da un handler di route, la richiesta del client verrà lasciata in sospeso. -| Metodo | Descrizione -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Richiedere un file da scaricare. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Terminare il processo di risposta. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Inviare una risposta JSON. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Inviare una risposta JSON con supporto JSONP. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Reindirizzare una richiesta. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Eseguire il rendering di un template di vista. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Inviare una risposta di vari tipi. -| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | Inviare un file come un flusso di ottetti. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Impostare il codice di stato della risposta e inviare la relativa rappresentazione di stringa come corpo della risposta. +| Metodo | Descrizione | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Richiedere un file da scaricare. | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Terminare il processo di risposta. | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Inviare una risposta JSON. | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Inviare una risposta JSON con supporto JSONP. | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Reindirizzare una richiesta. | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Eseguire il rendering di un template di vista. | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Inviare una risposta di vari tipi. | +| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | Inviare un file come un flusso di ottetti. | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Impostare il codice di stato della risposta e inviare la relativa rappresentazione di stringa come corpo della risposta. |

    app.route()

    @@ -273,20 +331,18 @@ Poiché il percorso è specificato in una singola ubicazione, la creazione di ro Ecco un esempio di handler di route concatenati, definiti utilizzando `app.route()`. -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
    +  })
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .put((req, res) => {
    +    res.send('Update the book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    +```

    express.Router

    @@ -296,37 +352,43 @@ Nel seguente esempio si crea un router come modulo, si carica al suo interno una Creare un file router denominato `birds.js` nella directory app, con il seguente contenuto: -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const router = express.Router()
     
     // middleware that is specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +const timeLog = (req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +}
    +router.use(timeLog)
    +
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
    +
    +module.exports = router
    +```
     
    -module.exports = router;
    -
    -
    +Successivamente, caricare il modulo router nell'applicazione: -Quindi, caricare il modulo router nell'app: +```js +const birds = require('./birds') -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +// ... + +app.use('/birds', birds) +``` L'app ora sarà in grado di gestire richieste a `/birds` e `/birds/about`, oltre a richiamare la funzione middleware `timeLog`, specifica per la 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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/it/guide/using-middleware.md b/it/guide/using-middleware.md old mode 100755 new mode 100644 index 5067487296..2084fbf27b --- a/it/guide/using-middleware.md +++ b/it/guide/using-middleware.md @@ -1,205 +1,244 @@ --- layout: page title: Utilizzo del middleware Express +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: it +redirect_from: " " --- # Utilizzo del middleware Express è un framework Web di routing e middleware, con funzionalità sua propria minima: un'applicazione Express è essenzialmente a serie di chiamate a funzioni middleware. -Le funzioni *middleware* sono funzioni con accesso all'[oggetto richiesta](/{{ page.lang }}/4x/api.html#req) (`req`), all'[oggetto risposta](/{{ page.lang }}/4x/api.html#res) (`res`) e alla successiva funzione middleware nel ciclo richiesta-risposta dell'applicazione. La successiva funzione middleware viene comunemente denotata da una variabile denominata `next`. +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the next middleware function in the application's request-response cycle. La successiva funzione middleware viene comunemente denotata da una variabile denominata `next`. Le funzioni middleware possono eseguire le attività elencate di seguito: -* Eseguire qualsiasi codice. -* Apportare modifiche agli oggetti richiesta e risposta. -* Terminare il ciclo richiesta-risposta. -* Chiamare la successiva funzione middleware nello stack. +- Eseguire qualsiasi codice. +- Apportare modifiche agli oggetti richiesta e risposta. +- Terminare il ciclo richiesta-risposta. +- Chiamare la successiva funzione middleware nello stack. Se la funzione middleware corrente non termina il ciclo richiesta-risposta, deve richiamare `next()` per passare il controllo alla successiva funzione middleware. Altrimenti, la richiesta verrà lasciata in sospeso. Un'applicazione Express può utilizzare i seguenti tipi di middleware: - - [Middleware a livello dell'applicazione](#middleware.application) - - [Middleware a livello del router](#middleware.router) - - [Middleware di gestione degli errori](#middleware.error-handling) - - [Middleware integrato](#middleware.built-in) - - [Middleware di terzi](#middleware.third-party) +- [Middleware a livello dell'applicazione](#middleware.application) +- [Middleware a livello del router](#middleware.router) +- [Middleware di gestione degli errori](#middleware.error-handling) +- [Middleware integrato](#middleware.built-in) +- [Middleware di terzi](#middleware.third-party) È possibile caricare il middleware a livello dell'applicazione e del router con un percorso di montaggio facoltativo. È possibile inoltre caricare una serie di funzioni middleware contemporaneamente e, in questo modo, si crea un sotto-stack del sistema middleware in un punto di montaggio.

    Middleware a livello dell'applicazione

    -Associare il middleware al livello dell'applicazione ad un'istanza dell'[oggetto app](/{{ page.lang }}/4x/api.html#app) utilizzando le funzioni `app.use()` e `app.METHOD()`, dove `METHOD` corrisponde al metodo HTTP della richiesta che la funzione middleware gestisce (ad esempio GET, PUT o POST) in lettere minuscole. +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. Questo esempio presenta una funzione middleware senza percorso di montaggio. La funzione viene eseguita ogni volta che l'app riceve una richiesta. -
    -
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    -
    -
    +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` Questo esempio presenta una funzione middleware montata nel percorso `/user/:id`. La funzione viene eseguita per qualsiasi tipo di richiesta HTTP nel percorso `/user/:id`. -
    -
    -app.use('/user/:id', function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Questo esempio presenta una route e la relativa funzione handler (sistema middleware). La funzione gestisce richieste GET nel percorso `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  res.send('USER');
    -});
    -
    -
    +```js +app.get('/user/:id', (req, res, next) => { + 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 sotto-stack middleware che stampa informazioni sulla richiesta per qualsiasi tipo di richiesta HTTP nel percorso `/user/:id`. -
    -
    -app.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Gli handler di route consentono di definire molteplici route per un percorso. Nell'esempio sottostante sono definite due route per richieste GET nel percorso `/user/:id`. La seconda route non provocherà alcun problema, ma non verrà mai chiamata, poiché la prima route termina il ciclo di richiesta-risposta. Questo esempio presenta un sotto-stack middleware che gestisce richieste GET nel percorso `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -}, function (req, res, next) {
    -  res.send('User Info');
    -});
    +```js
    +app.get('/user/:id', (req, res, next) => {
    +  console.log('ID:', req.params.id)
    +  next()
    +}, (req, res, next) => {
    +  res.send('User Info')
    +})
     
     // handler for the /user/:id path, which prints the user ID
    -app.get('/user/:id', function (req, res, next) {
    -  res.end(req.params.id);
    -});
    -
    -
    +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) +}) +``` -Per ignorare le restanti funzioni middleware da uno stack di middleware del router, richiamare `next('route')` per passare il controllo alla route successiva. -**NOTA**: `next('route')` funzionerà solo in funzioni middleware che sono state caricate utilizzando le funzioni `app.METHOD()` o `router.METHOD()`. +`redirect` + +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} Questo esempio presenta un sotto-stack middleware che gestisce richieste GET nel percorso `/user/:id`. -
    -
    -app.get('/user/:id', function (req, res, next) {
    +```js
    +app.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next route
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass the control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    -  // render a regular page
    -  res.render('regular');
    -});
    +  else next()
    +}, (req, res, next) => {
    +  // send a regular response
    +  res.send('regular')
    +})
     
    -// handler for the /user/:id path, which renders a special page
    -app.get('/user/:id', function (req, res, next) {
    -  res.render('special');
    -});
    -
    -
    +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +Ecco un esempio di utilizzo della funzione middleware `express.static` con un oggetto opzioni elaborato: + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

    Middleware a livello del router

    Il middleware a livello del router funziona nello stesso modo di quello a livello dell'applicazione, fatta eccezione per il fatto di essere associato ad un'istanza di `express.Router()`. -
    -
    -var router = express.Router();
    -
    -
    +```js +const router = express.Router() +``` + Caricare il middleware a livello del router utilizzando le funzioni `router.use()` e `router.METHOD()`. Il seguente codice di esempio replica il sistema middleware mostrato sopra per il middleware a livello dell'applicazione, utilizzando il middleware a livello del router: -
    -
    -var app = express();
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const app = express()
    +const router = express.Router()
     
     // a middleware function with no mount path. This code is executed for every request to the router
    -router.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time:', Date.now())
    +  next()
    +})
     
     // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    -router.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    +router.use('/user/:id', (req, res, next) => {
    +  console.log('Request URL:', req.originalUrl)
    +  next()
    +}, (req, res, next) => {
    +  console.log('Request Type:', req.method)
    +  next()
    +})
     
     // a middleware sub-stack that handles GET requests to the /user/:id path
    -router.get('/user/:id', function (req, res, next) {
    +router.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next router
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    +  else next()
    +}, (req, res, next) => {
       // render a regular page
    -  res.render('regular');
    -});
    +  res.render('regular')
    +})
     
     // handler for the /user/:id path, which renders a special page
    -router.get('/user/:id', function (req, res, next) {
    -  console.log(req.params.id);
    -  res.render('special');
    -});
    +router.get('/user/:id', (req, res, next) => {
    +  console.log(req.params.id)
    +  res.render('special')
    +})
     
     // mount the router on the app
    -app.use('/', router);
    -
    -
    +app.use('/', router) +``` + +Per ulteriori dettagli sulla funzione `serve-static` e sulle relative opzioni, consultare: documentazione [serve-static](https://github.com/expressjs/serve-static). + +Questo esempio presenta un sotto-stack middleware che gestisce richieste GET nel percorso `/user/:id`. + +```js +const express = require('express') +const app = express() +const router = express.Router() + +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) + +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) + +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +```

    Middleware di gestione degli errori

    -Il middleware di gestione degli errori impiega sempre *quattro* argomenti. È necessario fornire quattro argomenti per identificarlo come funzione middleware di gestione degli errori. Anche se non è necessario utilizzare l'oggetto `next`, lo si deve specificare per mantenere la firma. Altrimenti, l'oggetto `next` verrà interpretato come middleware regolare e non sarà in grado di gestire gli errori. +Il middleware di gestione degli errori impiega sempre *quattro* argomenti. È necessario fornire quattro argomenti per identificarlo come funzione middleware di gestione degli errori. Anche se non è necessario utilizzare l'oggetto `next`, lo si deve specificare per mantenere la firma. Altrimenti, l'oggetto `next` verrà interpretato come middleware regolare e non sarà in grado di gestire gli errori.
    Definire le funzioni middleware di gestione degli errori nello stesso modo delle altre funzioni middleware, ma con quattro argomenti invece di tre, nello specifico con la firma `(err, req, res, next)`): -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Per dettagli sul middleware di gestione degli errori, consultare la sezione: [Gestione degli errori](/{{ page.lang }}/guide/error-handling.html). @@ -208,56 +247,11 @@ Per dettagli sul middleware di gestione degli errori, consultare la sezione: [Ge Dalla versione 4.x, Express non dipende più da [Connect](https://github.com/senchalabs/connect). Fatta eccezione per `express.static`, tutte le funzioni middleware che prima erano state incluse in Express, ora sono in moduli separati. Vedere [l'elenco delle funzioni middleware](https://github.com/senchalabs/connect#middleware). -

    express.static(root, [options])

    - -L'unica funzione middleware integrata in Express è `express.static`. Questa funzione è basata su [serve-static](https://github.com/expressjs/serve-static) ed è responsabile della fornitura degli asset statici di un'applicazione Express. - -L'argomento `root` specifica la directory root da cui fornire gli asset statici. - -L'oggetto facoltativo `options` può avere le seguenti proprietà: - -| Proprietà | Descrizione | Tipo | Valore predefinito | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | Opzione per la fornitura di dotfiles. Valori possibili sono "allow", "deny" e "ignore" | Stringa | "ignore" | -| `etag` | Abilitare o disabilitare la generazione di etag | Booleano | `true` | -| `extensions` | Imposta i fallback dell'estensione file. | Array | `[]` | -| `index` | Invia un file di indice di directory. Impostare su `false` per disabilitare l'indicizzazione della directory. | Misto | "index.html" | - `lastModified` | Impostare l'intestazione `Last-Modified`sulla data dell'ultima modifica del file nel sistema operativo. I valori possibili sono `true` o `false`. | Booleano | `true` | -| `maxAge` | Impostare la proprietà dell'intestazione Cache-Control, in millisecondi o una stringa in [formato ms](https://www.npmjs.org/package/ms) | Numero | 0 | -| `redirect` | Reindirizzare al carattere "/" finale, quando il nome percorso è una directory. | Booleano | `true` | -| `setHeaders` | Funzione per l'impostazione delle intestazioni HTTP perché siano adatte al file. | Funzione | | +L'unica funzione middleware integrata in Express è `express.static`. -Ecco un esempio di utilizzo della funzione middleware `express.static` con un oggetto opzioni elaborato: - -
    -
    -var options = {
    -  dotfiles: 'ignore',
    -  etag: false,
    -  extensions: ['htm', 'html'],
    -  index: false,
    -  maxAge: '1d',
    -  redirect: false,
    -  setHeaders: function (res, path, stat) {
    -    res.set('x-timestamp', Date.now());
    -  }
    -}
    -
    -app.use(express.static('public', options));
    -
    -
    - -È possibile avere più di una directory statica per app: - -
    -
    -app.use(express.static('public'));
    -app.use(express.static('uploads'));
    -app.use(express.static('files'));
    -
    -
    - -Per ulteriori dettagli sulla funzione `serve-static` e sulle relative opzioni, consultare: documentazione [serve-static](https://github.com/expressjs/serve-static). +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**

    Middleware di terzi

    @@ -267,21 +261,17 @@ Installare il modulo Node.js per la funzionalità richiesta, quindi, caricarlo n Il seguente esempio illustra l'installazione e il caricamento della funzione middleware di analisi dei cookie `cookie-parser`. -
    -
    +```bash
     $ npm install cookie-parser
    -
    -
    +``` -
    -
    -var express = require('express');
    -var app = express();
    -var cookieParser = require('cookie-parser');
    +```js
    +const express = require('express')
    +const app = express()
    +const cookieParser = require('cookie-parser')
     
     // load the cookie-parsing middleware
    -app.use(cookieParser());
    -
    -
    +app.use(cookieParser()) +``` Per un elenco parziale delle funzioni middleware di terzi comunemente utilizzate con Express, consultare la sezione: [Middleware di terzi](../resources/middleware.html). diff --git a/it/guide/using-template-engines.md b/it/guide/using-template-engines.md old mode 100755 new mode 100644 index f5e23397f3..6bd6bee198 --- a/it/guide/using-template-engines.md +++ b/it/guide/using-template-engines.md @@ -1,61 +1,62 @@ --- layout: page title: Utilizzo di motori di template con Express +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: it +redirect_from: " " --- # Utilizzo di motori di template con Express -Prima che Express possa eseguire il rendering di file template, è necessario specificare le seguenti impostazioni dell'applicazione: +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +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. -* `views`, la directory dove sono ubicati i file di template. Ad esempio: `app.set('views', './views')` -* `view engine`, il motore di template da utilizzare. Ad esempio: `app.set('view engine', 'pug')` +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. + +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: + +- `views`, la directory dove sono ubicati i file di template. Ad esempio: `app.set('views', './views')` + This defaults to the `views` directory in the application root directory. +- `view engine`, il motore di template da utilizzare. Ad esempio: `app.set('view engine', 'pug')` Quindi, installare il pacchetto npm del motore di template corrispondente: -
    -
    +```bash
     $ npm install pug --save
    -
    -
    +```
    I motori di template compatibili con Express, ad esempio Pug esportano una funzione denominata `__express(filePath, options, callback)`, che viene richiamata dalla funzione `res.render()`, per il rendering del codice di template. Alcuni motori di template non seguono questa convenzione. La libreria [Consolidate.js](https://www.npmjs.org/package/consolidate) segue questa convenzione, associando tutti i motori di template Node.js popolari e, perciò, funziona ininterrottamente in Express. +
    Una volta specificata l'impostazione view engine, non è necessario specificare il motore o caricare il modulo del motore di template nella propria app; Express carica il modulo internamente, come mostrato di seguito (per l'esempio precedente). -
    -
    -app.set('view engine', 'pug');
    -
    -
    +```js +app.set('view engine', 'pug') +``` Creare un file di template Pug denominato `index.pug` nella directory `views`, con il seguente contenuto: -
    -
    +```pug
     html
       head
         title= title
       body
         h1= message
    -
    -
    +``` Quindi, creare una route per il rendering del file `index.pug`. Se la proprietà `view engine` non è impostata, è necessario specificare l'estensione del file `view`. Altrimenti, è possibile ometterla. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` Quando si fa una richiesta alla home page, verrà eseguito il rendering del file `index.pug` come HTML. -Per ulteriori informazioni su come funzionano i motori di template in Express, consultare la sezione: ["Sviluppo dei motori di template per Express"](/{{ page.lang }}/advanced/developing-template-engines.html). +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/it/guide/writing-middleware.md b/it/guide/writing-middleware.md old mode 100755 new mode 100644 index c9f6079b9d..d2d105f878 --- a/it/guide/writing-middleware.md +++ b/it/guide/writing-middleware.md @@ -1,33 +1,35 @@ --- layout: page title: Compilazione del middleware per l'utilizzo nelle applicazioni Express +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: it +redirect_from: " " --- # Compilazione del middleware per l'utilizzo nelle applicazioni Express

    Panoramica

    -Le funzioni *middleware* sono funzioni con accesso all'[oggetto richiesta](/{{ page.lang }}/4x/api.html#req) (`req`), all'[oggetto risposta](/{{ page.lang }}/4x/api.html#res) (`res`) e alla successiva funzione middleware nel ciclo richiesta-risposta dell'applicazione. La successiva funzione middleware viene comunemente denotata da una variabile denominata `next`. +Le funzioni _middleware_ sono funzioni con accesso all'[oggetto richiesta](/{{ page.lang }}/4x/api.html#req) (`req`), all'[oggetto risposta](/{{ page.lang }}/4x/api.html#res) (`res`) e alla successiva funzione middleware nel ciclo richiesta-risposta dell'applicazione. La successiva funzione middleware viene comunemente denotata da una variabile denominata `next`. Le funzioni middleware possono eseguire le attività elencate di seguito: -* Eseguire qualsiasi codice. -* Apportare modifiche agli oggetti richiesta e risposta. -* Terminare il ciclo richiesta-risposta. -* Chiamare il successivo middleware nello stack. +- Eseguire qualsiasi codice. +- Apportare modifiche agli oggetti richiesta e risposta. +- Terminare il ciclo richiesta-risposta. +- Chiamare il successivo middleware nello stack. Se la funzione middleware corrente non termina il ciclo richiesta-risposta, deve richiamare `next()` per passare il controllo alla successiva funzione middleware. Altrimenti, la richiesta verrà lasciata in sospeso. I seguenti esempi mostrano gli elementi di una chiamata alla funzione middleware: - -
    - +
    + + -
    Percorso (route) per cui si applica la funzione middleware.
    @@ -40,86 +42,64 @@ I seguenti esempi mostrano gli elementi di una chiamata alla funzione middleware
    Argomento richiesta HTTP nella funzione middleware, denominato "req" per convenzione.
    +Elements of a middleware function call -
    Metodo HTTP per cui si applica la funzione middleware.
    +
    +
    Metodo HTTP per cui si applica la funzione middleware.
    +
    - +

    Esempio

    Ecco un esempio di una semplice applicazione Express "Hello World", per cui si definiranno due funzioni middleware: +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. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    - -

    Sviluppo

    +app.listen(3000) +``` +

    Middleware function myLogger

    Ecco un semplice esempio di una funzione middleware, denominata "myLogger". Questa funzione stampa semplicemente la dicitura "LOGGED" quando una richiesta all'applicazione la attraversa. La funzione middleware è assegnata ad una variabile denominata `myLogger`. -
    -
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    -
    -
    +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
    -Si noti la chiamata precedente a `next()`. Richiamando questa funzione si richiama la successiva funzione middleware nell'applicazione. -La funzione `next()` non fa parte dell'API Express o Node.js, ma è il terzo argomento trasmesso alla funzione middleware. La funzione `next()` potrebbe essere denominata in qualsiasi modo, ma per convenzione viene sempre denominata "next". Per evitare confusione, utilizzare sempre questa convenzione. +Si noti la chiamata precedente a `next()`. Richiamando questa funzione si richiama la successiva funzione middleware nell'applicazione. +La funzione `next()` non fa parte dell'API Express o Node.js, ma è il terzo argomento trasmesso alla funzione middleware. La funzione `next()` potrebbe essere denominata in qualsiasi modo, ma per convenzione viene sempre denominata "next". +Per evitare confusione, utilizzare sempre questa convenzione.
    Per caricare la funzione middleware, richiamare `app.use()`, specificando la funzione middleware. Ad esempio, il seguente codice carica la funzione middleware `myLogger` prima della route al percorso root (/). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    +const myLogger = function (req, res, next) {
    +  console.log('LOGGED')
    +  next()
    +}
     
    -app.use(myLogger);
    +app.use(myLogger)
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    +app.listen(3000) +``` Ogni volta che un'applicazione riceve una richiesta, viene stampato il messaggio "LOGGED" sul terminale. @@ -129,43 +109,112 @@ Se `myLogger` viene caricato dopo la route sul percorso root, la richiesta non l La funzione middleware `myLogger` stampa semplicemente un messaggio, successivamente passa la richiesta alla successiva funzione middleware nello stack chiamando la funzione `next()`. +

    Middleware function requestTime

    + Nel successivo esempio viene aggiunta una proprietà denominata `requestTime` all'oggetto richiesta. Questa funzione middleware verrà denominata "requestTime". -
    -
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    -
    -
    +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` L'applicazione utilizza ora la funzione middleware `requestTime`. Inoltre, la funzione di callback della route percorso root utilizza la proprietà che la funzione middleware aggiunge a `req` (l'oggetto richiesta). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    +const requestTime = function (req, res, next) {
    +  req.requestTime = Date.now()
    +  next()
    +}
     
    -app.use(requestTime);
    +app.use(requestTime)
     
    -app.get('/', function (req, res) {
    -  var responseText = 'Hello World!
    '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) -app.listen(3000); -
    -
    +app.listen(3000) +``` Quando si effettua una richiesta al root dell'applicazione, l'applicazione mostra la cronologia data e ora della richiesta nel browser. +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    + Poiché si dispone dell'accesso all'oggetto richiesta, l'oggetto risposta, la successiva funzione middleware nello stack e l'API Node.js completo, le possibilità con le funzioni middleware sono infinite. Per ulteriori informazioni sul middleware Express, consultare: [Utilizzo del middleware Express](/{{ page.lang }}/guide/using-middleware.html). + +

    Configurable middleware

    + +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. + +File: `my-middleware.js` + +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` + +The middleware can now be used as shown below. + +```js +const mw = require('./my-middleware.js') + +app.use(mw({ option1: '1', option2: '2' })) +``` + +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/it/index.md b/it/index.md index 9c2a8b0037..be45482a6a 100644 --- a/it/index.md +++ b/it/index.md @@ -1,53 +1,61 @@ --- layout: home -title: Express - Framework per applicazioni web Node.js +title: Express - Node.js web application framework +description: "Express is a fast, unopinionated, minimalist web framework for Node.js, providing a robust set of features for web and mobile applications." menu: home -lang: it +redirect_from: " " --- +
    - {% include header/header-{{ page.lang }}.html %} -
    - - Framework web veloce, non categorico e minimalista per Node.js + +

    Fast, unopinionated, minimalist web framework for Node.js

    -
    $ npm install express --save
    -
    -
    - +
    $ npm install express --save
    -
    - - +
    -
    - -
    -
    -

    Applicazioni web

    Express è un framework per applicazioni web Node.js flessibile e leggero che fornisce una serie di funzioni avanzate per le applicazioni web e per dispositivi mobili. -
    +```javascript +const express = require('express') +const app = express() +const port = 3000 -
    -

    API

    Con una miriade di metodi di utilità HTTP e middleware a disposizione, la creazione di un'API affidabile è un processo facile e veloce. -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -
    -

    Prestazioni

    Express fornisce uno strato sottile di funzionalità di base per le applicazioni web, senza nascondere le funzioni Node.js che conosci e ami. -
    +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` -
    -
    - diff --git a/it/resources/community.md b/it/resources/community.md old mode 100755 new mode 100644 index a619f8728c..5c9004c57c --- a/it/resources/community.md +++ b/it/resources/community.md @@ -1,27 +1,59 @@ --- layout: page title: Community di Express +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: it +redirect_from: " " --- # Community -## Mailing List +## Technical committee -Unisciti a oltre 2000 utenti Express o cerca oltre 5000 -dibattiti nel [Gruppo Google](https://groups.google.com/group/express-js). +The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, +and other issues relevant to the Express project. Each meeting is typically announced in an +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is +open to all observers. -## Gitter +The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -La [chatroom di expressjs/express](https://gitter.im/expressjs/express) è un posto unico per gli sviluppatori -che sono interessati ai dibattiti giornalieri su Express. +Members of the Express technical committee are: -## Canale IRC +**Active:** -Centinaia di sviluppatori inattivi in #express su freenode ogni giorno. -Per domande sul framework, entra per un -feedback veloce. +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida + +**Inactive:** + +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express is made of many modules + +La nostra community molto attiva ha creato una vasta varietà di estensioni, +[moduli middleware](/{{ page.lang }}/resources/middleware.html) e framework di livello più elevato. + +Additionally, the Express community maintains modules in these two GitHub orgs: + +- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. + +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). + +## Problematiche + +Se si riscontra un bug o un problema oppure se si desidera semplicemente sottoporre una richiesta, +aprire un ticket in [coda problemi](https://github.com/expressjs/express/issues). ## Esempi @@ -29,14 +61,32 @@ Visualizzare dozzine di [esempi](https://github.com/expressjs/express/tree/maste di applicazioni Express nel repository che copre tutto dall'autenticazione e progettazione API all'integrazione del motore di template. -## Problematiche +## Github Discussions -Se si riscontra un bug o un problema oppure se si desidera semplicemente sottoporre una richiesta, -aprire un ticket in [coda problemi](https://github.com/expressjs/express/issues). +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. -## Terze parti +# Branding of Express.js -La nostra community molto attiva ha creato una vasta varietà di estensioni, -[moduli middleware](/{{ page.lang }}/resources/middleware.html) e framework di livello più elevato. È possibile verificarli in -[wiki](https://github.com/expressjs/express/wiki). +## Express.js Logo + +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/it/resources/contributing.md b/it/resources/contributing.md new file mode 100644 index 0000000000..e37cee3122 --- /dev/null +++ b/it/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/it/resources/glossary.md b/it/resources/glossary.md old mode 100755 new mode 100644 index ec22bc0d1f..ab17ddf990 --- a/it/resources/glossary.md +++ b/it/resources/glossary.md @@ -1,8 +1,9 @@ --- layout: page title: Glossario di Express +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: it +redirect_from: " " --- # Glossario @@ -13,11 +14,11 @@ Solitamente, uno o più programmi progettati per gestire operazioni per uno scop ### API -Interfaccia di programmazione dell'applicazione. Si consiglia di scrivere per intero l'acronimo quando lo si usa per la prima volta. +Interfaccia di programmazione dell'applicazione. Si consiglia di scrivere per intero l'acronimo quando lo si usa per la prima volta. ### Express -Un framework web veloce, non categorico e minimalista per le applicazioni Node.js. Solitamente, si preferisce utilizzare "Express" piuttosto che "Express.js," anche se il secondo è accettabile. +Un framework web veloce, non categorico e minimalista per le applicazioni Node.js. Solitamente, si preferisce utilizzare "Express" piuttosto che "Express.js," anche se il secondo è accettabile. ### libuv @@ -25,23 +26,31 @@ Una libreria di supporto multi-piattaforma che si focalizza su I/O asincrono, in ### middleware -Una funzione che viene richiamata dal livello di routing Express prima dell'handler di richiesta finale, pertanto si trova al centro tra una richiesta base e la route prevista. Segue un elenco che indica alcune terminologie utilizzate per middleware: +Una funzione che viene richiamata dal livello di routing Express prima dell'handler di richiesta finale, pertanto si trova al centro tra una richiesta base e la route prevista. Segue un elenco che indica alcune terminologie utilizzate per middleware: - * `var foo = require('middleware')` significa *richiesta* o *utilizzo* di un modulo Node.js. E l'istruzione `var mw = foo()` solitamente restituisce il middleware. - * `app.use(mw)` significa *aggiunta del middleware allo stack di elaborazione globale*. - * `app.get('/foo', mw, function (req, res) { ... })` significa *aggiunta del middleware allo stack di elaborazione "GET /foo"*. +- `var foo = require('middleware')` significa _richiesta_ o _utilizzo_ di un modulo Node.js. E l'istruzione `var mw = foo()` solitamente restituisce il middleware. +- `app.use(mw)` significa _aggiunta del middleware allo stack di elaborazione globale_. +- `app.get('/foo', mw, function (req, res) { ... })` significa _aggiunta del middleware allo stack di elaborazione "GET /foo"_. ### Node.js -Una piattaforma software utilizzata per creare applicazioni di rete scalabili. Node.js utilizza JavaScript e il relativo linguaggio di scripting e raggiunge una trasmissione di dati elevata tramite un I/O non a blocchi e un loop di evento a thread singolo. Consultare [nodejs.org](http://nodejs.org/). **Nota di utilizzo**: Inizialmente, "Node.js," successivamente "Node". +Una piattaforma software utilizzata per creare applicazioni di rete scalabili. Node.js utilizza JavaScript e il relativo linguaggio di scripting e raggiunge una trasmissione di dati elevata tramite un I/O non a blocchi e un loop di evento a thread singolo. Consultare [nodejs.org](http://nodejs.org/). **Nota di utilizzo**: Inizialmente, "Node.js," successivamente "Node". ### open-source, open source -Quando utilizzato come aggettivo, viene aggiunto un trattino; ad esempio: "Questo è un software open-source." Consultare [Software open-source su Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Nota: anche se è molto comune scriverlo senza trattino, stiamo utilizzando le regole dell'inglese standard che richiedono di inserire un trattino in un aggettivo composto. +Quando utilizzato come aggettivo, viene aggiunto un trattino; ad esempio: "Questo è un software open-source." Consultare [Software open-source su Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). + +{% capture english-rules %} + +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. + +{% endcapture %} + +{% include admonitions/note.html content=english-rules %} ### richiesta -Una richiesta HTTP. Un client un messaggio di richiesta HTTP a un server, il quale restituisce una risposta. La richiesta deve utilizzare uno dei diversi [metodi di richiesta](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) ad esempio GET, POST e così via. +Una richiesta HTTP. Un client un messaggio di richiesta HTTP a un server, il quale restituisce una risposta. La richiesta deve utilizzare uno dei diversi [metodi di richiesta](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) ad esempio GET, POST e così via. ### risposta @@ -49,7 +58,7 @@ Una risposta HTTP. Un server restituisce un messaggio di risposta HTTP al client ### route -Parte di un URL che identifica una risorsa. Ad esempio, in `http://foo.com/products/id`, "/products/id" è la route. +Parte di un URL che identifica una risorsa. Ad esempio, in `http://foo.com/products/id`, "/products/id" è la route. ### router diff --git a/it/resources/learning.md b/it/resources/learning.md deleted file mode 100755 index d7b1afcbdb..0000000000 --- a/it/resources/learning.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: page -title: Apprendimento aggiuntivo -menu: resources -lang: it ---- - -# Apprendimento aggiuntivo - -
    Disclaimer: Unendorsed community content.
    - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Node-tricks Blog: Express category](http://node-tricks.com/category/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/it/resources/middleware.md b/it/resources/middleware.md old mode 100755 new mode 100644 index dc257d525e..08437e4b22 --- a/it/resources/middleware.md +++ b/it/resources/middleware.md @@ -1,64 +1,43 @@ --- -layout: page +layout: middleware title: Middleware Express +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: it +redirect_from: " " +module: mw-home --- -# Middleware di terzi +## Middleware Express Di seguito vengono riportati alcuni moduli middleware Express: - - [body-parser](https://github.com/expressjs/body-parser): in precedenza `express.bodyParser`, `json` e `urlencoded`. - Consultare inoltre: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): in precedenza `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): moduli middleware Connect/Express per una gestione dell'immagine ottimale. Se possibile, cambia le estensioni delle immagini a `.webp` o `.jxr`. - - [connect-timeout](https://github.com/expressjs/timeout): in precedenza `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): in precedenza `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): in precedenza `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): in precedenza `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): in precedenza `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): uno strumento di sviluppo riservato che aggiunge una scheda contenente informazioni sulle variabili di template (locali), sessione corrente, dati della richiesta utili e altro ancora all'applicazione. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): modulo middleware Express per filtrare le parti delle risposte JSON in base alla stringa query `fields`; utilizzando una risposta parziale API Google. - - [express-session](https://github.com/expressjs/session): in precedenza `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): modulo middleware Express per l'utilizzo di un CDN per asset statici, con supporto host multiplo (Ad esempio: cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): modulo middleware Express per persone che sono rigide sull'utilizzo di barre. - - [express-stormpath](https://github.com/stormpath/stormpath-express): modulo middleware Express per lo storage utente, autenticazione, autorizzazione, SSO e sicurezza dati. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): modulo middleware per il reindirizzamento delle richieste HTTP contenenti caratteri maiuscoli per una forma con caratteri minuscoli canonica. - - [helmet](https://github.com/helmetjs/helmet): modulo che aiuta a proteggere le applicazioni impostando varie intestazioni HTTP. - - [join-io](https://github.com/coderaiser/join-io "join-io"): modulo per unire i file in entrata per ridurre il conteggio delle richieste. - - [method-override](https://github.com/expressjs/method-override): in precedenza `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): in precedenza `logger` - - [passport](https://github.com/jaredhanson/passport): modulo middleware Express per l'autenticazione. - - [response-time](https://github.com/expressjs/response-time): in precedenza `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): in precedenza `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): in precedenza `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): modulo per gestire i contenuti statici. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): URL riconosciute o Caching Header per asset statici incluso il supporto per uno o più domini esterni. - - [vhost](https://github.com/expressjs/vhost): in precedenza `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): modulo middleware Express che fornisce metodi di aiuto comuni per le viste. - - [sriracha-admin](https://github.com/hdngr/siracha): modulo middleware Express che crea in modo dinamico un sito admin per Mongoose. +| Middleware module | Descrizione | +| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | -Alcuni moduli middleware precedentemente inclusi in Connect non sono più supportati dal team di Connect/Express. Questi moduli sono stati sostituiti da un modulo alternativo o dovrebbero essere sostituiti a un modulo migliore. Utilizzare una delle seguenti alternative: +## Per ulteriori moduli middleware, consultare: - - express.cookieParser - - [cookie](https://github.com/jed/cookies) e [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) +These are some additional popular middleware modules. -Per ulteriori moduli middleware, consultare: +{% include community-caveat.html %} - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| Middleware module | Descrizione | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet): modulo che aiuta a proteggere le applicazioni impostando varie intestazioni HTTP. | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport): modulo middleware Express per l'autenticazione. | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/it/resources/middleware/body-parser.md b/it/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/it/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/it/resources/middleware/compression.md b/it/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/it/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/it/resources/middleware/connect-rid.md b/it/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/it/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/it/resources/middleware/cookie-parser.md b/it/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/it/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/it/resources/middleware/cookie-session.md b/it/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/it/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/it/resources/middleware/cors.md b/it/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/it/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/it/resources/middleware/errorhandler.md b/it/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/it/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/it/resources/middleware/method-override.md b/it/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/it/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/it/resources/middleware/morgan.md b/it/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/it/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/it/resources/middleware/multer.md b/it/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/it/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/it/resources/middleware/response-time.md b/it/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/it/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/it/resources/middleware/serve-favicon.md b/it/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/it/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/it/resources/middleware/serve-index.md b/it/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/it/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/it/resources/middleware/serve-static.md b/it/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/it/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/it/resources/middleware/session.md b/it/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/it/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/it/resources/middleware/timeout.md b/it/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/it/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/it/resources/middleware/vhost.md b/it/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/it/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/it/resources/utils.md b/it/resources/utils.md new file mode 100644 index 0000000000..5fc784092d --- /dev/null +++ b/it/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/it/starter/basic-routing.md b/it/starter/basic-routing.md old mode 100755 new mode 100644 index f710d028df..b42b7cacea --- a/it/starter/basic-routing.md +++ b/it/starter/basic-routing.md @@ -1,22 +1,22 @@ --- layout: page title: Routing di base Express +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: it +redirect_from: " " --- # Routing di base -Per *Routing* si intende determinare come un'applicazione risponde a una richiesta client a un endpoint particolare, il quale è un URI (o percorso) e un metodo di richiesta HTTP specifico (GET, POST e così via). +Per _Routing_ si intende determinare come un'applicazione risponde a una richiesta client a un endpoint particolare, il quale è un URI (o percorso) e un metodo di richiesta HTTP specifico (GET, POST e così via). Ciascuna route può disporre di una o più funzioni dell'handler, le quali vengono eseguite quando si trova una corrispondenza per la route. La definizione della route ha la seguente struttura: -
    -
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` Dove: @@ -33,42 +33,36 @@ I seguenti esempi mostrano come definire route semplici. Rispondere con `Hello World!` sulla homepage: -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -Rispondere alla richiesta POST sulla route principale (`/`), la home page dell'applicazione: +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` Rispondere a una richiesta PUT alla route `/user`: -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` Rispondere a una richiesta DELETE alla route `/user`: -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` Per ulteriori dettagli sul routing, consultare il [Manuale routing](/{{ page.lang }}/guide/routing.html). + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/it/starter/examples.md b/it/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/it/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/it/starter/faq.md b/it/starter/faq.md old mode 100755 new mode 100644 index 8d52cb5ab3..2ce2ea1384 --- a/it/starter/faq.md +++ b/it/starter/faq.md @@ -1,8 +1,9 @@ --- layout: page title: FAQ di Express +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: it +redirect_from: " " --- # FAQ @@ -17,13 +18,13 @@ Le route e altre logiche specifiche dell'applicazione possono essere presenti in in qualsiasi struttura di directory desiderata. Visualizzare i seguenti esempi: -* [Elenchi route](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Definizione route](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [Controllori stile MVC](https://github.com/expressjs/express/tree/master/examples/mvc) +- [Elenchi route](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [Definizione route](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [Controllori stile MVC](https://github.com/expressjs/express/tree/master/examples/mvc) Inoltre, ci sono delle estensioni di terze parti per Express, le quali semplificano alcuni di questi modelli: -* [Routing pieno di risorse](https://github.com/expressjs/express-resource) +- [Routing pieno di risorse](https://github.com/expressjs/express-resource) ## In che modo è possibile definire i modelli? @@ -36,10 +37,9 @@ Consultare [LoopBack](http://loopback.io) per un framework basato su Express inc ## In che modo è possibile autenticare gli utenti? L'autenticazione è un'altra area categorica in cui non si -avventura Express. È possibile utilizzare qualsiasi schema di autenticazione desiderato. +avventura Express. È possibile utilizzare qualsiasi schema di autenticazione desiderato. Per uno schema nome utente / password semplice, consultare [questo esempio](https://github.com/expressjs/express/tree/master/examples/auth). - ## Quale motore di template supporta Express? Express supporta qualsiasi motore di template conforme alla sigla `(path, locals, callback)`. @@ -47,6 +47,8 @@ Per normalizzare le interfacce del motore di template e la memorizzazione in cac [consolidate.js](https://github.com/visionmedia/consolidate.js) per il supporto. I motori di template potrebbero ancora non supportare Express. +For more information, see [Using template engines with Express](/{{page.lang}}/guide/using-template-engines.html). + ## In che modo è possibile gestire le risposte 404? In Express, le risposte 404 non sono il risultato di un errore, pertanto @@ -57,27 +59,26 @@ e non ha riscontrato nessuna risposta da parte di quest'ultimi. L'unica cosa da una funzione middleware alla parte finale dello stack (sotto tutte le altre funzioni) per gestire una risposta 404: -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` + +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## In che modo è possibile impostare un gestore degli errori? È possibile definire il middleware di gestione degli errori nello stesso modo in cui si definisce qualsiasi altro middleware, ad eccezione delle funzioni di gestione degli errori che hanno quattro argomenti invece di tre; nello specifico la firma `(err, req, res, next)`: -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Per ulteriori informazioni, consultare [Gestione degli errori](/{{ page.lang }}/guide/error-handling.html). @@ -87,3 +88,10 @@ Non è necessario farlo! Non è necessario "eseguire il rendering" dell'HTML con Se si dispone di un file specifico, utilizzare la funzione `res.sendFile()`. Se si stanno gestendo molti asset da una directory, utilizzare la funzione middleware `express.static()`. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/it/starter/generator.md b/it/starter/generator.md old mode 100755 new mode 100644 index 43f465d909..c2e8bec343 --- a/it/starter/generator.md +++ b/it/starter/generator.md @@ -1,29 +1,34 @@ --- layout: page title: Programma di creazione applicazione Express +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: it +redirect_from: " " --- # Programma di creazione applicazione Express Utilizzare lo strumento di creazione dell'applicazione, `express`, per creare velocemente una struttura dell'applicazione. -Installare `express` con il seguente comando: +You can run the application generator with the `npx` command (available in Node.js 8.2.0). -
    -
    -$ npm install express-generator -g
    -
    -
    +```bash +$ npx express-generator +``` + +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` Visualizzare le opzioni del comando con l'opzione `-h`: -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -34,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` -Ad esempio, quanto segue crea un'applicazione Express denominata _myapp_ nella directory di lavoro corrente: +Ad esempio, quanto segue crea un'applicazione Express denominata _myapp_ nella directory di lavoro corrente: The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -64,40 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` Successivamente, installare le dipendenze: -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` -Su MacOS o Linux, eseguire l'applicazione con il seguente comando: +Su Windows, utilizzare questo comando: -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` -Su Windows, utilizzare questo comando: +Su MacOS o Linux, eseguire l'applicazione con il seguente comando: -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` + +On Windows PowerShell, use this command: + +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` Quindi caricare `http://localhost:3000/` sul browser per accedere all'applicazione. L'applicazione creata dispone della seguente struttura per la directory: -
    -
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -117,9 +118,10 @@ L'applicazione creata dispone della seguente struttura per la directory:
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    La struttura dell'applicazione creata dal programma di creazione è solo uno dei tanti modi disponibili per creare la struttura delle applicazioni Express. È possibile utilizzare questa struttura o modificarla a seconda delle proprie necessità.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/it/starter/hello-world.md b/it/starter/hello-world.md old mode 100755 new mode 100644 index 58d590c6ff..e11217a50f --- a/it/starter/hello-world.md +++ b/it/starter/hello-world.md @@ -1,8 +1,9 @@ --- layout: page title: Esempio di "Hello World" di express +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: it +redirect_from: " " --- # Esempio di Hello world @@ -11,12 +12,7 @@ lang: it In sostanza, questa sarà l'applicazione Express più semplice che è possibile creare. È un'applicazione a singolo file — e *non* quello che si ottiene se si utilizza il [Programma di creazione Express](/{{ page.lang }}/starter/generator.html), il quale crea le fondamenta per un'applicazione completa con molti file JavaScript, template Jade e sotto directory per diversi scopi.
    -Per prima cosa creare una directory denominata `myapp`, passare a quest'ultima ed eseguire `npm init`. Quindi installare `express` come dipendenza, come descritto nella [Guida all'installazione](/{{ page.lang }}/starter/installing.html). - -Nella directory `myapp`, creare un file denominato `app.js` e aggiungere il seguente codice: - -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -26,13 +22,18 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    -
    +``` L'applicazione avvia un server e resta in ascolto sulla porta 3000 per le connessioni. L'applicazione risponde con "Hello World!" per le richieste -all'URL root (`/`) o *route*. Per qualsiasi altro percorso, risponderà con il messaggio **404 Non trovato**. +all'URL root (`/`) o _route_. Per qualsiasi altro percorso, risponderà con il messaggio **404 Non trovato**. + +### Running Locally + +Per prima cosa creare una directory denominata `myapp`, passare a quest'ultima ed eseguire `npm init`. Quindi installare `express` come dipendenza, come descritto nella [Guida all'installazione](/{{ page.lang }}/starter/installing.html). + +Nella directory `myapp`, creare un file denominato `app.js` e aggiungere il seguente codice:
    I valori `req` (richiesta) e `res` (risposta) sono esattamente gli stessi oggetti forniti da Node, quindi è possibile richiamare @@ -41,11 +42,10 @@ I valori `req` (richiesta) e `res` (risposta) sono esattamente gli stessi oggett Eseguire l'applicazione con il seguente comando: -
    -
    +```bash
     $ node app.js
    -
    -
    +``` Successivamente, caricare [http://localhost:3000/](http://localhost:3000/) su un browser per visualizzare l'output. +### [Previous: Installing ](/{{ page.lang }}/starter/installing.html)    [Next: Express Generator ](/{{ page.lang }}/starter/generator.html) diff --git a/it/starter/installing.md b/it/starter/installing.md old mode 100755 new mode 100644 index e5bcf28699..5834f3fc87 --- a/it/starter/installing.md +++ b/it/starter/installing.md @@ -1,58 +1,53 @@ --- layout: page title: Installazione di Express +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: it +redirect_from: " " --- # Installazione Presumendo che sia stato già installato [Node.js](https://nodejs.org/), creare una directory in cui conservare l'applicazione e renderla la directory di lavoro. -
    -
    +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher.
    +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher.
    +
    +```bash
     $ mkdir myapp
     $ cd myapp
    -
    -
    +``` Utilizzare il comando `npm init` per creare un file `package.json` per l'applicazione. Per ulteriori informazioni sul funzionamento di `package.json`, consultare [Informazioni specifiche sulla gestione di package.json di npm](https://docs.npmjs.com/files/package.json). -
    -
    +```bash
     $ npm init
    -
    -
    +``` Questo comando richiede di specificare alcune informazioni, ad esempio il nome e la versione dell'applicazione. Per il momento, è possibile semplicemente premere il tasto INVIO per accettare i valori di default per molti di esse, ad eccezione di quanto segue: -
    -
    +```
     entry point: (index.js)
    -
    -
    +``` Immettere `app.js` o qualsiasi altra cosa come nome del file principale. Se si desidera che sia `index.js`, premere il tasto INVIO per accettare il nome file predefinito consigliato. Quindi installare Express nella directory `myapp` e salvarlo nell'elenco delle dipendenze. Ad esempio: -
    -
    -$ npm install express --save
    -
    -
    +```bash +$ npm install express +``` Per installare momentaneamente Express e non aggiungerlo all'elenco di dipendenze, omettere l'opzione `--save`: -
    -
    -$ npm install express
    -
    -
    +```bash +$ npm install express --no-save +```
    -I moduli Node installati con l'opzione `--save` vengono aggiunti all'elenco `dependencies` nel file `package.json`. -Successivamente, l'esecuzione di `npm install` nella directory `app` installerà automaticamente i moduli nell'elenco di dipendenze. +I moduli Node installati con l'opzione `--save` vengono aggiunti all'elenco `dependencies` nel file `package.json`. Successivamente, l'esecuzione di `npm install` nella directory `app` installerà automaticamente i moduli nell'elenco di dipendenze.
    + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/it/starter/static-files.md b/it/starter/static-files.md old mode 100755 new mode 100644 index dc12af48a6..c06a0b09b1 --- a/it/starter/static-files.md +++ b/it/starter/static-files.md @@ -1,33 +1,39 @@ --- layout: page title: Gestione dei file statici in Express +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: it +redirect_from: " " --- # Gestione dei file statici in Express Per gestire i file statici, quali immagini, file CSS e file JavaScript, utilizzare la funzione middleware integrata `express.static` in Express. -Fornire il nome della directory che contiene gli asset statici alla funzione middleware `express.static` per iniziare a gestire i file direttamente. Ad esempio, utilizzare il seguente codice per gestire le immagini, i file CSS e i file JavaScript nella directory denominata `public`: +The function signature is: -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +Ad esempio, utilizzare il seguente codice per gestire le immagini, i file CSS e i file JavaScript nella directory denominata `public`: + +```js +app.use(express.static('public')) +``` Ora, è possibile caricare i file che si trovano nella directory `public`: -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +```
    Express ricerca i file relativi alla directory statica, pertanto il nome della directory statica non è parte dell'URL. @@ -35,39 +41,41 @@ Express ricerca i file relativi alla directory statica, pertanto il nome della d Per utilizzare più directory di asset statiche, richiamare la funzione middleware `express.static` più volte: -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` Express ricerca i file nell'ordine in cui sono state impostate le directory statiche con la funzione middleware `express.static`. -Per creare un prefisso per il percorso virtuale (in cui il percorso non esiste effettivamente nel file system) per i file gestiti dalla funzione `express.static`, [specificare un percorso di caricamento](/{{ page.lang }}/4x/api.html#app.use) per la directory statica, come mostrato di seguito: +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` Ora, è possibile caricare i file che si trovano nella directory `public` dal prefisso del percorso `/static`. -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` Tuttavia, il percorso fornito per la funzione `express.static` è relativo alla directory dalla quale è possibile avviare il processo `node`. Se si esegue l'applicazione express da un'altra directory, è preferibile utilizzare il percorso assoluto della directory che si desidera gestire: -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +```js +const path = require('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.html). + +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/it/support/index.md b/it/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/it/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/ja/3x/api.md b/ja/3x/api.md old mode 100755 new mode 100644 index 03f530dcc7..39825ab5e4 --- a/ja/3x/api.md +++ b/ja/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - API リファレンス +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: ja +redirect_from: " " --- +
    **Express 3.x は保守されなくなりました** - 最終更新日 (2015 年 8 月 1 日) 以降、3.x における既知および不明のセキュリティーとパフォーマンスの問題には対応していません。最新バージョンの Express を使用することを強くお勧めします。 -
    - -

    3.x API

    +3.xの既知および未知のセキュリティ問題は、最終更新(2015年8月1日)以降は対処されていません。3.x系を使用することは安全であると見なされるべきではありません。 It is highly recommended to use the latest version of Express. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
    - - {% include api/en/3x/res.md %} +

    3.x API

    - - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %}
    diff --git a/ja/4x/api.md b/ja/4x/api.md old mode 100755 new mode 100644 index e6c169e0d1..f9e750ddf2 --- a/ja/4x/api.md +++ b/ja/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - API リファレンス +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: ja +redirect_from: " " --- +

    4.x API

    - - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
    diff --git a/ja/5x/api.md b/ja/5x/api.md new file mode 100644 index 0000000000..e3214d6fd7 --- /dev/null +++ b/ja/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - API リファレンス +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
    + +

    5.x API

    + +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
    diff --git a/ja/advanced/best-practice-performance.md b/ja/advanced/best-practice-performance.md old mode 100755 new mode 100644 index 89121e7aca..3de26f0e60 --- a/ja/advanced/best-practice-performance.md +++ b/ja/advanced/best-practice-performance.md @@ -1,113 +1,102 @@ --- layout: page title: 実稼働環境における Express の使用におけるパフォーマンスに関するベスト・プラクティス +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: ja +redirect_from: " " --- # 実稼働環境におけるベスト・プラクティス: パフォーマンスと信頼性 -## 概説 - この記事では、実稼働環境にデプロイされた Express アプリケーションのパフォーマンスと信頼性に関するベスト・プラクティスについて説明します。 -このトピックは、従来型の開発と運用の両方にわたる「DevOps」の世界に明確に分類されます。したがって、情報は次の 2 つの部分に分かれています。 - -* コードで実行する処理 (開発部分) - * [gzip 圧縮を使用する](#use-gzip-compression) - * [同期関数を使用しない](#dont-use-synchronous-functions) - * [ロギングを正確に実行する](#do-logging-correctly) - * [例外を適切に処理する](#handle-exceptions-properly) -* 環境/セットアップで実行する処理 (運用部分) - * [Set NODE_ENV to "production"](#set-node_env-to-production) - * [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) - * [Run your app in a cluster](#run-your-app-in-a-cluster) - * [Cache request results](#cache-request-results) - * [Use a load balancer](#use-a-load-balancer) - * [Use a reverse proxy](#use-a-reverse-proxy) +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: + +- コードで実行する処理 (開発部分) + - [gzip 圧縮を使用する](#use-gzip-compression) + - [同期関数を使用しない](#dont-use-synchronous-functions) + - [ロギングを正確に実行する](#do-logging-correctly) + - [例外を適切に処理する](#handle-exceptions-properly) +- 環境/セットアップで実行する処理 (運用部分) + - [Set NODE_ENV to "production"](#set-node_env-to-production) + - [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) + - [Run your app in a cluster](#run-your-app-in-a-cluster) + - [Cache request results](#cache-request-results) + - [Use a load balancer](#use-a-load-balancer) + - [Use a reverse proxy](#use-a-reverse-proxy) ## コードで実行する処理 {#in-code} 以下に、アプリケーションのパフォーマンスを向上させるためにコードで実行できる処理をいくつか挙げます。 -* [gzip 圧縮を使用する](#use-gzip-compression) -* [同期関数を使用しない](#dont-use-synchronous-functions) -* [ロギングを正確に実行する](#do-logging-correctly) -* [例外を適切に処理する](#handle-exceptions-properly) +- [gzip 圧縮を使用する](#use-gzip-compression) +- [同期関数を使用しない](#dont-use-synchronous-functions) +- [ロギングを正確に実行する](#do-logging-correctly) +- [例外を適切に処理する](#handle-exceptions-properly) ### gzip 圧縮を使用する -Gzip 圧縮により、応答本体のサイズを大幅に縮小できるため、Web アプリケーションの速度が高くなります。Express アプリケーションで gzip 圧縮として [compression](https://www.npmjs.com/package/compression) ミドルウェアを使用してください。次に例を示します。 +Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Gzip 圧縮により、応答本体のサイズを大幅に縮小できるため、Web アプリケーションの速度が高くなります。Express アプリケーションで gzip 圧縮として [compression](https://www.npmjs.com/package/compression) ミドルウェアを使用してください。次に例を示します。 For example: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` -トラフィックが多い実稼働環境の Web サイトでは、圧縮を適用する最適な方法は、リバース・プロキシー・レベルで実装することです ([リバース・プロキシーの使用](#proxy)を参照)。その場合は、compression ミドルウェアを使用する必要はありません。Nginx で gzip 圧縮を有効にする方法について詳しくは、Nginx 資料の [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html) を参照してください。 +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. トラフィックが多い実稼働環境の Web サイトでは、圧縮を適用する最適な方法は、リバース・プロキシー・レベルで実装することです ([リバース・プロキシーの使用](#proxy)を参照)。その場合は、compression ミドルウェアを使用する必要はありません。Nginx で gzip 圧縮を有効にする方法について詳しくは、Nginx 資料の [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html) を参照してください。 ### 同期関数を使用しない -同期の関数とメソッドは、返されるまで実行中のプロセスを結合します。同期関数に対する 1 回の呼び出しは数マイクロ秒から数ミリ秒で返される可能性がありますが、トラフィックが多い Web サイトでは、これらの呼び出しを合計すると、アプリケーションのパフォーマンスが低下します。実稼働環境では、これらを使用しないでください。 +同期の関数とメソッドは、返されるまで実行中のプロセスを結合します。同期関数に対する 1 回の呼び出しは数マイクロ秒から数ミリ秒で返される可能性がありますが、トラフィックが多い Web サイトでは、これらの呼び出しを合計すると、アプリケーションのパフォーマンスが低下します。実稼働環境では、これらを使用しないでください。 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. -ノードおよび多くのモジュールは、同期版と非同期版の関数を提供していますが、実稼働環境では必ず非同期版を使用してください。同期関数を使用しても構わないのは、初期始動時のみです。 +ノードおよび多くのモジュールは、同期版と非同期版の関数を提供していますが、実稼働環境では必ず非同期版を使用してください。同期関数を使用しても構わないのは、初期始動時のみです。 The only time when a synchronous function can be justified is upon initial startup. -Node.js 4.0+ または io.js 2.1.0+ を使用している場合、アプリケーションで同期 API を使用するときに、いつでも `--trace-sync-io` コマンド・ライン・フラグを使用して、警告とスタック・トレースを出力することができます。無論、この機能を実際に実稼働環境で使用することはありませんが、コードを実稼働環境で使用する準備ができていることを確認するために使用できます。詳細については、[io.js 2.1.0 の週次更新](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0)を参照してください。 +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#cli_trace_sync_io) for more information. ### ロギングを正確に実行する -一般に、アプリケーションからのロギングを行う理由には、デバッグと、アプリケーション・アクティビティー (基本的にその他すべて) のロギングの 2 つがあります。`console.log()` または `console.err()` を使用してログ・メッセージを端末に出力するのは、開発環境では一般的な手法です。しかし、宛先が端末またはファイルの場合、[これらの関数は同期的](https://nodejs.org/api/console.html#console_console_1)であるため、出力を別のプログラムにパイプ接続しない限り、実稼働環境には向いていません。 +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 -デバッグの目的でロギングを実行する場合は、`console.log()` を使用するのではなく、[debug](https://www.npmjs.com/package/debug) などの特殊なデバッグ・モジュールを使用します。このモジュールでは、DEBUG 環境変数を使用して、`console.err()` に送信されるデバッグ・メッセージを制御できます。アプリケーションを純粋に非同期的にしておくために、`console.err()` を別のプログラムにパイプ接続することもできます。しかし、実稼働環境ではデバッグを実行することはお勧めしません。 +デバッグの目的でロギングを実行する場合は、`console.log()` を使用するのではなく、[debug](https://www.npmjs.com/package/debug) などの特殊なデバッグ・モジュールを使用します。このモジュールでは、DEBUG 環境変数を使用して、`console.err()` に送信されるデバッグ・メッセージを制御できます。アプリケーションを純粋に非同期的にしておくために、`console.err()` を別のプログラムにパイプ接続することもできます。しかし、実稼働環境ではデバッグを実行することはお勧めしません。 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? #### アプリケーション・アクティビティー -アプリケーション・アクティビティー (例えば、トラフィックまたは API 呼び出しのトラッキング) のロギングを実行する場合は、`console.log()` を使用するのではなく、[Winston](https://www.npmjs.com/package/winston) や [Bunyan](https://www.npmjs.com/package/bunyan) などのロギング・ライブラリーを使用します。これらの 2 つのライブラリーの詳細な比較については、StrongLoop ブログ投稿の [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/) を参照してください。 +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. ### 例外を適切に処理する -Node アプリケーションは、キャッチされていない例外が発生すると、異常終了します。例外を処理せず、適切な処置を取らないと、Express アプリケーションは異常終了してオフラインになります。下記の『[アプリケーションが確実に自動再始動するようにする](#restart)』に記載されているアドバイスに従うと、アプリケーションは異常終了から復旧します。幸い、Express アプリケーションの起動時間は通常短いものです。それでも、異常終了は避けたいものであり、そのためには例外を適切に処理する必要があります。 +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. [アプリケーションが確実に自動再始動するようにする](#ensure-your-app-automatically-restarts) 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. 確実にすべての例外を処理するには、以下の技法を使用します。 -* [Try-catch の使用](#try-catch) -* [Promise の使用](#promises) +- [Try-catch の使用](#try-catch) +- [Promise の使用](#promises) -上記のトピックを読む前に、error-first コールバックの使用と、ミドルウェアへのエラーの伝搬という Node/Express エラー処理の基礎を理解しておく必要があります。Node は、非同期関数からエラーを返すために「error-first コールバック」という規則を使用します。この場合、コールバック関数への最初のパラメーターがエラー・オブジェクトで、その後に続くパラメーターに結果データがあります。エラーがないことを示すには、最初のパラメーターとして `null` を渡します。コールバック関数は、エラーを有意に処理するには、error-first コールバック規則に対応して従う必要があります。Express におけるベスト・プラクティスは、next() 関数を使用して、ミドルウェア・チェーンを介してエラーを伝搬することです。 +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. 上記のトピックを読む前に、error-first コールバックの使用と、ミドルウェアへのエラーの伝搬という Node/Express エラー処理の基礎を理解しておく必要があります。Node は、非同期関数からエラーを返すために「error-first コールバック」という規則を使用します。この場合、コールバック関数への最初のパラメーターがエラー・オブジェクトで、その後に続くパラメーターに結果データがあります。エラーがないことを示すには、最初のパラメーターとして `null` を渡します。コールバック関数は、エラーを有意に処理するには、error-first コールバック規則に対応して従う必要があります。Express におけるベスト・プラクティスは、next() 関数を使用して、ミドルウェア・チェーンを介してエラーを伝搬することです。 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. エラー処理のその他の基礎については、下記を参照してください。 -* [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop ブログ) - -#### 実行してはならないこと - -実行しては*ならない* ことの 1 つは、例外がイベント・ループまでたどり着いた場合に生成される `uncaughtException` イベントを listen することです。`uncaughtException` のイベント・リスナーを追加すると、例外が発生したプロセスのデフォルトの動作が変更されます。プロセスは、例外に関係なく実行し続けます。この方法でアプリケーションの異常終了を防止できそうに思えますが、キャッチされていない例外が発生した後にアプリケーションの実行を続けるのは危険な手法であり、お勧めしません。プロセスの状態の信頼性と予測可能性が低くなるためです。 - -さらに、`uncaughtException` の使用は、正式に[粗雑なもの](https://nodejs.org/api/process.html#process_event_uncaughtexception)として認められており、これをコアから削除するための[提案](https://github.com/nodejs/node-v0.x-archive/issues/2582)が出されています。したがって、`uncaughtException` を listen するのは悪い方法です。この理由から複数のプロセスとスーパーバイザーなどの使用をお勧めしています。異常終了と再始動は、場合によってはエラーから復旧するための最も信頼できる方法となります。 - -また、[domain](https://nodejs.org/api/domain.html) の使用もお勧めしません。このモジュールは概して問題を解決しないため、推奨されていません。 +- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### Try-catch の使用 -Try-catch は、同期コードで例外をキャッチするために使用できる JavaScript 言語構造体です。Try-catch は、例えば、下記のように JSON 構文解析エラーを処理するために使用します。 - -[JSHint](http://jshint.com/) または [JSLint](http://www.jslint.com/) などのツールを使用して、[未定義変数の参照エラー](http://www.jshint.com/docs/options/#undef)などの暗黙的な例外を検出します。 +Try-catch は、同期コードで例外をキャッチするために使用できる JavaScript 言語構造体です。Try-catch は、例えば、下記のように JSON 構文解析エラーを処理するために使用します。 Use try-catch, for example, to handle JSON parsing errors as shown below. -次に、プロセスを異常終了させる可能性がある例外を処理するための Try-catch の使用例を示します。 -このミドルウェア関数は、JSON オブジェクトである「params」という照会フィールド・パラメーターを受け入れます。 +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(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -116,156 +105,124 @@ app.get('/search', (req, res) => { }) ``` -ただし、Try-catch は同期コードでのみ機能します。Node プラットフォームは主に (特に実稼働環境で) 非同期的であるため、Try-catch は多くの例外をキャッチしません。 +However, try-catch works only for synchronous code. ただし、Try-catch は同期コードでのみ機能します。Node プラットフォームは主に (特に実稼働環境で) 非同期的であるため、Try-catch は多くの例外をキャッチしません。 #### Promise の使用 -Promise は、`then()` を使用する非同期コード・ブロックのすべての例外 (明示的と暗黙的の両方) を処理します。単に、Promise チェーンの最後に `.catch(next)` を追加してください。次に例を示します。 +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -これで、非同期と同期のエラーがすべてエラー・ミドルウェアに伝搬されます。 - -ただし、注意点が 2 つあります。 - -1. すべての非同期コードが Promise を返す必要があります (エミッターを除く)。特定のライブラリーが Promise を返さない場合は、[Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html) などのヘルパー関数を使用して基本オブジェクトを変換します。 -2. イベント・エミッター (ストリームなど) により、例外がキャッチされないことがあります。そのため、必ずエラー・イベントを適切に処理してください。次に例を示します。 +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -Promise を使用するエラー処理の詳細については、下記を参照してください。 +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. + +#### 実行してはならないこと + +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. -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +さらに、`uncaughtException` の使用は、正式に[粗雑なもの](https://nodejs.org/api/process.html#process_event_uncaughtexception)として認められており、これをコアから削除するための[提案](https://github.com/nodejs/node-v0.x-archive/issues/2582)が出されています。したがって、`uncaughtException` を listen するのは悪い方法です。この理由から複数のプロセスとスーパーバイザーなどの使用をお勧めしています。異常終了と再始動は、場合によってはエラーから復旧するための最も信頼できる方法となります。 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. + +また、[domain](https://nodejs.org/api/domain.html) の使用もお勧めしません。このモジュールは概して問題を解決しないため、推奨されていません。 It generally doesn't solve the problem and is a deprecated module. ## 環境/セットアップで実行する処理 以下に、アプリケーションのパフォーマンスを向上させるためにシステム環境で実行できる処理をいくつか挙げます。 -* [NODE_ENV を「production」に設定する](#set-node_env-to-production) -* [アプリケーションが確実に自動再始動するようにする](#ensure-your-app-automatically-restarts) -* [アプリケーションをクラスターで実行する](#run-your-app-in-a-cluster) -* [要求の結果をキャッシュに入れる](#cache-request-results) -* [ロード・バランサーを使用する](#use-a-load-balancer) -* [リバース・プロキシーを使用する](#use-a-reverse-proxy) +- [Set NODE_ENV to "production"](#set-node_env-to-production) +- [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) +- [Run your app in a cluster](#run-your-app-in-a-cluster) +- [Cache request results](#cache-request-results) +- [Use a load balancer](#use-a-load-balancer) +- [Use a reverse proxy](#use-a-reverse-proxy) ### NODE_ENV を「production」に設定する -NODE_ENV 環境変数は、アプリケーションが実行される環境 (通常は開発または実稼働) を指定します。パフォーマンスを向上させるために実行できる最も単純な処理の 1 つは、NODE_ENV を「production」に設定することです。 +NODE_ENV 環境変数は、アプリケーションが実行される環境 (通常は開発または実稼働) を指定します。パフォーマンスを向上させるために実行できる最も単純な処理の 1 つは、NODE_ENV を「production」に設定することです。 One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. NODE_ENV を「production」に設定すると、Express は次のようになります。 -* ビュー・テンプレートをキャッシュに入れる。 -* CSS 拡張から生成された CSS ファイルをキャッシュに入れる。 -* 詳細度の低いエラー・メッセージを生成する。 - -[テスト](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/)により、こうすると、アプリケーション・パフォーマンスが 3 倍も高くなることが示されています。 - -環境固有のコードを作成する必要がある場合は、`process.env.NODE_ENV` を使用して NODE_ENV の値を確認できます。どの環境変数の値を確認する場合でもパフォーマンスに悪影響が及ぶため、慎重に行ってください。 +- ビュー・テンプレートをキャッシュに入れる。 +- CSS 拡張から生成された CSS ファイルをキャッシュに入れる。 +- 詳細度の低いエラー・メッセージを生成する。 -開発環境では、通常、対話式シェルで環境変数を設定します。例えば、`export` または `.bash_profile` ファイルを使用します。しかし、一般的には実動サーバーではそうしません。代わりに、OS の init システム (systemd または Upstart) を使用します。次のセクションでは、init システムの一般的な使用法について詳しく説明しています。ここで重点的に説明したのは、NODE_ENV の設定がパフォーマンスにとって極めて重要であるため (かつ簡単に実行できるため) です。 +[Tests indicate](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! -Upstart では、ジョブ・ファイルで `env` キーワードを使用します。次に例を示します。 - -```sh -# /etc/init/env.conf - env NODE_ENV=production -``` +環境固有のコードを作成する必要がある場合は、`process.env.NODE_ENV` を使用して NODE_ENV の値を確認できます。どの環境変数の値を確認する場合でもパフォーマンスに悪影響が及ぶため、慎重に行ってください。 Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. -詳細については、[Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables) を参照してください。 +開発環境では、通常、対話式シェルで環境変数を設定します。例えば、`export` または `.bash_profile` ファイルを使用します。しかし、一般的には実動サーバーではそうしません。代わりに、OS の init システム (systemd または Upstart) を使用します。次のセクションでは、init システムの一般的な使用法について詳しく説明しています。ここで重点的に説明したのは、NODE_ENV の設定がパフォーマンスにとって極めて重要であるため (かつ簡単に実行できるため) です。 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. -systemd では、unit ファイルで `Environment` ディレクティブを使用します。次に例を示します。 +systemd では、unit ファイルで `Environment` ディレクティブを使用します。次に例を示します。 For example: ```sh # /etc/systemd/system/myservice.service Environment=NODE_ENV=production ``` -詳細については、[Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html) を参照してください。 +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### アプリケーションが確実に自動再始動するようにする -実稼働環境では、アプリケーションを絶対にオフラインにしたくありません。つまり、アプリケーションが異常終了した場合も、サーバー自体が異常終了した場合も、アプリケーションが必ず再始動するようにする必要があります。いずれの事態も望ましくないことですが、現実的には以下の対策を通して両方の事態に備えておく必要があります。 +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: -* アプリケーション (および Node) が異常終了した場合にプロセス・マネージャーを使用してそれらを再始動する。 -* OS の異常終了時に、OS で提供されている init システムを使用してプロセス・マネージャーを再始動する。プロセス・マネージャーがなくても、init システムを使用することは可能です。 +- アプリケーション (および Node) が異常終了した場合にプロセス・マネージャーを使用してそれらを再始動する。 +- 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 アプリケーションは、キャッチされていない例外が発生すると、異常終了します。最初に実行する必要があることは、アプリケーションが十分にテストされていて、すべての例外を処理することを確認することです (詳細については、[例外を適切に処理する](#exceptions)を参照)。ただし、フェイルセーフ動作として、アプリケーションが異常終了した場合に確実に自動再始動するためのメカニズムを適用してください。 +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. #### プロセス・マネージャーを使用する -開発環境では、単にコマンド・ラインから `node server.js` などを使用してアプリケーションを開始しています。ただし、この方法を実稼働環境で実行すると、危険を招くことになります。アプリケーションが異常終了した場合、アプリケーションは再始動されるまでオフラインになります。アプリケーションが異常終了した場合に確実に再始動するようにするには、プロセス・マネージャーを使用します。プロセス・マネージャーは、デプロイメントを容易に行えるようにして、高可用性を実現し、アプリケーションを実行時に管理できるようにする、アプリケーションの「コンテナー」です。 +開発環境では、単にコマンド・ラインから `node server.js` などを使用してアプリケーションを開始しています。ただし、この方法を実稼働環境で実行すると、危険を招くことになります。アプリケーションが異常終了した場合、アプリケーションは再始動されるまでオフラインになります。アプリケーションが異常終了した場合に確実に再始動するようにするには、プロセス・マネージャーを使用します。プロセス・マネージャーは、デプロイメントを容易に行えるようにして、高可用性を実現し、アプリケーションを実行時に管理できるようにする、アプリケーションの「コンテナー」です。 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. アプリケーションを異常終了時に再始動することに加えて、プロセス・マネージャーでは以下が可能になります。 -* ランタイム・パフォーマンスとリソース使用量に関するインサイトを得る。 -* パフォーマンスを向上させるために設定を動的に変更する。 -* クラスタリングを制御する (StrongLoop PM および pm2)。 - -Node 向けの最も一般的なプロセス・マネージャーは次のとおりです。 - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -3 つのプロセス・マネージャーの各機能の比較については、[http://strong-pm.io/compare/](http://strong-pm.io/compare/) を参照してください。3 つすべての詳細な紹介については、[Express アプリケーション用のプロセス・マネージャー](/{{ page.lang }}/advanced/pm.html) を参照してください。 - -これらのプロセス・マネージャーのいずれかを使用すれば、時々異常終了してもアプリケーションの稼働状態を維持するのに十分です。 +- ランタイム・パフォーマンスとリソース使用量に関するインサイトを得る。 +- パフォーマンスを向上させるために設定を動的に変更する。 +- Control clustering (pm2). -ただし、StrongLoop PM には、明確に実動でのデプロイメントを対象とした機能が数多くあります。このツールを関連する StrongLoop ツールとともに使用して、以下を実行できます。 - -* アプリケーションをローカル側で作成してパッケージし、実動システムのセキュアにデプロイする。 -* 何らかの理由で異常終了したアプリケーションを自動的に再始動する。 -* クラスターをリモート側で管理する。 -* CPU プロファイルとヒープ・スナップショットを表示して、パフォーマンスを最適化し、メモリー・リークを診断する。 -* アプリケーションのパフォーマンス・メトリックを表示する。 -* Nginx ロード・バランサーの制御が統合された複数のホストに容易に拡張する。 - -下記で説明するように、init システムを使用して、StrongLoop PM をオペレーティング・システム・サービスとしてインストールすると、システムの再始動時に自動的に再始動します。そのため、アプリケーション・プロセスとクラスターの稼働が永続的に維持されます。 +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. #### init システムの使用 -次の信頼性の層は、サーバーの再始動時にアプリケーションが確実に再始動するようにすることです。システムもさまざまな理由でダウンすることがあります。サーバーが異常終了した場合にアプリケーションが確実に再始動するようにするには、OS に組み込まれている init システムを使用します。今日使用されている 2 つの主な init システムは、[systemd](https://wiki.debian.org/systemd) および [Upstart](http://upstart.ubuntu.com/) です。 +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). Express アプリケーションで init システムを使用する方法は 2 つあります。 -* プロセス・マネージャーでアプリケーションを実行し、init システムを使用してプロセス・マネージャーをサービスとしてインストールします。アプリケーションが異常終了した場合にプロセス・マネージャーが再始動して、OS の再始動時に init システムがプロセス・マネージャーを再始動します。この方法をお勧めします。 -* init システムで直接、アプリケーション (および Node) を実行します。この方法の方が単純ですが、プロセス・マネージャーを使用する場合に得られる利点は得られません。 +- 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. +- init システムで直接、アプリケーション (および Node) を実行します。この方法の方が単純ですが、プロセス・マネージャーを使用する場合に得られる利点は得られません。 This is somewhat simpler, but you don't get the additional advantages of using a process manager. ##### Systemd -Systemd は、Linux システムとサービス・マネージャーです。大半の主要な Linux ディストリビューションでは、Systemd がデフォルトの init システムとして採用されています。 +Systemd は、Linux システムとサービス・マネージャーです。大半の主要な Linux ディストリビューションでは、Systemd がデフォルトの init システムとして採用されています。 Most major Linux distributions have adopted systemd as their default init system. -Systemd サービス構成ファイルは、*unit ファイル* という名前で、ファイル名の末尾は .service です。次に、Node アプリケーションを直接管理するための unit ファイルの例を示します (太字のテキストを、ご使用のシステムとアプリケーションの値に置き換えてください)。 +Systemd サービス構成ファイルは、_unit ファイル_ という名前で、ファイル名の末尾は .service です。次に、Node アプリケーションを直接管理するための unit ファイルの例を示します (太字のテキストを、ご使用のシステムとアプリケーションの値に置き換えてください)。 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=Awesome Express App +Description= [Service] Type=simple -ExecStart=/usr/local/bin/node /projects/myapp/index.js -WorkingDirectory=/projects/myapp +ExecStart=/usr/local/bin/node +WorkingDirectory= User=nobody Group=nogroup @@ -290,144 +247,44 @@ WantedBy=multi-user.target Systemd について詳しくは、[systemd の解説 (man ページ)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html) を参照してください。 -##### Systemd サービスとしての StrongLoop PM - -StrongLoop Process Manager を Systemd サービスとして簡単にインストールできます。インストール後、サーバーが再始動すると、StrongLoop PM が自動的に再始動され、管理対象アプリケーションのすべてが再始動されます。 - -StrongLoop PM を Systemd サービスとしてインストールするには、次のようにします。 - -```sh -$ sudo sl-pm-install --systemd -``` - -次に、サービスを開始します。 - -```sh -$ sudo /usr/bin/systemctl start strong-pm -``` - -詳しくは、[Setting up a production host (StrongLoop 資料)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10) を参照してください。 - -##### Upstart - -Upstart は、多くの Linux ディストリビューションで提供されているシステム・ツールです。システム始動時にタスクとサービスを開始して、シャットダウン時にそれらを停止するほか、監視するために使用されます。Express アプリケーションまたはプロセス・マネージャーをサービスとして構成すると、Upstart が異常終了時に自動的に再始動します。 - -Upstart サービスは、ファイル名が `.conf` で終わるジョブ構成ファイル (「ジョブ」とも呼ばれます) で定義されます。次の例は、`/projects/myapp/index.js` にあるメインファイルを使用して、「myapp」というアプリケーションの「myapp」というジョブを作成する方法を示しています。 - -以下の内容で `myapp.conf` というファイルを `/etc/init/` に作成します (太字のテキストを、ご使用のシステムとアプリケーションの値に置き換えてください)。 - -```sh -# When to start the process -start on runlevel [2345] - -# When to stop the process -stop on runlevel [016] - -# Increase file descriptor limit to be able to handle more requests -limit nofile 50000 50000 - -# Use production mode -env NODE_ENV=production - -# Run as www-data -setuid www-data -setgid www-data - -# Run from inside the app dir -chdir /projects/myapp - -# The process to start -exec /usr/local/bin/node /projects/myapp/index.js - -# Restart the process if it is down -respawn - -# Limit restart attempt to 10 times within 10 seconds -respawn limit 10 10 -``` - -注: このスクリプトには、Ubuntu 12.04-14.10 でサポートされる Upstart 1.4 以降が必要です。 - -ジョブは、システムの始動時に実行されるように構成されるため、アプリケーションは、オペレーティング・システムと並行して開始され、アプリケーションの異常終了時またはシステムの停止時に自動的に再始動されます。 - -アプリケーションの自動再始動のほか、Upstart では、以下のコマンドを使用できます。 - -* `start myapp` – アプリケーションの開始 -* `restart myapp` – アプリケーションの再始動 -* `stop myapp` – アプリケーションの停止 - -Upstart について詳しくは、[Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook) を参照してください。 - -##### Upstart サービスとしての StrongLoop PM - -StrongLoop Process Manager を Upstart サービスとして簡単にインストールできます。インストール後、サーバーが再始動すると、StrongLoop PM が自動的に再始動され、管理対象アプリケーションのすべてが再始動されます。 - -StrongLoop PM を Upstart 1.4 サービスとしてインストールするには、次のようにします。 - -```sh -$ sudo sl-pm-install -``` - -次に、サービスを実行します。 - -```sh -$ sudo /sbin/initctl start strong-pm -``` - -注: Upstart 1.4 をサポートしないシステムでは、コマンドが若干異なります。詳しくは、[Setting up a production host (StrongLoop 資料)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) を参照してください。 - ### アプリケーションをクラスターで実行する -マルチコア・システムでは、プロセスのクラスターを起動することで、Node アプリケーションのパフォーマンスを数倍も向上させることができます。クラスターは、アプリケーションの複数インスタンスを実行して (理想的には CPU コアごとに 1 つのインスタンス)、負荷とタスクをインスタンス間で分散させます。 +マルチコア・システムでは、プロセスのクラスターを起動することで、Node アプリケーションのパフォーマンスを数倍も向上させることができます。クラスターは、アプリケーションの複数インスタンスを実行して (理想的には CPU コアごとに 1 つのインスタンス)、負荷とタスクをインスタンス間で分散させます。 A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. ![クラスター API を使用したアプリケーション・インスタンス間のバランシング](/images/clustering.png) -重要: アプリケーション・インスタンスは別々のインスタンスとして実行されるため、同じメモリー・スペースを共有しません。つまり、オブジェクトは、アプリケーションの各インスタンスに対してローカル側にあります。そのため、アプリケーション・コードの状態を維持できません。ただし、[Redis](http://redis.io/) などのメモリー内のデータ・ストアを使用して、セッション関連のデータと状態を保管できます。この注意点は、複数のプロセスまたは複数の物理サーバーのどちらを使用したクラスタリングでも、基本的にあらゆる形式の水平スケーリングに適用されます。 +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](http://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. -クラスター・アプリケーションでは、ワーカー・プロセスは、残りのプロセスに影響を与えることなく、個々に異常終了することがあります。パフォーマンス上の利点の他に障害分離は、アプリケーション・プロセスのクラスターを実行するもう 1 つの理由です。ワーカー・プロセスが異常終了するたびに、必ず、イベントをログに記録して、cluster.fork() を使用して新規プロセスを作成してください。 +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. クラスター・アプリケーションでは、ワーカー・プロセスは、残りのプロセスに影響を与えることなく、個々に異常終了することがあります。パフォーマンス上の利点の他に障害分離は、アプリケーション・プロセスのクラスターを実行するもう 1 つの理由です。ワーカー・プロセスが異常終了するたびに、必ず、イベントをログに記録して、cluster.fork() を使用して新規プロセスを作成してください。 #### Node のクラスター・モジュールの使用 -クラスタリングには、Node の[クラスター・モジュール](https://nodejs.org/api/cluster.html.)を使用します。このモジュールにより、マスター・プロセスは、ワーカー・プロセスを作成して、着信接続をワーカー間で分散させることができます。ただし、このモジュールを直接使用するよりも、[node-pm](https://www.npmjs.com/package/node-pm) や [cluster-service](https://www.npmjs.com/package/cluster-service) など、これらの処理を自動的に実行する多くのツールを使用する方がはるかに簡単です。 - -#### StrongLoop PM の使用 - -アプリケーションを StrongLoop Process Manager (PM) にデプロイする場合、アプリケーション・コードを変更*せずに*、クラスタリングを利用できます。 - -StrongLoop Process Manager (PM) は、アプリケーションを実行する際、システム上の CPU コアの数と等しい数のワーカーを使用するクラスターで自動的に実行します。クラスター内のワーカー・プロセスの数は、アプリケーションを停止することなく、slc コマンド・ライン・ツールを使用して手動で変更できます。 - -例えば、アプリケーションを prod.foo.com にデプロイして、StrongLoop PM がポート 8701 (デフォルト) で listen している場合は、slc を使用してクラスター・サイズを 8 に設定します。 - -```sh -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8 -``` - -StrongLoop PM を使用したクラスタリングについて詳しくは、StrongLoop 資料の [Clustering](https://docs.strongloop.com/display/SLC/Clustering) を参照してください。 +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. #### 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](http://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). +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: -```sh +```bash # Start 4 worker processes -$ pm2 start app.js -i 4 +$ pm2 start npm --name my-app -i 4 -- start # Auto-detect number of available CPUs and start that many worker processes -$ pm2 start app.js -i max +$ 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, a given application with the name `app` can be scaled like so: -```sh +```bash # Add 3 more workers -$ pm2 scale app +3 +$ pm2 scale my-app +3 # Scale to a specific number of workers -$ pm2 scale app 2 +$ 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. @@ -436,18 +293,18 @@ For more information on clustering with PM2, see [Cluster Mode](https://pm2.keym 実稼働環境のパフォーマンスを向上させるもう 1 つの戦略は、アプリケーションが同じ要求に何回も対応するために操作を繰り返すことがないように、要求の結果をキャッシュに入れることです。 -[Varnish](https://www.varnish-cache.org/) や [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) ([Nginx Caching](https://serversforhackers.com/nginx-caching/) も参照) などのキャッシュ・サーバーを使用すると、アプリケーションの速度とパフォーマンスを大幅に向上させることができます。 +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. -### ロード・バランサーを使用する +### [ロード・バランサーを使用する](#use-a-load-balancer) -アプリケーションがどれだけ最適化されていても、単一インスタンスは、限られた量の負荷とトラフィックしか処理できません。アプリケーションを拡張する 1 つの方法は、複数インスタンスを実行して、ロード・バランサーを使用してトラフィックを分散させることです。ロード・バランサーをセットアップすると、アプリケーションのパフォーマンスと速度を向上させることができ、単一インスタンスよりも大規模に拡張できます。 +アプリケーションがどれだけ最適化されていても、単一インスタンスは、限られた量の負荷とトラフィックしか処理できません。アプリケーションを拡張する 1 つの方法は、複数インスタンスを実行して、ロード・バランサーを使用してトラフィックを分散させることです。ロード・バランサーをセットアップすると、アプリケーションのパフォーマンスと速度を向上させることができ、単一インスタンスよりも大規模に拡張できます。 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. -ロード・バランサーは通常、複数のアプリケーション・インスタンスやサーバーとの間のトラフィックを調整するリバース・プロキシーです。[Nginx](http://nginx.org/en/docs/http/load_balancing.html) や [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts) を使用して、アプリケーション用にロード・バランサーを簡単にセットアップできます。 +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). -ロード・バランシングでは、特定のセッション ID に関連する要求が発信元のプロセスに接続することを確認する必要があります。これは、*セッション・アフィニティー* または*スティッキー・セッション* と呼ばれ、セッション・データに Redis などのデータ・ストアを使用する上記の提案によって対応できます (ご使用のアプリケーションによって異なります)。説明については、[Using multiple nodes](http://socket.io/docs/using-multiple-nodes/) を参照してください。 +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) -リバース・プロキシーは、Web アプリケーションの前に配置され、アプリケーションへの要求の転送とは別に、要求に対する補助操作を実行します。特に、エラー・ページ、圧縮、キャッシング、ファイル・サービス提供、ロード・バランシングを処理できます。 +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. -アプリケーションの状態を知る必要のないタスクをリバース・プロキシーに引き渡すことで、Express が解放されて、特殊なアプリケーション・タスクを実行できるようになります。この理由から、実稼働環境で Express を [Nginx](https://www.nginx.com/) や [HAProxy](http://www.haproxy.org/) などのリバース・プロキシーの背後で実行することをお勧めします。 +アプリケーションの状態を知る必要のないタスクをリバース・プロキシーに引き渡すことで、Express が解放されて、特殊なアプリケーション・タスクを実行できるようになります。この理由から、実稼働環境で Express を [Nginx](https://www.nginx.com/) や [HAProxy](http://www.haproxy.org/) などのリバース・プロキシーの背後で実行することをお勧めします。 For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/ja/advanced/best-practice-security.md b/ja/advanced/best-practice-security.md old mode 100755 new mode 100644 index 84aedf6712..37739aa555 --- a/ja/advanced/best-practice-security.md +++ b/ja/advanced/best-practice-security.md @@ -1,63 +1,113 @@ --- layout: page title: 実稼働環境における Express のセキュリティーに関するベスト・プラクティス +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: ja +redirect_from: " " --- # 実稼働環境におけるベスト・プラクティス: セキュリティー ## 概説 -「*実稼働*」という用語は、ソフトウェアのライフサイクルにおいて、アプリケーションや API をエンド・ユーザーまたはコンシューマーが広く使用できる段階を指します。対照的に、「*開発*」段階では、まだコードの作成とテストを積極的に行っていて、アプリケーションへの外部アクセスは不可能です。対応するシステム環境は、それぞれ*実稼働* 環境と*開発* 環境と呼ばれています。 +The term _"production"_ refers to the stage in the software lifecycle when an application or API is generally available to its end-users or consumers. In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively. -開発環境と実稼働環境は通常、別々にセットアップされ、それぞれの要件は大きく異なっています。開発環境では許可されることが、実稼働環境では許可されないことがあります。例えば、開発環境ではデバッグのためにエラーの詳細なロギングを実行できますが、同じ動作が実稼働環境ではセキュリティー上の問題となります。開発環境では、スケーラビリティー、信頼性、パフォーマンスについて心配する必要はありませんが、それらは実稼働環境では重大な問題となります。 +Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production. -{% include note.html content="If you believe you have discovered a security vulnerability in Express, please see [Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures)." %} +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} 本番環境でのExpressアプリケーションのセキュリティのベスト・プラクティスは次のとおりです。 -- [非推奨バージョンや脆弱なバージョンの Express を使用しない](#dont-use-deprecated-or-vulnerable-versions-of-express) -- [TLS を使用する](#use-tls) -- [Helmet を使用する](#use-helmet) -- [Cookie をセキュアに使用する](#use-cookies-securely) -- [依存関係がセキュアであることを確認する](#ensure-your-dependencies-are-secure) -- [その他の既知の脆弱性を回避する](#avoid-other-known-vulnerabilities) -- [その他の考慮事項](#additional-considerations) +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [TLS を使用する](#use-tls) + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - [Helmet を使用する](#use-helmet) + - [Reduce fingerprinting](#reduce-fingerprinting) + - [Cookie をセキュアに使用する](#use-cookies-securely) + - 対照的に、[cookie-session](https://www.npmjs.com/package/cookie-session) ミドルウェアは、Cookie が支持するストレージを実装します。セッション・キーだけでなく、セッション全体を Cookie に対して直列化します。これは、セッション・データが比較的小規模で、(オブジェクトではなく) プリミティブ値として容易にエンコードできる場合にのみ使用してください。ブラウザーは Cookie 当たり最小 4096 バイトをサポートすることが想定されますが、その制限を必ず超えないようにするために、ドメイン当たり 4093 バイトのサイズを超えないようにしてください。また、Cookie データがクライアントに対して可視になることに注意してください。何らかの理由でデータを保護したり覆い隠したりする必要がある場合は、express-session を使用することをお勧めします。 + - デフォルトのセッション Cookie 名を使用すると、アプリケーションが攻撃を受けやすくなります。提起されているセキュリティー問題は `X-Powered-By` と似ています。潜在的なアタッカーがこれを使用して、サーバーに対して指紋認証し、攻撃の標的にする可能性があります。 + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [依存関係がセキュアであることを確認する](#ensure-your-dependencies-are-secure) + - [その他の既知の脆弱性を回避する](#avoid-other-known-vulnerabilities) + - [その他の考慮事項](#additional-considerations) ## 非推奨バージョンや脆弱なバージョンの Express を使用しない -Express 2.x および 3.x は保守されなくなりました。これらのバージョンにおけるセキュリティーとパフォーマンスの問題は修正されません。これらのバージョンを決して使用しないでください。まだバージョン 4 に移行していない場合は、[マイグレーション・ガイド](/{{ page.lang }}/guide/migrating-4.html)に従ってください。 +Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html) or consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). -また、[セキュリティー更新ページ](/{{ page.lang }}/advanced/security-updates.html)にリストされている脆弱な Express バージョンを使用していないことを確認してください。使用している場合は、安定しているリリース (最新を推奨します) に更新してください。 +また、[セキュリティー更新ページ](/{{ page.lang }}/advanced/security-updates.html)にリストされている脆弱な Express バージョンを使用していないことを確認してください。使用している場合は、安定しているリリース (最新を推奨します) に更新してください。 If you are, update to one of the stable releases, preferably the latest. ## TLS を使用する -アプリケーションが機密データを処理または送信する場合は、[Transport Layer Security](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)に対して脆弱です。 +If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -Secure Socket Layer (SSL) 暗号化については理解されていると思います。[TLS は、単に SSL が進化したものです](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx)。つまり、以前に SSL を使用していた場合は、TLS へのアップグレードを検討してください。一般に、TLS を処理するために Nginx を使用することをお勧めします。Nginx (およびその他のサーバー) で TLS を構成するための解説については、[Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations) を参照してください。 +You may be familiar with Secure Socket Layer (SSL) encryption. Secure Socket Layer (SSL) 暗号化については理解されていると思います。[TLS は、単に SSL が進化したものです](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx)。つまり、以前に SSL を使用していた場合は、TLS へのアップグレードを検討してください。一般に、TLS を処理するために Nginx を使用することをお勧めします。Nginx (およびその他のサーバー) で TLS を構成するための解説については、[Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations) を参照してください。 In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). また、[Let's Encrypt](https://letsencrypt.org/about/) は、無料の TLS 証明書を取得するための便利なツールです。このツールは、[Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/) が提供する、無料の自動的かつオープンな認証局 (CA) です。 +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## Helmet を使用する [Helmet](https://www.npmjs.com/package/helmet) は、HTTP ヘッダーを適切に設定することによって、いくつかの既知の Web の脆弱性からアプリケーションを保護します。 -Helmet は、実際には、セキュリティー関連の HTTP ヘッダーを設定する 9 個の小さなミドルウェア関数の単なる集合です。 +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* [csp](https://github.com/helmetjs/csp) は、クロスサイト・スクリプティング攻撃やその他のクロスサイト・インジェクションを防止するために `Content-Security-Policy` ヘッダーを設定します。 -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) は、`X-Powered-By` ヘッダーを削除します。 -* [hsts](https://github.com/helmetjs/hsts) は、サーバーへのセキュア (SSL/TLS を介して HTTP) 接続を適用する `Strict-Transport-Security` ヘッダーを設定します。 -* [ieNoOpen](https://github.com/helmetjs/ienoopen) は、IE8+ の `X-Download-Options` を設定します。 -* [noCache](https://github.com/helmetjs/nocache) は、クライアント側のキャッシュを無効にするために `Cache-Control` ヘッダーと Pragma ヘッダーを設定します。 -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) は、宣言されているコンテンツの種類からの応答をブラウザーが MIME スニッフィングしないように、`X-Content-Type-Options` を設定します。 -* [frameguard](https://github.com/helmetjs/frameguard) は、[クリックジャッキング](https://www.owasp.org/index.php/Clickjacking)保護を有効にするために `X-Frame-Options` ヘッダーを設定します。 -* [xssFilter](https://github.com/helmetjs/x-xss-protection) は、最新の Web ブラウザーでクロスサイト・スクリプティング (XSS) フィルターを有効にするために `X-XSS-Protection` を設定します。 +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. その他のモジュールと同様に Helmet をインストールします。 -```sh -$ npm install --save helmet +```bash +$ npm install helmet ``` 次に、コードで使用します。 @@ -65,15 +115,19 @@ $ npm install --save helmet ```js // ... -var helmet = require('helmet') +const helmet = require('helmet') app.use(helmet()) // ... ``` -### 少なくとも X-Powered-By ヘッダーを無効にする +## Reduce fingerprinting -Helmet を使用しない場合は、少なくとも `X-Powered-By` ヘッダーを無効にしてください。アタッカーが、(デフォルトで有効になっている) このヘッダーを使用して、Express を実行しているアプリケーションを検出し、具体的に対象を絞った攻撃を開始する可能性があります。 +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. そのため、`app.disable()` メソッドを使用してこのヘッダーをオフにすることがベスト・プラクティスです。 @@ -81,9 +135,37 @@ Helmet を使用しない場合は、少なくとも `X-Powered-By` ヘッダー app.disable('x-powered-by') ``` -`helmet.js` を使用する場合は、この操作が自動的に実行されます。 +{% capture powered-advisory %} + +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. -{% include note.html content="Disabling the `X-Powered-By header` does not prevent a sophisticated attacker from determining that an app is running Express. It may discourage a casual exploit, but there are other ways to determine an app is running Express. "%} +{% endcapture %} + +{% include admonitions/note.html content=powered-advisory %} + +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): + +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## Cookie をセキュアに使用する @@ -91,21 +173,21 @@ Cookie を介してアプリケーションが悪用されないように、デ 主なミドルウェア Cookie セッション・モジュールが 2 つあります。 -* [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` ミドルウェアに取って代わります。 +- [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` ミドルウェアに取って代わります。 -これらの 2 つのモジュールの主な違いは、Cookie セッション・データの保存方法です。[express-session](https://www.npmjs.com/package/express-session) ミドルウェアは、セッション・データをサーバーに保管します。セッション・データではなく、Cookie 自体の中にあるセッション ID のみを保存します。デフォルトで、メモリー内のストレージを使用し、実稼働環境向けには設計されていません。実稼働環境では、スケーラブルなセッション・ストアをセットアップする必要があります。[互換性のあるセッション・ストア](https://github.com/expressjs/session#compatible-session-stores)のリストを参照してください。 +The main difference between these two modules is how they save cookie session data. これらの 2 つのモジュールの主な違いは、Cookie セッション・データの保存方法です。[express-session](https://www.npmjs.com/package/express-session) ミドルウェアは、セッション・データをサーバーに保管します。セッション・データではなく、Cookie 自体の中にあるセッション ID のみを保存します。デフォルトで、メモリー内のストレージを使用し、実稼働環境向けには設計されていません。実稼働環境では、スケーラブルなセッション・ストアをセットアップする必要があります。[互換性のあるセッション・ストア](https://github.com/expressjs/session#compatible-session-stores)のリストを参照してください。 By default, it uses in-memory storage and is not designed for a production environment. 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 バイトをサポートすることが想定されますが、その制限を必ず超えないようにするために、ドメイン当たり 4093 バイトのサイズを超えないようにしてください。また、Cookie データがクライアントに対して可視になることに注意してください。何らかの理由でデータを保護したり覆い隠したりする必要がある場合は、express-session を使用することをお勧めします。 +In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then `express-session` may be a better choice. ### デフォルトのセッション Cookie 名を使用しない -デフォルトのセッション Cookie 名を使用すると、アプリケーションが攻撃を受けやすくなります。提起されているセキュリティー問題は `X-Powered-By` と似ています。潜在的なアタッカーがこれを使用して、サーバーに対して指紋認証し、攻撃の標的にする可能性があります。 +Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. この問題を回避するには、汎用な Cookie 名を使用します。例えば、[express-session](https://www.npmjs.com/package/express-session) ミドルウェアを使用します。 ```js -var session = require('express-session') +const session = require('express-session') app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 's3Cur3', @@ -117,20 +199,20 @@ app.use(session({ セキュリティーを強化するために、以下の Cookie オプションを設定します。 -* `secure` - ブラウザーが確実に HTTPS のみを介して Cookie を送信するようにします。 -* `httpOnly` - Cookie がクライアント JavaScript ではなく、HTTP(S) のみを介して送信されるようにして、クロスサイト・スクリプティング攻撃から保護します。 -* `domain` - Cookie のドメインを指定します。URL が要求されているサーバーのドメインとの比較に使用します。一致する場合は、次にパス属性を確認します。 -* `path` - Cookie のパスを指定します。要求パスとの比較に使用します。このパスがドメインと一致する場合は、要求の Cookie を送信します。 -* `expires` - 永続的な Cookie の有効期限を設定するために使用します。 +- `secure` - ブラウザーが確実に HTTPS のみを介して Cookie を送信するようにします。 +- `httpOnly` - Cookie がクライアント JavaScript ではなく、HTTP(S) のみを介して送信されるようにして、クロスサイト・スクリプティング攻撃から保護します。 +- `domain` - Cookie のドメインを指定します。URL が要求されているサーバーのドメインとの比較に使用します。一致する場合は、次にパス属性を確認します。 If they match, then check the path attribute next. +- `path` - Cookie のパスを指定します。要求パスとの比較に使用します。このパスがドメインと一致する場合は、要求の Cookie を送信します。 If this and domain match, then send the cookie in the request. +- `expires` - 永続的な Cookie の有効期限を設定するために使用します。 次に、[cookie-session](https://www.npmjs.com/package/cookie-session) ミドルウェアの使用例を示します。 ```js -var session = require('cookie-session') -var express = require('express') -var app = express() +const session = require('cookie-session') +const express = require('express') +const app = express() -var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour app.use(session({ name: 'session', keys: ['key1', 'key2'], @@ -144,51 +226,56 @@ app.use(session({ })) ``` +## Prevent brute-force attacks against authorization + +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +1. The number of consecutive failed attempts by the same user name and IP address. +2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) + ## 依存関係がセキュアであることを確認する -npm を使用したアプリケーションの依存関係の管理は、強力で便利な方法です。ただし、使用するパッケージに、アプリケーションにも影響を与える可能性がある重大なセキュリティーの脆弱性が含まれている可能性があります。アプリケーションのセキュリティーの強さは、依存関係の中で「最も弱いリンク」程度でしかありません。 +npm を使用したアプリケーションの依存関係の管理は、強力で便利な方法です。ただし、使用するパッケージに、アプリケーションにも影響を与える可能性がある重大なセキュリティーの脆弱性が含まれている可能性があります。アプリケーションのセキュリティーの強さは、依存関係の中で「最も弱いリンク」程度でしかありません。 But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. -npm@6以降、npmはすべてのインストール要求を自動的に確認します。また、'npm audit'を使用して依存関係ツリーを分析することもできます。 +Since npm@6, npm automatically reviews every install request. npm@6以降、npmはすべてのインストール要求を自動的に確認します。また、'npm audit'を使用して依存関係ツリーを分析することもできます。 -```sh +```bash $ npm audit ``` よりセキュアな状態を保ちたい場合は、[Snyk](https://snyk.io/)を検討してください。 -Snykは、[Snykのオープンソース脆弱性データベース](https://snyk.io/vuln/)に対して、依存関係の既知の脆弱性に対するアプリケーションをチェックする[コマンドラインツール](https://www.npmjs.com/package/snyk)と[Github integration](https://snyk.io/docs/github)を提供しています。 次のようにCLIをインストールします。 +Snykは、[Snykのオープンソース脆弱性データベース](https://snyk.io/vuln/)に対して、依存関係の既知の脆弱性に対するアプリケーションをチェックする[コマンドラインツール](https://www.npmjs.com/package/snyk)と[Github integration](https://snyk.io/docs/github)を提供しています。 次のようにCLIをインストールします。 Install the CLI as follows: -```sh +```bash $ npm install -g snyk $ cd your-app ``` このコマンドを使用して、アプリケーションの脆弱性をテストします。 -```sh +```bash $ snyk test ``` -このコマンドを使用して、検出された脆弱性を修正するための更新プログラムやパッチを適用するプロセスを案内するウィザードを開きます。 +### その他の既知の脆弱性を回避する -```sh -$ snyk wizard -``` +アプリケーションで使用する Express やその他のモジュールに影響を与える可能性がある [Node Security Project](https://npmjs.com/advisories) のアドバイザリーに常に注意してください。一般に、Node Security Project は、Node のセキュリティーに関する知識とツールの優れたリソースです。 In general, these databases are excellent resources for knowledge and tools about Node security. -## その他の既知の脆弱性を回避する - -アプリケーションで使用する Express やその他のモジュールに影響を与える可能性がある [Node Security Project](https://npmjs.com/advisories) のアドバイザリーに常に注意してください。一般に、Node Security Project は、Node のセキュリティーに関する知識とツールの優れたリソースです。 - -最後に、Express アプリケーションは、その他の Web アプリケーションと同様、さまざまな Web ベースの攻撃に対して脆弱になりえます。既知の [Web の脆弱性](https://www.owasp.org/index.php/Top_10_2013-Top_10)をよく理解して、それらを回避するための予防措置を取ってください。 +最後に、Express アプリケーションは、その他の Web アプリケーションと同様、さまざまな Web ベースの攻撃に対して脆弱になりえます。既知の [Web の脆弱性](https://www.owasp.org/www-project-top-ten/)をよく理解して、それらを回避するための予防措置を取ってください。 Familiarize yourself with known [web vulnerabilities](https://www.owasp.org/www-project-top-ten/) and take precautions to avoid them. ## その他の考慮事項 -次に、優れた [Node.js セキュリティー・チェックリスト](https://blog.risingstack.com/node-js-security-checklist/)に記載されているその他の推奨事項をリストします。これらの推奨事項の詳細については、ブログの投稿を参照してください。 +次に、優れた [Node.js セキュリティー・チェックリスト](https://blog.risingstack.com/node-js-security-checklist/)に記載されているその他の推奨事項をリストします。これらの推奨事項の詳細については、ブログの投稿を参照してください。 Refer to that blog post for all the details on these recommendations: + +- クロスサイト・スクリプティング (XSS) とコマンド・インジェクション攻撃から保護するために、必ず、ユーザー入力のフィルタリングとサニタイズを実行してください。 +- パラメーター化照会または作成済みステートメントを使用して、SQL インジェクション攻撃に対して防衛してください。 +- オープン・ソースの [sqlmap](http://sqlmap.org/) ツールを使用して、アプリケーションの SQL インジェクションに対する脆弱性を検出してください。 +- [nmap](https://nmap.org/) ツールと [sslyze](https://github.com/nabla-c0d3/sslyze) ツールを使用して、SSL 暗号、鍵、再交渉の構成のほか、証明書の妥当性をテストしてください。 +- [safe-regex](https://www.npmjs.com/package/safe-regex) を使用して、使用している正規表現が[正規表現サービス妨害](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)攻撃を受けやすくなっていないことを確認してください。 -* 認証に対する総当たり攻撃を防止するために、回数制限を実装してください。そのための 1 つの方法では、[StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) を使用して回数制限ポリシーを適用します。あるいは、[express-limiter](https://www.npmjs.com/package/express-limiter) などのミドルウェアを使用できますが、そのためにはコードを若干変更する必要があります。 -* クロスサイト・リクエスト・フォージェリー (CSRF) から保護するために、[csurf](https://www.npmjs.com/package/csurf) ミドルウェアを使用してください。 -* クロスサイト・スクリプティング (XSS) とコマンド・インジェクション攻撃から保護するために、必ず、ユーザー入力のフィルタリングとサニタイズを実行してください。 -* パラメーター化照会または作成済みステートメントを使用して、SQL インジェクション攻撃に対して防衛してください。 -* オープン・ソースの [sqlmap](http://sqlmap.org/) ツールを使用して、アプリケーションの SQL インジェクションに対する脆弱性を検出してください。 -* [nmap](https://nmap.org/) ツールと [sslyze](https://github.com/nabla-c0d3/sslyze) ツールを使用して、SSL 暗号、鍵、再交渉の構成のほか、証明書の妥当性をテストしてください。 -* [safe-regex](https://www.npmjs.com/package/safe-regex) を使用して、使用している正規表現が[正規表現サービス妨害](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)攻撃を受けやすくなっていないことを確認してください。 +[helmet]: <`helmet.js` を使用する場合は、この操作が自動的に実行されます。> \ No newline at end of file diff --git a/ja/advanced/developing-template-engines.md b/ja/advanced/developing-template-engines.md old mode 100755 new mode 100644 index b890555b42..41cc517423 --- a/ja/advanced/developing-template-engines.md +++ b/ja/advanced/developing-template-engines.md @@ -1,24 +1,26 @@ --- layout: page title: Express 用のテンプレート・エンジンの開発 +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: ja +redirect_from: " " --- # Express 用のテンプレート・エンジンの開発 -独自のテンプレート・エンジンを作成するには、`app.engine(ext, callback)` メソッドを使用します。`ext` はファイル拡張子を表し、`callback` はテンプレート・エンジン関数です。この関数は、ファイルのロケーション、options オブジェクト、およびコールバック関数の項目をパラメーターとして受け入れます。 +独自のテンプレート・エンジンを作成するには、`app.engine(ext, callback)` メソッドを使用します。`ext` はファイル拡張子を表し、`callback` はテンプレート・エンジン関数です。この関数は、ファイルのロケーション、options オブジェクト、およびコールバック関数の項目をパラメーターとして受け入れます。 `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. 次のコードは、`.ntl` ファイルをレンダリングするための極めて単純なテンプレート・エンジンを実装する例です。 ```js -var fs = require('fs') // this engine requires the fs module -app.engine('ntl', function (filePath, options, callback) { // define the template engine - fs.readFile(filePath, function (err, content) { +const fs = require('fs') // this engine requires the fs module +app.engine('ntl', (filePath, options, callback) => { // define the template engine + fs.readFile(filePath, (err, content) => { if (err) return callback(err) // this is an extremely simple template engine - var rendered = content.toString().replace('#title#', '' + options.title + '') - .replace('#message#', '

    ' + options.message + '

    ') + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

    ${options.message}

    `) return callback(null, rendered) }) }) @@ -26,17 +28,19 @@ app.set('views', './views') // specify the views directory app.set('view engine', 'ntl') // register the template engine ``` -これで、アプリケーションは `.ntl` ファイルをレンダリングできるようになります。以下のコンテンツで `index.ntl` というファイルを `views` ディレクトリーに作成します。 +Your app will now be able to render `.ntl` files. これで、アプリケーションは `.ntl` ファイルをレンダリングできるようになります。以下のコンテンツで `index.ntl` というファイルを `views` ディレクトリーに作成します。 -```text +```pug #title# #message# ``` + 次に、アプリケーションで次のルートを作成します。 ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index', { title: 'Hey', message: 'Hello there!' }) }) ``` -ホーム・ページに要求すると、`index.ntl` ファイルは HTML としてレンダリングされます。 + +ホーム・ページに要求すると、`index.ntl` ファイルは HTML としてレンダリングされます。 \ No newline at end of file diff --git a/ja/advanced/healthcheck-graceful-shutdown.md b/ja/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..e5c452cad7 --- /dev/null +++ b/ja/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/ja/advanced/pm.md b/ja/advanced/pm.md deleted file mode 100755 index cee3066d68..0000000000 --- a/ja/advanced/pm.md +++ /dev/null @@ -1,292 +0,0 @@ ---- -layout: page -title: Express アプリケーション用のプロセス・マネージャー -menu: advanced -lang: ja ---- - -# Express アプリケーション用のプロセス・マネージャー - -Express アプリケーションを実動で実行する際、以下のタスクを実行するために*プロセス・マネージャー* を使用すると便利です。 - -- アプリケーションが異常終了した場合に自動的に再始動する。 -- ランタイム・パフォーマンスとリソース使用量に関するインサイトを得る。 -- パフォーマンスを向上させるために設定を動的に変更する。 -- クラスタリングを制御する。 - -プロセス・マネージャーは、アプリケーション・サーバーに似ていて、デプロイメントを容易に行えるようにして、高可用性を実現し、アプリケーションを実行時に管理できるようにする、アプリケーションの「コンテナー」です。 - -Express およびその他の Node.js アプリケーション用の最も一般的なプロセス・マネージャーは次のとおりです。 - -- [Forever](#forever) -- [PM2](#pm2) -- [StrongLoop Process Manager](#strongloop-process-manager) -- [SystemD](#systemd) - - -上記の 4 つのツールのいずれを使用しても非常に役立ちますが、StrongLoop Process Manager は、Node.js アプリケーションのライフサイクル全体に対応した包括的な実行時とデプロイメントのソリューションを提供する唯一のツールであり、実動前と実動後のすべてのステップに関するツールを統合インターフェースで提供します。 - -以下に、これらの各ツールについて簡単に説明します。 -詳細な比較については、[http://strong-pm.io/compare/](http://strong-pm.io/compare/) を参照してください。 - -## Forever - -Forever は、特定のスクリプトが確実に継続的 (永続的) に実行されるようにするための単純なコマンド・ライン・インターフェース・ツールです。Forever のインターフェースは単純であるため、Node.js アプリケーションおよびスクリプトの小規模なデプロイメントを実行するのに理想的です。 - -詳細については、[https://github.com/foreverjs/forever](https://github.com/foreverjs/forever) を参照してください。 - -### インストール - -```sh -$ [sudo] npm install forever -g -``` - -### 基本的な使用法 - -スクリプトを開始するには、次のように `forever start` コマンドを使用して、スクリプトのパスを指定します。 - -```sh -$ forever start script.js -``` - -このコマンドは、スクリプトをデーモン・モード (バックグラウンド) で実行します。 - -端末に接続されるようにスクリプトを実行するには、次のように `start` を省略します。 - -```sh -$ forever script.js -``` - -次の例に示すように、ロギング・オプション `-l`、`-o`、および `-e` を使用して Forever ツールおよびスクリプトの出力をログに記録することをお勧めします。 - -```sh -$ forever start -l forever.log -o out.log -e err.log script.js -``` - -Forever によって開始されたスクリプトのリストを表示するには、次のようにします。 - -```sh -$ forever list -``` - -Forever によって開始されたスクリプトを停止するには、`forever stop` コマンドを使用して、プロセス索引 (`forever list` コマンドによってリストされます) を指定します。 - -```sh -$ forever stop 1 -``` - -あるいは、次のようにファイルのパスを指定します。 - -```sh -$ forever stop script.js -``` - -Forever によって開始されたすべてのスクリプトを停止するには、次のようにします。 - -```sh -$ forever stopall -``` - -Forever には、さらに多くのオプションがあり、プログラマチック API もあります。 - -## PM2 - -PM2 は、ロード・バランサーが組み込まれた、Node.js アプリケーション用の実動プロセス・マネージャーです。PM2 では、アプリケーションの稼働を永続的に維持して、ダウン時間を発生させずに再ロードすることができ、共通のシステム管理タスクを簡単に実行できます。PM2 では、アプリケーションのロギング、モニター、クラスタリングを管理することもできます。 - -詳細については、[https://github.com/Unitech/pm2](https://github.com/Unitech/pm2) を参照してください。 - -### インストール - -```sh -$ [sudo] npm install pm2 -g -``` - -### 基本的な使用法 - -`pm2` コマンドを使用してアプリケーションを開始する場合、アプリケーションのパスを指定する必要があります。ただし、アプリケーションの停止、再始動、または削除を行う場合は、アプリケーションの名前または ID を指定するだけで済みます。 - -```sh -$ pm2 start npm --name my-app -- start -[PM2] restartProcessId process id 0 -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐ -│ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤ -│ my-app │ 0 │ fork │ 64029 │ online │ 1 │ 0s │ 17.816 MB │ disabled │ -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘ - Use the `pm2 show ` command to get more details about an app. -``` - -`pm2` コマンドを使用してアプリケーションを開始する場合、アプリケーションは即時にバックグラウンドに送信されます。さまざまな `pm2` コマンドを使用して、コマンド・ラインからバックグラウンド・アプリケーションを制御できます。 - -`pm2` コマンドを使用してアプリケーションが開始された後、アプリケーションはID を使用して PM2 のプロセス・リストに登録されます。そのため、システム上の別のディレクトリーからID を使用して同じ名前を持つアプリケーションを管理できます。 - -同じ名前を持つ複数のアプリケーションが実行されている場合、`pm2` コマンドがすべてのアプリケーションに影響を与えることに注意してください。そのため、個々のアプリケーションを管理するには、名前ではなく ID を使用してください。 - -実行中のプロセスをすべてリストするには、次のようにします。 - -```sh -$ pm2 list -``` - -アプリケーションを停止するには、次のようにします。 - -```sh -$ pm2 stop 0 -``` - -アプリケーションを再始動するには、次のようにします。 - -```sh -$ pm2 restart 0 -``` - -アプリケーションに関する詳細情報を表示するには、次のようにします。 - -```sh -$ pm2 show 0 -``` - -アプリケーションを PM2 のレジストリーから削除するには、次のようにします。 - -```sh -$ pm2 delete 0 -``` - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) は、Node.js アプリケーション用の実動プロセス・マネージャーです。StrongLoop PM には、ロード・バランシング、モニター、マルチホスト・デプロイメント、およびグラフィカル・コンソールが組み込まれています。 -StrongLoop PM は、以下のタスクに使用できます。 - -- Node.js アプリケーションを作成してパッケージし、ローカル・システムまたはリモート・システムにデプロイする。 -- CPU プロファイルとヒープ・スナップショットを表示して、パフォーマンスを最適化し、メモリー・リークを診断する。 -- プロセスとクラスターの稼働を永続的に維持する。 -- アプリケーションのパフォーマンス・メトリックを表示する。 -- Nginx が統合されたマルチホスト・デプロイメントを容易に管理する。 -- 複数の StrongLoop PM を、Arc から管理される分散マイクロサービス・ランタイムに統合する。 - -StrongLoop PM で作業するには、`slc` という強力なコマンド・ライン・インターフェース、または Arc というグラフィカル・ツールを使用します。Arc は、オープン・ソースであり、StrongLoop によって専門的なサポートが提供されます。 - -詳細については、[http://strong-pm.io/](http://strong-pm.io/) を参照してください。 - -詳細な説明: - -- [Operating Node apps (StrongLoop 資料)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### インストール -```sh -$ [sudo] npm install -g strongloop -``` - -### 基本的な使用法 -```sh -$ cd my-app -$ slc start -``` - -プロセス・マネージャーとすべてのデプロイ済みアプリケーションを表示するには、次のようにします。 - -```sh -$ slc ctl -Service ID: 1 -Service Name: my-app -Environment variables: - No environment variables defined -Instances: - Version Agent version Cluster size - 4.1.13 1.5.14 4 -Processes: - ID PID WID Listening Ports Tracking objects? CPU profiling? - 1.1.57692 57692 0 - 1.1.57693 57693 1 0.0.0.0:3001 - 1.1.57694 57694 2 0.0.0.0:3001 - 1.1.57695 57695 3 0.0.0.0:3001 - 1.1.57696 57696 4 0.0.0.0:3001 -``` - -すべての管理対象アプリケーション (サービス) をリストするには、次のようにします。 - -```sh -$ slc ctl ls -Id Name Scale - 1 my-app 1 -``` - -アプリケーションを停止するには、次のようにします。 - -```sh -$ slc ctl stop my-app -``` - -アプリケーションを再始動するには、次のようにします。 - -```sh -$ slc ctl restart my-app -``` - -「ソフト再始動」も実行できます。実行するとワーカー・プロセスに既存の接続をクローズするための猶予期間を与えた後で、現行のアプリケーションが再始動されます。 - -```sh -$ slc ctl soft-restart my-app -``` - -アプリケーションを管理対象から削除するには、次のようにします。 - -```sh -$ slc ctl remove my-app -``` -## SystemD - -### イントロダクション - -SystemDは現代のLinuxディストリビューションにおける、デフォルトのプロセスマネージャです。SystemDに基づいたノードサービスの実行は非常に簡単です。注:このセクションは、[Ralph Slooten(@axllent) のブログ記事](https://www.axllent.org/docs/view/nodejs-service-with-systemd/)に基づいています。 - -### serviceのセットアップ - -Create a file in `/etc/systemd/system/express.service`: - -```sh -[Unit] -Description=Express -# Set dependencies to other services (optional) -#After=mongodb.service - -[Service] -# Run Grunt before starting the server (optional) -#ExecStartPre=/usr/bin/grunt - -# Start the js-file starting the express server -ExecStart=/usr/bin/node server.js -WorkingDirectory=/usr/local/express -Restart=always -RestartSec=10 -StandardOutput=syslog -StandardError=syslog -SyslogIdentifier=Express -# Change to a non-root user (optional, but recommended) -#User= -#Group= -# Set environment options -Environment=NODE_ENV=production PORT=8080 - -[Install] -WantedBy=multi-user.target -``` - -### serviceの有効化 - -```sh -$ systemctl enable express.service -``` - -### serviceの起動 - -```sh -$ systemctl start express.service -``` - -### serviceのステータスのチェック - -```sh -$ systemctl status express.service -``` diff --git a/ja/advanced/security-updates.md b/ja/advanced/security-updates.md old mode 100755 new mode 100644 index 94bbae8332..d791a746e4 --- a/ja/advanced/security-updates.md +++ b/ja/advanced/security-updates.md @@ -1,67 +1,87 @@ --- layout: page title: Express のセキュリティー更新 +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: ja +redirect_from: " " --- # セキュリティー更新
    - -Node.js の脆弱性は Express に直接影響を与えます。そのため、[Node.js の脆弱性の監視を続けて](http://blog.nodejs.org/vulnerability/)、必ず、安定した最新バージョンの Node.js を使用してください。 - +Node.js の脆弱性は Express に直接影響を与えます。そのため、[Node.js の脆弱性の監視を続けて](https://nodejs.org +/en/blog/vulnerability/)、必ず、安定した最新バージョンの Node.js を使用してください。 Therefore, [keep a watch on Node.js vulnerabilities](https://nodejs.org/en/blog/vulnerability/) and make sure you are using the latest stable version of Node.js.
    次のリストに、示されているバージョンの更新で修正された Express の脆弱性を列挙します。 -**注意**: Expressでセキュリティ上の脆弱性を発見したと思われる場合は、[セキュリティポリシーと手順](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures)を参照してください。 +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} ## 4.x - * 4.16.0 - * 依存関係`forwarded`は、[脆弱性](https://npmjs.com/advisories/527)に対処するために更新されました。これは、`req.host`、`req.hostname`、`req.ip`、`req.ips`、`req.protocol`のAPIが使用されている場合、アプリケーションに影響を与える可能性があります。 - * 依存関係`mime`は[脆弱性](https://npmjs.com/advisories/535)に対処するために更新されましたが、この問題は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 - * 依存関係`debug`は[脆弱性](https://snyk.io/vuln/npm:debug:20170905)に対処するために更新されましたが、この問題はExpressには影響しません。 - * 依存関係`fresh`は、[脆弱性](https://npmjs.com/advisories/526)に対処するために更新されました。これは、次のAPIが使用されている場合、アプリケーションに影響します:`express.static`、`req.fresh`、`res.json`、`res.jsonp`、`res.send`、`res.sendfile`、`res.sendFile`、`res.sendStatus` - * 4.15.3 - * 依存関係`ms`は、[脆弱性](https://snyk.io/vuln/npm:ms:20170412)に対処するために更新されました。`express.static`、`res.sendfile`、および`res.sendFile`のAPIで、信頼できない文字列が入力され`maxAge`オプションに渡されると、アプリケーションに影響を与える可能性があります。 - * 4.15.2 - * 依存関係`qs`は[脆弱性](https://snyk.io/vuln/npm:qs:20170213)に対処するために更新されましたが、この問題はExpressには影響しません。4.15.2へのアップデートは良い習慣ですが、この脆弱性に対処する必要はありません。 - * 4.11.1 - * `express.static`、`res.sendfile`、および `res.sendFile` のルート・パス開示の脆弱性を修正しました。 - * 4.10.7 - * `express.static` のオープン・リダイレクトの脆弱性を修正しました ([アドバイザリー](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))。 - * 4.8.8 - * `express.static` のディレクトリー・トラバーサルの脆弱性を修正しました ([アドバイザリー](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` エラーが発生したり、サーバーが応答しなくなったりする可能性があります。 - * 4.8.0 - * クエリストリングに極めて多数の索引が含まれる疎な配列により、プロセスがメモリー不足になり、サーバーが異常終了する可能性があります。 - * 過度にネストされたクエリストリング・オブジェクトにより、プロセスがサーバーをブロックして、サーバーが一時的に応答できなくなる可能性があります。 +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). 依存関係`forwarded`は、[脆弱性](https://npmjs.com/advisories/527)に対処するために更新されました。これは、`req.host`、`req.hostname`、`req.ip`、`req.ips`、`req.protocol`のAPIが使用されている場合、アプリケーションに影響を与える可能性があります。 + - 依存関係`mime`は[脆弱性](https://npmjs.com/advisories/535)に対処するために更新されましたが、この問題はExpressには影響しません。 + - 依存関係`send`が更新され、[Node.js 8.5.0の脆弱性](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/)に対する保護が提供されています。これは特定のNode.jsバージョン8.5.0でExpressを実行する場合にのみ影響します。 This only impacts running Express on the specific Node.js version 8.5.0. +- 4.15.5 + - 依存関係`debug`は[脆弱性](https://snyk.io/vuln/npm:debug:20170905)に対処するために更新されましたが、この問題はExpressには影響しません。 + - The dependency `fresh` has been updated to address a [vulnerability](https://npmjs.com/advisories/526). 依存関係`fresh`は、[脆弱性](https://npmjs.com/advisories/526)に対処するために更新されました。これは、次のAPIが使用されている場合、アプリケーションに影響します:`express.static`、`req.fresh`、`res.json`、`res.jsonp`、`res.send`、`res.sendfile`、`res.sendFile`、`res.sendStatus` +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). 依存関係`ms`は、[脆弱性](https://snyk.io/vuln/npm:ms:20170412)に対処するために更新されました。`express.static`、`res.sendfile`、および`res.sendFile`のAPIで、信頼できない文字列が入力され`maxAge`オプションに渡されると、アプリケーションに影響を与える可能性があります。 +- 4.15.2 + - 依存関係`qs`は[脆弱性](https://snyk.io/vuln/npm:qs:20170213)に対処するために更新されましたが、この問題はExpressには影響しません。4.15.2へのアップデートは良い習慣ですが、この脆弱性に対処する必要はありません。 Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - `express.static`、`res.sendfile`、および `res.sendFile` のルート・パス開示の脆弱性を修正しました。 +- 4.10.7 + - `express.static` のオープン・リダイレクトの脆弱性を修正しました ([アドバイザリー](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))。 +- 4.8.8 + - `express.static` のディレクトリー・トラバーサルの脆弱性を修正しました ([アドバイザリー](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` エラーが発生したり、サーバーが応答しなくなったりする可能性があります。 Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. +- 4.8.0 + - クエリストリングに極めて多数の索引が含まれる疎配列により、プロセスがメモリー不足になり、サーバーが異常終了する可能性があります。 + - 過度にネストされたクエリストリング・オブジェクトにより、プロセスがサーバーをブロックして、サーバーが一時的に応答できなくなる可能性があります。 ## 3.x
    + **Express 3.x は保守されなくなりました** - **Express 3.x はもうメンテナンスされていません** +3.xの既知および未知のセキュリティ問題は、最終更新(2015年8月1日)以降は対処されていません。3.x系を使用することは安全であると見なされるべきではありません。 It is highly recommended to use the latest version of Express. - 3.xの既知および未知のセキュリティ問題は、最終更新(2015年8月1日)以降は対処されていません。3.x系を使用することは安全であると見なされるべきではありません。 +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options).
    - * 3.19.1 - * `express.static`、`res.sendfile`、および `res.sendFile` のルート・パス開示の脆弱性を修正しました。 - * 3.19.0 - * `express.static` のオープン・リダイレクトの脆弱性を修正しました ([アドバイザリー](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))。 - * 3.16.10 - * `express.static` のディレクトリー・トラバーサルの脆弱性を修正しました。 - * 3.16.6 - * Node.js 0.10 は、特定の状況で `fd` をリークして、`express.static` および `res.sendfile` に影響を及ぼす可能性があります。悪意ある要求によって `fd` がリークされ、最終的に `EMFILE` エラーが発生したり、サーバーが応答しなくなったりする可能性があります。 - * 3.16.0 - * クエリストリングに極めて多数の索引が含まれる疎配列により、プロセスがメモリー不足になり、サーバーが異常終了する可能性があります。 - * 過度にネストされたクエリストリング・オブジェクトにより、プロセスがサーバーをブロックして、サーバーが一時的に応答できなくなる可能性があります。 - * 3.3.0 - * サポートされていないメソッドのオーバーライドの 404 応答は、クロスサイト・スクリプティングの攻撃を受ける可能性がありました。 +- 3.19.1 + - `express.static`、`res.sendfile`、および `res.sendFile` のルート・パス開示の脆弱性を修正しました。 +- 3.19.0 + - `express.static` のオープン・リダイレクトの脆弱性を修正しました ([アドバイザリー](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))。 +- 3.16.10 + - `express.static` のディレクトリー・トラバーサルの脆弱性を修正しました。 +- 3.16.6 + - Node.js 0.10 は、特定の状況で `fd` をリークして、`express.static` および `res.sendfile` に影響を及ぼす可能性があります。悪意ある要求によって `fd` がリークされ、最終的に `EMFILE` エラーが発生したり、サーバーが応答しなくなったりする可能性があります。 Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. +- 3.16.0 + - クエリストリングに極めて多数の索引が含まれる疎な配列により、プロセスがメモリー不足になり、サーバーが異常終了する可能性があります。 + - 過度にネストされたクエリストリング・オブジェクトにより、プロセスがサーバーをブロックして、サーバーが一時的に応答できなくなる可能性があります。 +- 3.3.0 + - サポートされていないメソッドのオーバーライドの 404 応答は、クロスサイト・スクリプティングの攻撃を受ける可能性がありました。 \ No newline at end of file diff --git a/ja/api.md b/ja/api.md old mode 100755 new mode 100644 index 9073f797c4..204151e989 --- a/ja/api.md +++ b/ja/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - API リファレンス -lang: ja +layout: api +version: 5x +title: Express 5.x - API リファレンス +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api +redirect_from: " " --- -
    - -

    4.x API

    - - - {% include api/en/4x/express.md %} +
    +

    5.x API

    + {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
    diff --git a/ja/changelog/index.md b/ja/changelog/index.md new file mode 100644 index 0000000000..42d115dac2 --- /dev/null +++ b/ja/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). 依存関係`forwarded`は、[脆弱性](https://npmjs.com/advisories/527)に対処するために更新されました。これは、`req.host`、`req.hostname`、`req.ip`、`req.ips`、`req.protocol`のAPIが使用されている場合、アプリケーションに影響を与える可能性があります。 +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). 依存関係`fresh`は、[脆弱性](https://npmjs.com/advisories/526)に対処するために更新されました。これは、次のAPIが使用されている場合、アプリケーションに影響します:`express.static`、`req.fresh`、`res.json`、`res.jsonp`、`res.send`、`res.sendfile`、`res.sendFile`、`res.sendStatus` +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). 依存関係`ms`は、[脆弱性](https://snyk.io/vuln/npm:ms:20170412)に対処するために更新されました。`express.static`、`res.sendfile`、および`res.sendFile`のAPIで、信頼できない文字列が入力され`maxAge`オプションに渡されると、アプリケーションに影響を与える可能性があります。 +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/ja/guide/behind-proxies.md b/ja/guide/behind-proxies.md old mode 100755 new mode 100644 index b46c51936c..c8309ce094 --- a/ja/guide/behind-proxies.md +++ b/ja/guide/behind-proxies.md @@ -1,42 +1,43 @@ --- layout: page title: プロキシーの背後の Express +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: ja +redirect_from: " " --- # プロキシーの背後の Express -Express アプリケーションをプロキシーの背後で実行する場合、([app.set()](/{{ page.lang }}/4x/api.html#app.set) を使用して) アプリケーション変数 `trust proxy` を次の表にリストされているいずれかの値に設定します。 +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
    - -アプリケーション変数 `trust proxy` が設定されていない場合でもアプリケーションの実行は失敗しませんが、`trust proxy` が構成されていない限り、プロキシーの IP アドレスを誤ってクライアント IP アドレスとして登録します。 - +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
    +The application setting `trust proxy` may be set to one of the values listed in the following table. + - - + - + - +
    真偽値 + Boolean`true` の場合、クライアントの IP アドレスは、`X-Forwarded-*` ヘッダーの左端の項目として理解されます。 -`true` の場合、クライアントの IP アドレスは、`X-Forwarded-*` ヘッダーの左端の項目として理解されます。 - -`false` の場合、アプリケーションはインターネットに直接接続されているものとして理解され、クライアントの IP アドレスは `req.connection.remoteAddress` から導き出されます。これはデフォルトの設定値です。 +`false` の場合、アプリケーションはインターネットに直接接続されているものとして理解され、クライアントの IP アドレスは `req.connection.remoteAddress` から導き出されます。これはデフォルトの設定値です。 This is the default setting. +
    +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
    IP アドレスIP addresses +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: -信頼される IP アドレス、サブネット、または IP アドレスとサブネットの配列。次のリストに、事前構成されたサブネット名を示します。 - -* loopback - `127.0.0.1/8`、`::1/128` -* linklocal - `169.254.0.0/16`、`fe80::/10` -* uniquelocal - `10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16`、`fc00::/7` +- loopback - `127.0.0.1/8`、`::1/128` +- linklocal - `169.254.0.0/16`、`fe80::/10` +- uniquelocal - `10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16`、`fc00::/7` 以下のどの方法でも IP アドレスを設定できます。 @@ -47,24 +48,27 @@ app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple s app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array ``` -IP アドレスまたはサブネットは、指定されると、アドレス決定プロセスから除外されます。アプリケーション・サーバーに最も近い信頼できない IP アドレスがクライアントの IP アドレスに決定されます。 +IP アドレスまたはサブネットは、指定されると、アドレス決定プロセスから除外されます。アプリケーション・サーバーに最も近い信頼できない IP アドレスがクライアントの IP アドレスに決定されます。 This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. +
    数字 +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. -プロキシー・サーバーから `n` 番目のホップをクライアントとして信頼します。 - +
    +When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
    関数Function -カスタムの信頼実装。実行内容を理解している場合にのみ、これを使用してください。 +Custom trust implementation. ```js -app.set('trust proxy', function (ip) { +app.set('trust proxy', (ip) => { if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs else return false }) @@ -78,19 +82,10 @@ app.set('trust proxy', function (ip) { `trust proxy`を有効にすると、次の3つの重要な変更が起こります。
      -
    • - - [req.hostname](/{{ page.lang }}/api.html#req.hostname) の値は、クライアントまたはプロキシーが設定できる `X-Forwarded-Host` ヘッダーに設定された値から導き出されます。 -
    • -
    • - - `X-Forwarded-Proto` は、`https` と `http` のどちらであるか、または無効な名前であるかをアプリケーションに通知するためにリバース・プロキシーによって設定できます。この値は、[req.protocol](/{{ page.lang }}/api.html#req.protocol) に反映されます。 -
    • -
    • - - [req.ip](/{{ page.lang }}/api.html#req.ip) および [req.ips](/{{ page.lang }}/api.html#req.ips) の値は、`X-Forwarded-For` のアドレス・リストから取り込まれます。 +
    • [req.hostname](/{{ page.lang }}/api.html#req.hostname) の値は、クライアントまたはプロキシーが設定できる `X-Forwarded-Host` ヘッダーに設定された値から導き出されます。
    • +
    • `X-Forwarded-Proto` は、`https` と `http` のどちらであるか、または無効な名前であるかをアプリケーションに通知するためにリバース・プロキシーによって設定できます。この値は、[req.protocol](/{{ page.lang }}/api.html#req.protocol) に反映されます。 This value is reflected by [req.protocol](/{{ page.lang }}/api.html#req.protocol).
    • +
    • [req.ip](/{{ page.lang }}/api.html#req.ip) および [req.ips](/{{ page.lang }}/api.html#req.ips) の値は、`X-Forwarded-For` のアドレス・リストから取り込まれます。
    -`trust proxy` 設定は、[proxy-addr](https://www.npmjs.com/package/proxy-addr) パッケージを使用して実装されます。詳細については、資料を参照してください。 - +`trust proxy` 設定は、[proxy-addr](https://www.npmjs.com/package/proxy-addr) パッケージを使用して実装されます。詳細については、資料を参照してください。 For more information, see its documentation. diff --git a/ja/guide/database-integration.md b/ja/guide/database-integration.md old mode 100755 new mode 100644 index 854b254c83..e5f3885f00 --- a/ja/guide/database-integration.md +++ b/ja/guide/database-integration.md @@ -1,51 +1,51 @@ --- layout: page title: Express でのデータベースの統合 +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: ja +redirect_from: " " --- # データベースの統合 -データベースを Express アプリケーションに接続できるようにするには、単にデータベースに適切な Node.js ドライバーをアプリケーションにロードするだけですみます。本書では、データベース・システム用の最も一般的な Node.js モジュールを Express アプリケーションに追加して使用する方法について簡単に説明します。 - -* [Cassandra](#cassandra) -* [Couchbase](#couchbase) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongodb) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgresql) -* [Redis](#redis) -* [SQL Server](#sql-server) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app: + +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongodb) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgresql) +- [Redis](#redis) +- [SQL Server](#sql-server) +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
    - -上記は、使用可能な多数のデータベース・ドライバーの一部です。その他のオプションについては、[npm](https://www.npmjs.com/) サイトで検索してください。 - +These database drivers are among many that are available. For other options, +search on the [npm](https://www.npmjs.com/) site.
    ## Cassandra **モジュール**: [cassandra-driver](https://github.com/datastax/nodejs-driver) -**インストール** +### **インストール** -```sh +```bash $ npm install cassandra-driver ``` ### 例 ```js -var cassandra = require('cassandra-driver') -var client = new cassandra.Client({ contactPoints: ['localhost'] }) +const cassandra = require('cassandra-driver') +const client = new cassandra.Client({ contactPoints: ['localhost'] }) -client.execute('select key from system.local', function (err, result) { +client.execute('select key from system.local', (err, result) => { if (err) throw err console.log(result.rows[0]) }) @@ -55,20 +55,20 @@ client.execute('select key from system.local', function (err, result) { **Module**: [couchnode](https://github.com/couchbase/couchnode) -### インストール +### **インストール** -```sh +```bash $ npm install couchbase ``` ### 例 ```js -var couchbase = require('couchbase') -var bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') // add a document to a bucket -bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, result) { +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { if (err) { console.log(err) } else { @@ -77,9 +77,9 @@ bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, res }) // get all documents with shoe size 13 -var n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' -var query = N1qlQuery.fromString(n1ql) -bucket.query(query, [13], function (err, result) { +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { if (err) { console.log(err) } else { @@ -92,21 +92,21 @@ bucket.query(query, [13], function (err, result) { **モジュール**: [nano](https://github.com/dscape/nano) -**インストール** +### **インストール** -```sh +```bash $ npm install nano ``` ### 例 ```js -var nano = require('nano')('http://localhost:5984') +const nano = require('nano')('http://localhost:5984') nano.db.create('books') -var books = nano.db.use('books') +const books = nano.db.use('books') // Insert a book document in the books database -books.insert({ name: 'The Art of war' }, null, function (err, body) { +books.insert({ name: 'The Art of war' }, null, (err, body) => { if (err) { console.log(err) } else { @@ -115,7 +115,7 @@ books.insert({ name: 'The Art of war' }, null, function (err, body) { }) // Get a list of all books -books.list(function (err, body) { +books.list((err, body) => { if (err) { console.log(err) } else { @@ -128,25 +128,25 @@ books.list(function (err, body) { **モジュール**: [levelup](https://github.com/rvagg/node-levelup) -### インストール +### **インストール** -```sh +```bash $ npm install level levelup leveldown ``` ### 例 ```js -var levelup = require('levelup') -var db = levelup('./mydb') +const levelup = require('levelup') +const db = levelup('./mydb') -db.put('name', 'LevelUP', function (err) { +db.put('name', 'LevelUP', (err) => { if (err) return console.log('Ooops!', err) - db.get('name', function (err, value) { + db.get('name', (err, value) => { if (err) return console.log('Ooops!', err) - console.log('name=' + value) + console.log(`name=${value}`) }) }) ``` @@ -155,17 +155,17 @@ db.put('name', 'LevelUP', function (err) { **モジュール**: [mysql](https://github.com/felixge/node-mysql/) -### インストール +### **インストール** -```sh +```bash $ npm install mysql ``` ### 例 ```js -var mysql = require('mysql') -var connection = mysql.createConnection({ +const mysql = require('mysql') +const connection = mysql.createConnection({ host: 'localhost', user: 'dbuser', password: 's3kreee7', @@ -174,7 +174,7 @@ var connection = mysql.createConnection({ connection.connect() -connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) { +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => { if (err) throw err console.log('The solution is: ', rows[0].solution) @@ -187,21 +187,21 @@ connection.end() **モジュール**: [mongodb](https://github.com/mongodb/node-mongodb-native) -**インストール** +### **インストール** -```sh +```bash $ npm install mongodb ``` -### 例 (v2.*) +### 例 (v3.\*) ```js -var MongoClient = require('mongodb').MongoClient +const MongoClient = require('mongodb').MongoClient -MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { if (err) throw err - db.collection('mammals').find().toArray(function (err, result) { + db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) @@ -209,17 +209,17 @@ MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { }) ``` -### 例 (v3.*) +### 例 (v2.\*) ```js -var MongoClient = require('mongodb').MongoClient +const MongoClient = require('mongodb').MongoClient -MongoClient.connect('mongodb://localhost:27017/animals', function (err, client) { +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { if (err) throw err - var db = client.db('animals') + const db = client.db('animals') - db.collection('mammals').find().toArray(function (err, result) { + db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) @@ -231,38 +231,42 @@ MongoDB 用のオブジェクト・モデル・ドライバーが必要な場合 ## Neo4j -**モジュール**: [apoc](https://github.com/hacksparrow/apoc) +データベースを Express アプリケーションに接続できるようにするには、単にデータベースに適切な Node.js ドライバーをアプリケーションにロードするだけですみます。本書では、データベース・システム用の最も一般的な Node.js モジュールを Express アプリケーションに追加して使用する方法について簡単に説明します。 -### インストール +### **インストール** -```sh -$ npm install apoc +```bash +$ npm install neo4j-driver ``` ### 例 ```js -var apoc = require('apoc') - -apoc.query('match (n) return n').exec().then( - function (response) { - console.log(response) - }, - function (fail) { - console.log(fail) - } -) +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) + +const session = driver.session() + +session.readTransaction((tx) => { + return tx.run('MATCH (n) RETURN count(n) AS count') + .then((res) => { + console.log(res.records[0].get('count')) + }) + .catch((error) => { + console.log(error) + }) +}) ``` ## Oracle **モジュール**: [oracledb](https://github.com/oracle/node-oracledb) -### インストール +### **インストール** - NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). +NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). -```sh +```bash $ npm install oracledb ``` @@ -304,23 +308,23 @@ getEmployee(101) **モジュール**: [pg-promise](https://github.com/vitaly-t/pg-promise) -### インストール +### **インストール** -```sh +```bash $ npm install pg-promise ``` ### 例 ```js -var pgp = require('pg-promise')(/* options */) -var db = pgp('postgres://username:password@host:port/database') +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') db.one('SELECT $1 AS value', 123) - .then(function (data) { + .then((data) => { console.log('DATA:', data.value) }) - .catch(function (error) { + .catch((error) => { console.log('ERROR:', error) }) ``` @@ -329,31 +333,31 @@ db.one('SELECT $1 AS value', 123) **モジュール**: [redis](https://github.com/mranney/node_redis) -### インストール +### **インストール** -```sh +```bash $ npm install redis ``` ### 例 ```js -var redis = require('redis') -var client = redis.createClient() +const redis = require('redis') +const client = redis.createClient() -client.on('error', function (err) { - console.log('Error ' + err) +client.on('error', (err) => { + console.log(`Error ${err}`) }) client.set('string key', 'string val', redis.print) client.hset('hash key', 'hashtest 1', 'some value', redis.print) client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print) -client.hkeys('hash key', function (err, replies) { - console.log(replies.length + ' replies:') +client.hkeys('hash key', (err, replies) => { + console.log(`${replies.length} replies:`) - replies.forEach(function (reply, i) { - console.log(' ' + i + ': ' + reply) + replies.forEach((reply, i) => { + console.log(` ${i}: ${reply}`) }) client.quit() @@ -364,27 +368,32 @@ client.hkeys('hash key', function (err, replies) { **モジュール**: [tedious](https://github.com/tediousjs/tedious) -### インストール +### **インストール** -```sh +```bash $ npm install tedious ``` ### 例 ```js -var Connection = require('tedious').Connection -var Request = require('tedious').Request +const Connection = require('tedious').Connection +const Request = require('tedious').Request -var config = { - userName: 'your_username', // update me - password: 'your_password', // update me - server: 'localhost' +const config = { + server: 'localhost', + authentication: { + type: 'default', + options: { + userName: 'your_username', // update me + password: 'your_password' // update me + } + } } -var connection = new Connection(config) +const connection = new Connection(config) -connection.on('connect', function (err) { +connection.on('connect', (err) => { if (err) { console.log(err) } else { @@ -393,17 +402,17 @@ connection.on('connect', function (err) { }) function executeStatement () { - request = new Request("select 123, 'hello world'", function (err, rowCount) { + request = new Request("select 123, 'hello world'", (err, rowCount) => { if (err) { console.log(err) } else { - console.log(rowCount + ' rows') + console.log(`${rowCount} rows`) } connection.close() }) - request.on('row', function (columns) { - columns.forEach(function (column) { + request.on('row', (columns) => { + columns.forEach((column) => { if (column.value === null) { console.log('NULL') } else { @@ -420,30 +429,30 @@ function executeStatement () { **モジュール**: [sqlite3](https://github.com/mapbox/node-sqlite3) -### インストール +### **インストール** -```sh +```bash $ npm install sqlite3 ``` ### 例 ```js -var sqlite3 = require('sqlite3').verbose() -var db = new sqlite3.Database(':memory:') +const sqlite3 = require('sqlite3').verbose() +const db = new sqlite3.Database(':memory:') -db.serialize(function () { +db.serialize(() => { db.run('CREATE TABLE lorem (info TEXT)') - var stmt = db.prepare('INSERT INTO lorem VALUES (?)') + const stmt = db.prepare('INSERT INTO lorem VALUES (?)') - for (var i = 0; i < 10; i++) { - stmt.run('Ipsum ' + i) + for (let i = 0; i < 10; i++) { + stmt.run(`Ipsum ${i}`) } stmt.finalize() - db.each('SELECT rowid AS id, info FROM lorem', function (err, row) { - console.log(row.id + ': ' + row.info) + db.each('SELECT rowid AS id, info FROM lorem', (err, row) => { + console.log(`${row.id}: ${row.info}`) }) }) @@ -454,17 +463,17 @@ db.close() **モジュール**: [elasticsearch](https://github.com/elastic/elasticsearch-js) -### インストール +### **インストール** -```sh +```bash $ npm install elasticsearch ``` ### 例 ```js -var elasticsearch = require('elasticsearch') -var client = elasticsearch.Client({ +const elasticsearch = require('elasticsearch') +const client = elasticsearch.Client({ host: 'localhost:9200' }) @@ -479,9 +488,9 @@ client.search({ } } } -}).then(function (response) { - var hits = response.hits.hits -}, function (error) { +}).then((response) => { + const hits = response.hits.hits +}, (error) => { console.trace(error.message) }) ``` diff --git a/ja/guide/debugging.md b/ja/guide/debugging.md old mode 100755 new mode 100644 index 175cab3584..ba20a68f26 --- a/ja/guide/debugging.md +++ b/ja/guide/debugging.md @@ -1,33 +1,28 @@ --- layout: page title: Express のデバッグ +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: ja +redirect_from: " " --- # Express のデバッグ -Express は、[debug](https://www.npmjs.com/package/debug) モジュールを内部的に使用して、ルートの一致、使用中のミドルウェア関数、アプリケーション・モード、および要求と応答のサイクルのフローに関する情報をログに記録します。 - -
    -`debug` は、`console.log` の拡張版のようなものですが、`console.log` とは異なり、実動コードで `debug` ログをコメント化する必要はありません。ロギングはデフォルトでオフになっており、`DEBUG` 環境変数を使用して条件付きでオンにすることができます。 -
    - Express で使用されているすべての内部ログを表示するには、アプリケーションの起動時に `DEBUG` 環境変数を `express:*` に設定します。 -```sh +```bash $ DEBUG=express:* node index.js ``` Windows では、対応するコマンドを使用します。 -```sh -> set DEBUG=express:* & node index.js +```bash +> $env:DEBUG = "express:*"; node index.js ``` [express ジェネレーター](/{{ page.lang }}/starter/generator.html) で生成されるデフォルトのアプリケーションでこのコマンドを実行すると、以下の出力が表示されます。 -```sh +```bash $ DEBUG=express:* node ./bin/www express:router:route new / +0ms express:router:layer new / +1ms @@ -63,17 +58,17 @@ $ DEBUG=express:* node ./bin/www express:router:layer new / +1ms express:router use /users router +0ms express:router:layer new /users +0ms - express:router use / <anonymous> +0ms + express:router use / &lt;anonymous&gt; +0ms express:router:layer new / +0ms - express:router use / <anonymous> +0ms + express:router use / &lt;anonymous&gt; +0ms express:router:layer new / +0ms - express:router use / <anonymous> +0ms + express:router use / &lt;anonymous&gt; +0ms express:router:layer new / +0ms ``` その後、アプリケーションに対して要求が出されると、Express コードで指定された次のログが表示されます。 -```sh +```bash express:router dispatching GET / +4h express:router query : / +2ms express:router expressInit : / +0ms @@ -91,7 +86,7 @@ $ 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` に設定します。その他についても同様に設定します。 Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. ## `express` によって生成されるアプリケーション @@ -99,14 +94,36 @@ $ DEBUG=express:* node ./bin/www 例えば、`$ express sample-app` を使用してアプリケーションを生成する場合、次のコマンドを使用してデバッグ・ステートメントを有効にすることができます。 -```sh +```bash $ DEBUG=sample-app:* node ./bin/www ``` 名前のコンマ区切りリストを割り当てることで、複数のデバッグ名前空間を指定できます。 -```sh +```bash $ DEBUG=http,mail,express:* node index.js ``` -`debug` の詳細については、[debug](https://www.npmjs.com/package/debug) を参照してください。 +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} + +{% include admonitions/note.html content=debug-text %} diff --git a/ja/guide/error-handling.md b/ja/guide/error-handling.md old mode 100755 new mode 100644 index 4d28da71b8..af90350530 --- a/ja/guide/error-handling.md +++ b/ja/guide/error-handling.md @@ -1,31 +1,35 @@ --- layout: page title: Express でのエラー処理 +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: ja +redirect_from: " " --- # エラー処理 -_エラー処理_ は、Expressが同期的および非同期的に発生するエラーをキャッチして処理する方法です。Expressにはデフォルトのエラーハンドラが付属しているので、自分で作成する必要はありません。 +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. ## エラーのキャッチ Expressがルート・ハンドラとミドルウェアの実行中に発生するすべてのエラーを確実にキャッチすることが重要です。 -ルート・ハンドラとミドルウェア内の同期コードで発生するエラーは、余分な作業を必要としません。同期コードがエラーをスローすると、Expressはそれをキャッチして処理します。 例えば: +ルート・ハンドラとミドルウェア内の同期コードで発生するエラーは、余分な作業を必要としません。同期コードがエラーをスローすると、Expressはそれをキャッチして処理します。 例えば: If synchronous code throws an error, then Express will +catch and process it. For example: ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { throw new Error('BROKEN') // Express will catch this on its own. }) ``` -ルート・ハンドラとミドルウェアによって呼び出された非同期関数から返されたエラーについては、それらを`next()`関数に渡す必要があります。ここでExpressはそれらをキャッチして処理します。例えば: +ルート・ハンドラとミドルウェアによって呼び出された非同期関数から返されたエラーについては、それらを`next()`関数に渡す必要があります。ここでExpressはそれらをキャッチして処理します。例えば: For example: ```js -app.get('/', function (req, res, next) { - fs.readFile('/file-does-not-exist', function (err, data) { +app.get('/', (req, res, next) => { + fs.readFile('/file-does-not-exist', (err, data) => { if (err) { next(err) // Pass errors to Express. } else { @@ -35,6 +39,23 @@ app.get('/', function (req, res, next) { }) ``` +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: + +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` + +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. + +`next()` 関数に (ストリング `'route'` を除く) 何らかを渡すと、Express は、現在のリクエストでエラーが発生したと想定して、エラーが発生していない残りのすべての処理のルーティングとミドルウェア関数をスキップします。そのエラーを何らかの方法で渡す場合は、次のセクションで説明するようにエラー処理ルートを作成する必要があります。 + シーケンス内のコールバックにデータがなく、エラーのみが発生する場合は、次のようにこのコードを単純化できます。 ```js @@ -48,13 +69,14 @@ app.get('/', [ ]) ``` -上記の例では`fs.writeFile`のコールバックとして`next`が提供されています。これはエラーの有無にかかわらず呼び出されます。エラーがなければ、2番目のハンドラが実行されます。それ以外の場合、Expressはエラーをキャッチして処理します。 +上記の例では`fs.writeFile`のコールバックとして`next`が提供されています。これはエラーの有無にかかわらず呼び出されます。エラーがなければ、2番目のハンドラが実行されます。それ以外の場合、Expressはエラーをキャッチして処理します。 If there is no error, the second +handler is executed, otherwise Express catches and processes the error. -ルート・ハンドラまたはミドルウェアによって呼び出された非同期コードで発生したエラーをキャッチして、Expressに渡して処理する必要があります。例えば: +ルート・ハンドラまたはミドルウェアによって呼び出された非同期コードで発生したエラーをキャッチして、Expressに渡して処理する必要があります。例えば: For example: ```js -app.get('/', function (req, res, next) { - setTimeout(function () { +app.get('/', (req, res, next) => { + setTimeout(() => { try { throw new Error('BROKEN') } catch (err) { @@ -66,11 +88,11 @@ app.get('/', function (req, res, next) { 上記の例では、`try ... catch`ブロックを使用して非同期コードのエラーを捕捉してExpressに渡しています。`try ... catch`ブロックが省略された場合、Expressは同期ハンドラ・コードの一部ではないため、エラーをキャッチしません。 -Promiseを使って`try..catch`ブロックのオーバーヘッドを避けるか、Promiseを返す関数を使うとき。例えば: +Promiseを使って`try..catch`ブロックのオーバーヘッドを避けるか、Promiseを返す関数を使うとき。例えば: For example: ```js -app.get('/', function (req, res, next) { - Promise.resolve().then(function () { +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { throw new Error('BROKEN') }).catch(next) // Errors will be passed to Express. }) @@ -78,12 +100,12 @@ app.get('/', function (req, res, next) { Promiseは自動的に同期エラーと拒否されたPromiseをキャッチするので、catchハンドラに最初の引数としてエラーが与えられ、最終的なcatchハンドラとして`next`を指定するだけで、Expressはエラーをキャッチします。 -また、非同期コードを単純なものに減らすことで、同期エラーのキャッチに依存する一連のハンドラを使用することもできます。例えば: +また、非同期コードを単純なものに減らすことで、同期エラーのキャッチに依存する一連のハンドラを使用することもできます。例えば: For example: ```js app.get('/', [ function (req, res, next) { - fs.readFile('/maybe-valid-file', 'utf8', function (err, data) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { res.locals.data = data next(err) }) @@ -95,21 +117,32 @@ app.get('/', [ ]) ``` -上の例は`readFile`呼び出しからの簡単なステートメントをいくつか持っています。`readFile`でエラーが発生した場合、エラーをExpressに渡します。そうでなければ、チェーン内の次のハンドラで同期エラー処理の世界に素早く戻ります。次に、上記の例ではデータを処理しようとしています。これが失敗すると、同期エラーハンドラはそれをキャッチします。 この処理を`readFile`コールバックの中で行った場合、アプリケーションは終了し、Expressのエラーハンドラは実行されません。 +The above example has a couple of trivial statements from the `readFile` +call. 上の例は`readFile`呼び出しからの簡単なステートメントをいくつか持っています。`readFile`でエラーが発生した場合、エラーをExpressに渡します。そうでなければ、チェーン内の次のハンドラで同期エラー処理の世界に素早く戻ります。次に、上記の例ではデータを処理しようとしています。これが失敗すると、同期エラーハンドラはそれをキャッチします。 この処理を`readFile`コールバックの中で行った場合、アプリケーションは終了し、Expressのエラーハンドラは実行されません。 Then, the example above tries to process the data. If this fails, then the +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. どちらの方法を使用しても、Expressのエラーハンドラを呼び出す場合や、アプリケーションを存続させる場合は、Expressがエラーを受け取るようにする必要があります。 ## デフォルトのエラー処理 -Expressには、アプリケーションで発生する可能性のあるエラーを処理するビルトインエラーハンドラが付属しています。 このデフォルトのエラー処理ミドルウェア関数は、ミドルウェア関数スタックの最後に追加されます。 +Expressには、アプリケーションで発生する可能性のあるエラーを処理するビルトインエラーハンドラが付属しています。 このデフォルトのエラー処理ミドルウェア関数は、ミドルウェア関数スタックの最後に追加されます。 This default error-handling middleware function is added at the end of the middleware function stack. -`next()`にエラーを渡し、カスタムエラーハンドラでそれを処理しない場合、それは組み込みのエラーハンドラによって処理されます。エラーはスタックトレースを使用してクライアントに書き込まれます。スタックトレースは本番環境には含まれていません。 +`next()`にエラーを渡し、カスタムエラーハンドラでそれを処理しない場合、それは組み込みのエラーハンドラによって処理されます。エラーはスタックトレースを使用してクライアントに書き込まれます。スタックトレースは本番環境には含まれていません。 The stack trace is not included +in the production environment. -
    +
    プロダクションモードでアプリケーションを実行するには、環境変数`NODE_ENV`を` production`に設定します。
    -プロダクションモードでアプリケーションを実行するには、環境変数`NODE_ENV`を` production`に設定します。 +When an error is written, the following information is added to the +response: -
    +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. レスポンスの記述を開始した後でエラーを伴って`next()`を呼び出すと(例えば、クライアントへの応答をストリーミング中にエラーが発生した場合)、Expressのデフォルトエラーハンドラは接続を閉じてリクエストを失敗します。 @@ -127,12 +160,14 @@ function errorHandler (err, req, res, next) { カスタムエラー処理ミドルウェアが存在していても、コード内でエラーが2回以上発生したときに`next()`を呼び出すと、デフォルトのエラーハンドラがトリガされることに注意してください。 +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html). + ## エラー処理を記述する -エラー処理ミドルウェア関数は、その他のミドルウェア関数と同じ方法で定義しますが、エラー処理関数の引数が3つではなく、4つ `(err、req、res、next)` であることが例外です。次に例を示します。 +エラー処理ミドルウェア関数は、その他のミドルウェア関数と同じ方法で定義しますが、エラー処理関数の引数が3つではなく、4つ `(err、req、res、next)` であることが例外です。次に例を示します。 For example: ```js -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) @@ -141,26 +176,27 @@ app.use(function (err, req, res, next) { エラー処理ミドルウェアは、その他の `app.use()` およびルート呼び出しの後で最後に定義します。次に例を示します。 ```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') +const bodyParser = require('body-parser') +const methodOverride = require('method-override') app.use(bodyParser.urlencoded({ extended: true })) app.use(bodyParser.json()) app.use(methodOverride()) -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { // logic }) ``` ミドルウェア関数の中からの応答は、HTML エラー・ページ、単純なメッセージ、または JSON ストリングなど、任意の形式にすることができます。 -組織的な (および高水準フレームワークの) 目的で、通常のミドルウェア関数と同じように、複数のエラー処理のミドルウェア関数を定義できます。例えば、`XHR` を使用する要求と、使用しない要求のためのエラー・ハンドラーを定義するには、以下のコマンドを使用します。 +組織的な (および高水準フレームワークの) 目的で、通常のミドルウェア関数と同じように、複数のエラー処理のミドルウェア関数を定義できます。例えば、`XHR` を使用する要求と、使用しない要求のためのエラー・ハンドラーを定義するには、以下のコマンドを使用します。 For example, to define an error-handler +for requests made by using `XHR` and those without: ```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') +const bodyParser = require('body-parser') +const methodOverride = require('method-override') app.use(bodyParser.urlencoded({ extended: true @@ -183,7 +219,7 @@ function logErrors (err, req, res, next) { また、この例では、`clientErrorHandler` は次のように定義されます。この場合、エラーは明示的に次のエラーに渡されます。 -エラー処理関数の中で"next"を呼んで _いない_ ときは、レスポンスの記述(および終了)を行う必要があります。そうしなければ、それらのリクエストは「ハング」し、ガベージコレクションの対象になりません。 +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. ```js function clientErrorHandler (err, req, res, next) { @@ -204,21 +240,19 @@ function errorHandler (err, req, res, next) { } ``` -`next()` 関数に (ストリング `'route'` を除く) 何らかを渡すと、Express は、現在のリクエストでエラーが発生したと想定して、エラーが発生していない残りのすべての処理のルーティングとミドルウェア関数をスキップします。そのエラーを何らかの方法で渡す場合は、次のセクションで説明するようにエラー処理ルートを作成する必要があります。 - -複数のコールバック関数を使用するルート・ハンドラーがある場合、`route` パラメーターを使用して、次のルート・ハンドラーまでスキップできます。次に例を示します。 +複数のコールバック関数を使用するルート・ハンドラーがある場合、`route` パラメーターを使用して、次のルート・ハンドラーまでスキップできます。次に例を示します。 For example: ```js app.get('/a_route_behind_paywall', - function checkIfPaidSubscriber (req, res, next) { + (req, res, next) => { if (!req.user.hasPaid) { // continue handling this request next('route') } else { next() } - }, function getPaidContent (req, res, next) { - PaidContent.find(function (err, doc) { + }, (req, res, next) => { + PaidContent.find((err, doc) => { if (err) return next(err) res.json(doc) }) @@ -228,7 +262,5 @@ app.get('/a_route_behind_paywall', この例では、`getPaidContent` ハンドラーはスキップされますが、`/a_route_behind_paywall` の `app` にある残りのハンドラーはすべて引き続き実行されます。
    - -`next()` および `next(err)` の呼び出しは、現在のハンドラーが完了したことと、その状態を示します。`next(err)` は、上記のようにエラーを処理するようにセットアップされたハンドラーを除き、チェーン内の残りのハンドラーをすべてスキップします。 - +Calls to `next()` and `next(err)` indicate that the current handler is complete and in what state. `next()` および `next(err)` の呼び出しは、現在のハンドラーが完了したことと、その状態を示します。`next(err)` は、上記のようにエラーを処理するようにセットアップされたハンドラーを除き、チェーン内の残りのハンドラーをすべてスキップします。
    diff --git a/ja/guide/migrating-4.md b/ja/guide/migrating-4.md old mode 100755 new mode 100644 index 88f7367fe1..f6221a168e --- a/ja/guide/migrating-4.md +++ b/ja/guide/migrating-4.md @@ -1,15 +1,16 @@ --- layout: page title: Express 4 への移行 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: ja +redirect_from: " " --- # Express 4 への移行

    概説

    -Express 4 では、Express 3 とは互換性の _ない_ 変更が行われています。つまり、依存関係にある Express のバージョンを更新すると、既存の Express 3 アプリケーションは機能しません。 +Express 4 では、Express 3 とは互換性の _ない_ 変更が行われています。つまり、依存関係にある Express のバージョンを更新すると、既存の Express 3 アプリケーションは機能しません。 That means an existing Express 3 app will _not_ work if you update the Express version in its dependencies. この記事では以下の内容を扱います。 @@ -24,23 +25,26 @@ Express 4 では、Express 3 とは互換性の _ない_ 変更が行われて Express 4 では、いくつかの大きな変更が行われています。 以下も参照してください。 -* [4.x の新機能](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [3.x から 4.x への移行](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [4.x の新機能](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [3.x から 4.x への移行](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

    Express コアおよびミドルウェア・システムの変更

    -Express 4 は、Connect に依存しなくなり、`express.static` 関数を除くすべての標準装備ミドルウェアをコアから削除しました。つまり、Express は独立したルーティングおよびミドルウェアの Web フレームワークになり、Express のバージョン管理とリリースはミドルウェア更新の影響を受けません。 +Express 4 は、Connect に依存しなくなり、`express.static` 関数を除くすべての標準装備ミドルウェアをコアから削除しました。つまり、Express は独立したルーティングおよびミドルウェアの Web フレームワークになり、Express のバージョン管理とリリースはミドルウェア更新の影響を受けません。 This means that +Express is now an independent routing and middleware web framework, and +Express versioning and releases are not affected by middleware updates. -標準装備ミドルウェアがないため、アプリケーションの実行に必要なすべてのミドルウェアを明示的に追加する必要があります。そのためには、単に以下のステップを実行してください。 +標準装備ミドルウェアがないため、アプリケーションの実行に必要なすべてのミドルウェアを明示的に追加する必要があります。そのためには、単に以下のステップを実行してください。 Simply follow these steps: 1. モジュールをインストールします。`npm install --save ` 2. アプリケーションでモジュールを要求します。`require('module-name')` @@ -49,7 +53,7 @@ Express 4 は、Connect に依存しなくなり、`express.static` 関数を除 次の表に、Express 3 のミドルウェアと、それぞれに対応する Express 4 のミドルウェアをリストします。 - + @@ -81,23 +85,26 @@ Express 4 は、Connect に依存しなくなり、`express.static` 関数を除 -
    Express 3Express 4
    Express 3Express 4
    express.bodyParser body-parser + multer
    serve-index
    express.static serve-static
    +
    Express 4 のミドルウェアの完全なリストは、[ここ](https://github.com/senchalabs/connect#middleware)を参照してください。 -ほとんどの場合、旧バージョン 3 のミドルウェアを単に Express 4 のミドルウェアに置き換えるだけですみます。詳細については、GitHub でモジュールの資料を参照してください。 +ほとんどの場合、旧バージョン 3 のミドルウェアを単に Express 4 のミドルウェアに置き換えるだけですみます。詳細については、GitHub でモジュールの資料を参照してください。 For details, see the module documentation in +GitHub.

    app.use がパラメーターを受け入れます

    バージョン 4 では、変数パラメーターを使用して、ミドルウェア関数がロードされるパスを定義し、ルート・ハンドラーからパラメーターの値を読み取ることができます。 次に例を示します。 +For example: ```js -app.use('/book/:id', function (req, res, next) { +app.use('/book/:id', (req, res, next) => { console.log('ID:', req.params.id) next() }) ``` +

    ルーティング・システム

    @@ -107,31 +114,34 @@ app.use('/book/:id', function (req, res, next) { ルートの定義方法は変わりませんが、ルーティング・システムには、ルートの編成に役立つ 2 つの新機能があります。 {: .doclist } -* 新しいメソッド `app.route()` は、ルート・パスのチェーン可能なルート・ハンドラーを作成します。 -* 新しいクラス `express.Router` は、モジュール式のマウント可能なルート・ハンドラーを作成します。 + +- 新しいメソッド `app.route()` は、ルート・パスのチェーン可能なルート・ハンドラーを作成します。 +- 新しいクラス `express.Router` は、モジュール式のマウント可能なルート・ハンドラーを作成します。

    app.route() メソッド

    -新しい `app.route()` メソッドを使用すると、ルート・パスのチェーン可能なルート・ハンドラーを作成できます。パスは単一の場所で指定されるため、モジュール式のルートを作成すると、便利であるほか、冗長性とタイプミスを減らすことができます。ルートについて詳しくは、[`Router()` 資料](/{{ page.lang }}/4x/api.html#router)を参照してください。 +新しい `app.route()` メソッドを使用すると、ルート・パスのチェーン可能なルート・ハンドラーを作成できます。パスは単一の場所で指定されるため、モジュール式のルートを作成すると、便利であるほか、冗長性とタイプミスを減らすことができます。ルートについて詳しくは、[`Router()` 資料](/{{ page.lang }}/4x/api.html#router)を参照してください。 Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more +information about routes, see [`Router()` documentation](/{{ page.lang }}/4x/api.html#router). 次に、`app.route()` 関数を使用して定義された、チェーニングされたルート・ハンドラーの例を示します。 ```js app.route('/book') - .get(function (req, res) { + .get((req, res) => { res.send('Get a random book') }) - .post(function (req, res) { + .post((req, res) => { res.send('Add a book') }) - .put(function (req, res) { + .put((req, res) => { res.send('Update the book') }) ```

    express.Router クラス

    -ルートの編成に役立つもう 1 つの機能は、新しいクラス `express.Router` です。これを使用すると、モジュール式のマウント可能なルート・ハンドラーを作成できます。`Router` インスタンスは、完全なミドルウェアおよびルーティング・システムです。そのため、よく「ミニアプリケーション」と呼ばれます。 +ルートの編成に役立つもう 1 つの機能は、新しいクラス `express.Router` です。これを使用すると、モジュール式のマウント可能なルート・ハンドラーを作成できます。`Router` インスタンスは、完全なミドルウェアおよびルーティング・システムです。そのため、よく「ミニアプリケーション」と呼ばれます。 A `Router` instance is a complete middleware and +routing system; for this reason it is often referred to as a "mini-app". 次の例では、ルーターをモジュールとして作成し、その中にミドルウェアをロードして、いくつかのルートを定義し、それをメインアプリケーションのパスにマウントします。 @@ -142,16 +152,16 @@ var express = require('express') var router = express.Router() // middleware specific to this router -router.use(function timeLog (req, res, next) { +router.use((req, res, next) => { console.log('Time: ', Date.now()) next() }) // define the home page route -router.get('/', function (req, res) { +router.get('/', (req, res) => { res.send('Birds home page') }) // define the about route -router.get('/about', function (req, res) { +router.get('/about', (req, res) => { res.send('About birds') }) @@ -177,7 +187,7 @@ app.use('/birds', birds) 次の表に、Express 4 におけるその他の小規模ながらも重要な変更点をリストします。 - + @@ -190,7 +200,10 @@ app.use('/birds', birds) `http.createServer()` @@ -198,7 +211,9 @@ app.use('/birds', birds) `app.configure()` @@ -278,15 +293,18 @@ app.use('/birds', birds) `res.setHeader('Set-Cookie', val)` -
    オブジェクト 説明
    + `http` モジュールは、このモジュールを直接処理する必要がある場合を除き、不要になりました (socket.io/SPDY/HTTPS)。アプリケーションは、`app.listen()` 関数を使用して開始できます。 + The app can be started by using the +`app.listen()` function.
    +The `app.configure()` function has been removed. `app.configure()` 関数は削除されました。環境を検出して、アプリケーションを適宜に構成するには、`process.env.NODE_ENV` 関数または `app.get('env')` 関数を使用してください。 +
    +Functionality is now limited to setting the basic cookie value. 機能が基本的な Cookie 値の設定に限定されるようになりました。機能を追加するには、`res.cookie()` を使用してください。 +
    +

    移行の例

    次に、Express 3 アプリケーションを Express 4 に移行する例を示します。 使用しているファイルは、`app.js` および `package.json` です。 +The files of interest are `app.js` and `package.json`.

    バージョン 3 アプリケーション @@ -325,7 +343,7 @@ if (app.get('env') === 'development') { app.get('/', routes.index) app.get('/users', user.list) -http.createServer(app).listen(app.get('port'), function () { +http.createServer(app).listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ``` @@ -355,15 +373,17 @@ http.createServer(app).listen(app.get('port'), function () { 移行プロセスを開始するには、次のコマンドを使用して、Express 4 アプリケーションに必要なミドルウェアをインストールし、Express と Pug をそれぞれの最新バージョンに更新します。 -```sh +```bash $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save ``` `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` オブジェクトで使用できなくなりました。代わりの関数を手動でインストールして、アプリケーションにロードする必要があります。 You must install their alternatives + manually and load them in the app. -2. `app.router` 関数をロードする必要がなくなりました。この関数は有効な Express 4 アプリケーション・オブジェクトではないため、`app.use(app.router);` コードを削除してください。 +2. You no longer need to load the `app.router` function. + `app.router` 関数をロードする必要がなくなりました。この関数は有効な Express 4 アプリケーション・オブジェクトではないため、`app.use(app.router);` コードを削除してください。 3. ミドルウェア関数が正しい順序でロードされていることを確認してください。つまり、アプリケーション・ルートをロードした後で `errorHandler` をロードしてください。 @@ -397,7 +417,8 @@ $ npm install serve-favicon morgan method-override express-session body-parser m

    app.js

    -次に、無効なコードを削除して、必要なミドルウェアをロードし、必要に応じてその他の変更を行います。`app.js` ファイルの内容は次のようになります。 +Then, remove invalid code, load the required middleware, and make other +changes as necessary. The `app.js` file will look like this: ```js var http = require('http') @@ -442,26 +463,26 @@ if (app.get('env') === 'development') { } var server = http.createServer(app) -server.listen(app.get('port'), function () { +server.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ``` -
    - -`http` モジュール (socket.io/SPDY/HTTPS) を直接処理する必要がある場合を除き、このモジュールをロードする必要はありません。次のようにして、アプリケーションを簡単に開始できます。 +
    `http` モジュール (socket.io/SPDY/HTTPS) を直接処理する必要がある場合を除き、このモジュールをロードする必要はありません。次のようにして、アプリケーションを簡単に開始できます。 ```js -app.listen(app.get('port'), function () { +app.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ``` +
    +

    アプリケーションの実行

    -これで移行プロセスは完了して、アプリケーションは Express 4 アプリケーションになりました。確認するには、次のコマンドを使用してアプリケーションを開始します。 +これで移行プロセスは完了して、アプリケーションは Express 4 アプリケーションになりました。確認するには、次のコマンドを使用してアプリケーションを開始します。 To confirm, start the app by using the following command: -```sh +```bash $ node . ``` @@ -475,7 +496,7 @@ Express アプリケーションを生成するためのコマンド・ライン システムに Express 3 アプリケーション・ジェネレーターがインストールされている場合は、次のようにしてアンインストールする必要があります。 -```sh +```bash $ npm uninstall -g express ``` @@ -483,7 +504,7 @@ $ npm uninstall -g express 次に、新しいジェネレーターをインストールします。 -```sh +```bash $ npm install -g express-generator ``` @@ -496,15 +517,16 @@ $ npm install -g express-generator コマンドのオプションと使用法の大部分は以前と同じですが、以下の例外があります。 {: .doclist } -* `--sessions` オプションを削除しました。 -* `--jshtml` オプションを削除しました。 -* [Hogan.js](http://twitter.github.io/hogan.js/) をサポートするために `--hogan` オプションを追加しました。 + +- `--sessions` オプションを削除しました。 +- `--jshtml` オプションを削除しました。 +- [Hogan.js](http://twitter.github.io/hogan.js/) をサポートするために `--hogan` オプションを追加しました。

    次のコマンドを実行して、Express 4 アプリケーションを作成します。 -```sh +```bash $ express app4 ``` @@ -514,22 +536,26 @@ $ express app4 依存関係をインストールした後、次のコマンドを使用してアプリケーションを開始します。 -```sh +```bash $ npm start ``` `package.json` ファイルで npm start スクリプトを見ると、アプリケーションを開始する実際のコマンドは `node ./bin/www` であることが分かります。これは、Express 3 では `node app.js` でした。 -Express 4 ジェネレーターによって生成される `app.js` ファイルが Node.js モジュールになったため、(コードを変更しない限り) アプリケーションとして単独では開始できなくなりました。モジュールを Node.js ファイルにロードして、Node.js ファイルから開始する必要があります。この場合、Node.js ファイルは `./bin/www` です。 +Express 4 ジェネレーターによって生成される `app.js` ファイルが Node.js モジュールになったため、(コードを変更しない限り) アプリケーションとして単独では開始できなくなりました。モジュールを Node.js ファイルにロードして、Node.js ファイルから開始する必要があります。この場合、Node.js ファイルは `./bin/www` です。 The module must be loaded in a Node.js file +and started via the Node.js file. The Node.js file is `./bin/www` +in this case. -Express アプリケーションの作成またはアプリケーションの開始のために、`bin` ディレクトリーも、拡張子のない `www` ファイルも必須ではありません。これらは単にジェネレーターが推奨するものであるため、ニーズに合わせて自由に変更してください。 +Express アプリケーションの作成またはアプリケーションの開始のために、`bin` ディレクトリーも、拡張子のない `www` ファイルも必須ではありません。これらは単にジェネレーターが推奨するものであるため、ニーズに合わせて自由に変更してください。 They are +just suggestions made by the generator, so feel free to modify them to suit your +needs. `www` ディレクトリーを削除して、処理を「Express 3 の方法」で実行するには、`app.js` ファイルの最後にある `module.exports = app;` という行を削除して、その場所に以下のコードを貼り付けます。 ```js app.set('port', process.env.PORT || 3000) -var server = app.listen(app.get('port'), function () { +var server = app.listen(app.get('port'), () => { debug('Express server listening on port ' + server.address().port) }) ``` @@ -542,4 +568,5 @@ var debug = require('debug')('app4') 次に、`package.json` ファイル内の `"start": "node ./bin/www"` を `"start": "node app.js"` に変更します。 -これで、`./bin/www` の機能を `app.js` に戻しました。この変更は推奨されるものではありませんが、この演習により、`./bin/www` ファイルの仕組みと、`app.js` ファイルが単独で開始されなくなった理由を理解できます。 +You have now moved the functionality of `./bin/www` back to +`app.js`. これで、`./bin/www` の機能を `app.js` に戻しました。この変更は推奨されるものではありませんが、この演習により、`./bin/www` ファイルの仕組みと、`app.js` ファイルが単独で開始されなくなった理由を理解できます。 diff --git a/ja/guide/migrating-5.md b/ja/guide/migrating-5.md old mode 100755 new mode 100644 index 1c471042d3..c6eb92faa0 --- a/ja/guide/migrating-5.md +++ b/ja/guide/migrating-5.md @@ -1,30 +1,44 @@ --- layout: page title: Express 5 への移行 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: ja +redirect_from: " " --- # Express 5 への移行

    概説

    -Express 5.0 は、まだアルファ・リリースの段階ですが、ここでは本リリースにおける変更のプレビューを示し、Express 4 アプリケーションを Express 5 に移行する方法を説明します。 +Express 5 は Express 4 とあまり変わりません。API の変更は、3.0 から 4.0 への変更ほど大きいものではありません。基本的な API は同じままですが、それでも互換性のない変更が行われています。つまり、Express 5 を使用するように既存の Express 4 を更新すると、機能しなくなる可能性があります。 Therefore, an application built with Express 4 might not work if you update it to use Express 5. -Express 5 は Express 4 とあまり変わりません。API の変更は、3.0 から 4.0 への変更ほど大きいものではありません。基本的な API は同じままですが、それでも互換性のない変更が行われています。つまり、Express 5 を使用するように既存の Express 4 を更新すると、機能しなくなる可能性があります。 +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -最新のアルファをインストールして Express 5 をプレビューするには、アプリケーションのルート・ディレクトリーで次のコマンドを入力します。 +```sh +npm install "express@5" +``` + +その後、自動テストを実行して、どの機能が失敗するかを確認し、下記の更新に従って問題を修正することができます。テストの失敗に対応した後、アプリケーションを実行して、どのようなエラーが発生するかを確認します。サポートされていないメソッドまたはプロパティーをアプリケーションが使用している場合は、すぐに判明します。 After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported. + +## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: ```sh -$ npm install express@>=5.0.0-alpha.1 --save +npx @expressjs/codemod upgrade ``` -その後、自動テストを実行して、どの機能が失敗するかを確認し、下記の更新に従って問題を修正することができます。テストの失敗に対応した後、アプリケーションを実行して、どのようなエラーが発生するかを確認します。サポートされていないメソッドまたはプロパティーをアプリケーションが使用している場合は、すぐに判明します。 +If you want to run a specific codemod, you can run the following command: -

    Express 5 における変更点

    +```sh +npx @expressjs/codemod name-of-the-codemod +``` -次に、Express のユーザーに影響を与える (アルファ 2 リリースの時点での) 変更のリストを示します。 -予定されているすべての機能のリストについては、[プル要求](https://github.com/expressjs/express/pull/2237)を参照してください。 +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). + +

    Express 5 における変更点

    **削除されたメソッドとプロパティー** @@ -36,96 +50,497 @@ $ npm install express@>=5.0.0-alpha.1 --save
  • req.param(name)
  • res.json(obj, status)
  • res.jsonp(obj, status)
  • +
  • res.redirect('back') and res.location('back')
  • +
  • res.redirect(url, status)
  • res.send(body, status)
  • res.send(status)
  • res.sendfile()
  • +
  • router.param(fn)
  • +
  • express.static.mime
  • +
  • express:router debug logs
  • -**変更** +**改善** -**改善** +**変更** -

    削除されたメソッドとプロパティー

    +## 削除されたメソッドとプロパティー -アプリケーションで以下のいずれかのメソッドまたはプロパティーを使用すると、異常終了します。そのため、バージョン 5 に更新した後で、アプリケーションを変更する必要があります。 +If you use any of these methods or properties in your app, it will crash. アプリケーションで以下のいずれかのメソッドまたはプロパティーを使用すると、異常終了します。そのため、バージョン 5 に更新した後で、アプリケーションを変更する必要があります。 -

    app.del()

    +

    app.del()

    -Express 5 は、`app.del()` 関数をサポートしなくなりました。この関数を使用すると、エラーがスローされます。HTTP DELETE ルートを登録するには、代わりに `app.delete()` 関数を使用してください。 +Express 5 は、`app.del()` 関数をサポートしなくなりました。この関数を使用すると、エラーがスローされます。HTTP DELETE ルートを登録するには、代わりに `app.delete()` 関数を使用してください。 If you use this function, an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. -最初は `del` が `delete` の代わりに使用されていました。`delete` は、JavaScript で予約されているキーワードであるためです。しかし、ECMAScript 6 以降では、`delete` およびその他の予約済みキーワードを正式にプロパティー名として使用できます。ここで、`app.del` 関数の非推奨につながった議論を読むことができます。 +最初は `del` が `delete` の代わりに使用されていました。`delete` は、JavaScript で予約されているキーワードであるためです。しかし、ECMAScript 6 以降では、`delete` およびその他の予約済みキーワードを正式にプロパティー名として使用できます。ここで、`app.del` 関数の非推奨につながった議論を読むことができます。 However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. -

    app.param(fn)

    +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: -`app.param(fn)` シグニチャーは、`app.param(name, fn)` 関数の動作を変更するために使用されていました。v4.11.0 以降では非推奨になったため、Express 5 は完全にサポートしなくなりました。 +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` + +{% endcapture %} -

    メソッド名の複数化

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} -以下のメソッド名は複数形になりました。Express 4 では、以前のメソッドを使用すると、非推奨の警告が出されていました。Express 5 では、完全にサポートされなくなりました。 +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) + +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

    app.param(fn)

    + +`app.param(fn)` シグニチャーは、`app.param(name, fn)` 関数の動作を変更するために使用されていました。v4.11.0 以降では非推奨になったため、Express 5 は完全にサポートしなくなりました。 It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. + +

    メソッド名の複数化

    + +The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: + +`req.acceptsLanguage()` は `req.acceptsLanguages()` に置き換えられます。 `req.acceptsCharset()` は `req.acceptsCharsets()` に置き換えられます。 `req.acceptsEncoding()` は `req.acceptsEncodings()` に置き換えられます。 -`req.acceptsLanguage()` は `req.acceptsLanguages()` に置き換えられます。 +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` -

    app.param(name, fn) の name の先頭コロン (:)

    +{% endcapture %} -`app.param(name, fn)` 関数の name の先頭コロン文字 (:) は、Express 3 の残余物であり、Express 4 では後方互換性のためにサポートされていましたが、非推奨の通知が出されてました。Express 5 では、サイレントに無視して、先頭にコロンを付けない name パラメーターを使用します。 +{% include admonitions/note.html content=codemod-pluralized-methods %} + +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    app.param(name, fn) の name の先頭コロン (:)

    + +`app.param(name, fn)` 関数の name の先頭コロン文字 (:) は、Express 3 の残余物であり、Express 4 では後方互換性のためにサポートされていましたが、非推奨の通知が出されてました。Express 5 では、サイレントに無視して、先頭にコロンを付けない name パラメーターを使用します。 Express 5 will silently ignore it and use the name parameter without prefixing it with a colon. [app.param](/{{ page.lang }}/4x/api.html#app.param) に関する Express 4 の資料では、先頭のコロンについて言及していないため、この資料に従う場合には、コードに影響は及ばないはずです。 -

    req.param(name)

    +

    req.param(name)

    + +This potentially confusing and dangerous method of retrieving form data has been removed. この混乱を招く可能性がある危険なメソッドは、フォーム・データを取得するためのものでしたが、削除されました。今後は、実行依頼されたパラメーター名を `req.params`、`req.body`、または `req.query` オブジェクトで具体的に見つける必要があります。 + +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    + +Express 5 は、シグニチャー `res.json(obj, status)` をサポートしなくなりました。代わりに、状況を設定してから、`res.status(status).json(obj)` のように `res.json()` メソッドにチェーニングします。 Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    + +Express 5 は、シグニチャー `res.jsonp(obj, status)` をサポートしなくなりました。代わりに、状況を設定してから、`res.status(status).jsonp(obj)` のように `res.jsonp()` メソッドにチェーニングします。 Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    + +Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    + +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    -この混乱を招く可能性がある危険なメソッドは、フォーム・データを取得するためのものでしたが、削除されました。今後は、実行依頼されたパラメーター名を `req.params`、`req.body`、または `req.query` オブジェクトで具体的に見つける必要があります。 +Express 5 は、シグニチャー `res.send(obj, status)` をサポートしなくなりました。代わりに、状況を設定してから、`res.status(status).send(obj)` のように `res.send()` メソッドにチェーニングします。 Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. -

    res.json(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} -Express 5 は、シグニチャー `res.json(obj, status)` をサポートしなくなりました。代わりに、状況を設定してから、`res.status(status).json(obj)` のように `res.json()` メソッドにチェーニングします。 +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) -

    res.jsonp(obj, status)

    +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` -Express 5 は、シグニチャー `res.jsonp(obj, status)` をサポートしなくなりました。代わりに、状況を設定してから、`res.status(status).jsonp(obj)` のように `res.jsonp()` メソッドにチェーニングします。 +

    res.send(status)

    -

    res.send(body, status)

    +Express 5 no longer supports the signature `res.send(status)`, where `status` is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. +If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature. -Express 5 は、シグニチャー `res.send(obj, status)` をサポートしなくなりました。代わりに、状況を設定してから、`res.status(status).send(obj)` のように `res.send()` メソッドにチェーニングします。 +{% include admonitions/note.html content=codemod-deprecated-signatures %} -

    res.send(status)

    +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) -Express 5 は、シグニチャー res.send(status) をサポートしなくなりました。ここで、*`status`* は数値です。代わりに、`res.sendStatus(statusCode)` 関数を使用します。この関数は、HTTP 応答ヘッダーの状況コードを設定して、コードのテキスト版 (「Not Found」、「Internal Server Error」など) を送信します。 -`res.send()` 関数を使用して数値を送信する必要がある場合は、数値を引用してストリングに変換し、Express によって、サポートされない以前のシグニチャーを使用しようとしていると解釈されないようにします。 +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` -

    res.sendfile()

    +

    res.sendfile()

    `res.sendfile()` 関数は、Express 5 ではキャメルケース版の `res.sendFile()` に置き換えられます。 -

    変更

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## 変更 + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. For example: + +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: -

    app.router

    +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    -`app.router` オブジェクトは、Express 4 で削除されましたが、Express 5 で復帰しました。アプリケーションが明示的にロードする必要があった Express 3 とは異なり、新しいバージョンでは、このオブジェクトは基本の Express ルーターの単なる参照です。 +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. -

    req.host

    +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). -Express 4 では、`req.host` 関数は、ポート番号が存在する場合に、ポート番号を誤って削除していました。Express 5 では、ポート番号は維持されます。 +

    express.urlencoded

    -

    req.query

    +The `express.urlencoded` method makes the `extended` option `false` by default. -Express 4.7 および Express 5 以降では、照会ストリング解析ロジックで独自の関数を使用する場合に、照会パーサー・オプションは `false` を受け入れて、照会ストリングの解析を無効にすることができます。 +

    express.static dotfiles

    -

    改善

    +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. -

    res.render()

    +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +For example: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    + +`app.router` オブジェクトは、Express 4 で削除されましたが、Express 5 で復帰しました。アプリケーションが明示的にロードする必要があった Express 3 とは異なり、新しいバージョンでは、このオブジェクトは基本の Express ルーターの単なる参照です。 In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. + +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    + +Express 4 では、`req.host` 関数は、ポート番号が存在する場合に、ポート番号を誤って削除していました。Express 5 では、ポート番号は維持されます。 In Express 5, the port number is maintained. + +

    req.query

    + +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". + +

    res.clearCookie

    + +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. + +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## 改善 + +

    res.render()

    このメソッドは、すべてのビュー・エンジンに非同期動作を適用するようになり、同期実装を使用して推奨インターフェースに違反していたビュー・エンジンに起因するバグを回避します。 + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/ja/guide/overriding-express-api.md b/ja/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/ja/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/ja/guide/routing.md b/ja/guide/routing.md old mode 100755 new mode 100644 index 8731d10345..1a175cbbd5 --- a/ja/guide/routing.md +++ b/ja/guide/routing.md @@ -1,32 +1,36 @@ --- layout: page title: Express でのルーティング +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: ja +redirect_from: " " --- # ルーティング -*ルーティング* とは、アプリケーション・エンドポイント (URI) と、クライアントリクエストに対するそれらのレスポンスの定義のことです。 -ルーティングの概要については、[基本的なルーティング](/{{ page.lang }}/starter/basic-routing.html)を参照してください。 +_Routing_ refers to how an application's endpoints (URIs) respond to client requests. +For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/basic-routing.html). ルーティングはHTTPメソッドに対応するExpressの`app`オブジェクトのメソッドを使用して定義します。たとえば、GETリクエストを処理する`app.get()`やPOSTリクエストを処理する`app.post`があります。 -完全なリストについては、[app.METHOD](/{{ page.lang }}/4x/ api.html#app.METHODを)を参照してください。 -また、すべてのHTTPメソッドを制御するために[app.all()](/{{ page.lang }}/4x/api.html#app.all)を、ミドルウェアを指定するために[app.use()](/{{ page.lang }}/4x/api.html#app.use)をコールバック関数として使用することができます(詳細については、[Using middleware](/{{ page.lang }}/guide/using-middleware.html)を参照してください)。 +完全なリストについては、[app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD)を参照してください。 +また、すべてのHTTPメソッドを制御するために[app.all()](/{{ page.lang }}/4x/api.html#app.all)を、ミドルウェアを指定するために[app.use()](/{{ page.lang }}/4x/api.html#app.use)をコールバック関数として使用することができます(詳細については、[Using middleware](/{{ page.lang }}/guide/using-middleware.html)を参照してください)。 For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). -これらのルーティングメソッドは、アプリケーションが指定されたルート(エンドポイント)とHTTPメソッドへのリクエストを受け取ったときに呼び出されるコールバック関数(ハンドラ関数とも呼ばれます)を指定します。 つまり、アプリケーションは指定されたルートとメソッドに一致するリクエストをリッスンし、一致を検出すると指定されたコールバック関数を呼び出します。 +これらのルーティングメソッドは、アプリケーションが指定されたルート(エンドポイント)とHTTPメソッドへのリクエストを受け取ったときに呼び出されるコールバック関数(ハンドラ関数とも呼ばれます)を指定します。 つまり、アプリケーションは指定されたルートとメソッドに一致するリクエストをリッスンし、一致を検出すると指定されたコールバック関数を呼び出します。 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 fact, the routing methods can have more than one callback function as arguments. 実際、ルーティングメソッドは複数のコールバック関数を引数として持つことができます。 複数のコールバック関数では、コールバック関数に引数として`next`を指定し、次のコールバックに制御を渡す関数の本体内で`next()`を呼び出すことが重要です。 次のコードは、極めて基本的なルートの例です。 ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() // respond with "hello world" when a GET request is made to the homepage -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('hello world') }) ``` @@ -39,23 +43,24 @@ route メソッドは、いずれかの HTTP メソッドから派生され、`e ```js // GET method route -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('GET request to the homepage') }) // POST method route -app.post('/', function (req, res) { +app.post('/', (req, res) => { res.send('POST request to the homepage') }) ``` Expressは、すべてのHTTPリクエストメソッドに対応するメソッド(`get`、`post`など)をサポートしています。 完全なリストについては、[app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD)を参照して下さい。 +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). -_すべての_ HTTPリクエストメソッドのパスにミドルウェア関数をロードするために使用される特別なルーティングメソッド、`app.all()`があります。 たとえば、GET、POST、PUT、DELETE、または[httpモジュール](https://nodejs.org/api/http.html#http_http_methods)でサポートされているその他のHTTPリクエストメソッドを使用するかどうかにかかわらず、"/secret"ルートへのリクエストに対して次のハンドラが実行されます。 +_すべての_ HTTPリクエストメソッドのパスにミドルウェア関数をロードするために使用される特別なルーティングメソッド、`app.all()`があります。 たとえば、GET、POST、PUT、DELETE、または[httpモジュール](https://nodejs.org/api/http.html#http_http_methods)でサポートされているその他のHTTPリクエストメソッドを使用するかどうかにかかわらず、"/secret"ルートへのリクエストに対して次のハンドラが実行されます。 For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). ```js -app.all('/secret', function (req, res, next) { +app.all('/secret', (req, res, next) => { console.log('Accessing the secret section ...') next() // pass control to the next handler }) @@ -63,26 +68,39 @@ app.all('/secret', function (req, res, next) {

    ルート・パス

    -ルート・パスは、リクエストメソッドとの組み合わせにより、リクエストを実行できるエンドポイントを定義します。ルート・パスは、ストリング、ストリング・パターン、または正規表現にすることができます。 +ルート・パスは、リクエストメソッドとの組み合わせにより、リクエストを実行できるエンドポイントを定義します。ルート・パスは、ストリング、ストリング・パターン、または正規表現にすることができます。 Route paths can be strings, string patterns, or regular expressions. -文字`?`、`+`、`*`、`()`は正規表現の部分集合です。 ハイフン(`-`)とドット(`.`)は、文字列ベースのパスによって文字通り解釈されます。 +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -パス文字列でドル文字(`$`)を使用する必要がある場合は、`([`と`])`の中にエスケープして囲みます。たとえば、"/data/$book"でのリクエストのパス文字列は"`/data /([\$])book`"となります。 +{% include admonitions/caution.html content=caution-character %} -
    -Express は、ルート・パスのマッチングに [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) を使用します。ルート・パスの定義におけるすべての可能性については、path-to-regexp 資料を参照してください。[Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) は、パターン・マッチングをサポートしていませんが、基本的な Express ルートをテストするための便利なツールです。 -
    +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} -
    -クエリ文字列は、ルート・パスの一部ではありません。 -
    +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [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. + +{% endcapture %} + +{% include admonitions/note.html content=note-path-to-regexp %} + +{% capture query-string-note %} + +Query strings are not part of the route path. -次に、ストリングに基づくルート・パスの例を示します。 +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### 次に、ストリングに基づくルート・パスの例を示します。 このルート・パスは、リクエストをルートのルート `/` にマッチングします。 ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('root') }) ``` @@ -90,7 +108,7 @@ app.get('/', function (req, res) { このルート・パスは、リクエストを `/about` にマッチングします。 ```js -app.get('/about', function (req, res) { +app.get('/about', (req, res) => { res.send('about') }) ``` @@ -98,17 +116,21 @@ app.get('/about', function (req, res) { このルート・パスは、リクエストを `/random.text` にマッチングします。 ```js -app.get('/random.text', function (req, res) { +app.get('/random.text', (req, res) => { res.send('random.text') }) ``` -次に、ストリング・パターンに基づくルート・パスの例を示します。 +### 次に、ストリング・パターンに基づくルート・パスの例を示します。 + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} + +{% include admonitions/caution.html content=caution-string-patterns %} このルート・パスは、`acd` および `abcd` をマッチングします。 ```js -app.get('/ab?cd', function (req, res) { +app.get('/ab?cd', (req, res) => { res.send('ab?cd') }) ``` @@ -116,7 +138,7 @@ app.get('/ab?cd', function (req, res) { このルート・パスは、`abcd`、`abbcd`、`abbbcd` などをマッチングします。 ```js -app.get('/ab+cd', function (req, res) { +app.get('/ab+cd', (req, res) => { res.send('ab+cd') }) ``` @@ -124,7 +146,7 @@ app.get('/ab+cd', function (req, res) { このルート・パスは、`abcd`、`abxcd`、`abRABDOMcd`、`ab123cd` などをマッチングします。 ```js -app.get('/ab*cd', function (req, res) { +app.get('/ab*cd', (req, res) => { res.send('ab*cd') }) ``` @@ -132,17 +154,17 @@ app.get('/ab*cd', function (req, res) { このルート・パスは、`/abe` および `/abcde` をマッチングします。 ```js -app.get('/ab(cd)?e', function (req, res) { +app.get('/ab(cd)?e', (req, res) => { res.send('ab(cd)?e') }) ``` -次に、正規表現に基づくルート・パスの例を示します。 +### 次に、正規表現に基づくルート・パスの例を示します。 このルート・パスは、ルート名に「a」が含まれるすべてのものをマッチングします。 ```js -app.get(/a/, function (req, res) { +app.get(/a/, (req, res) => { res.send('/a/') }) ``` @@ -150,25 +172,25 @@ app.get(/a/, function (req, res) { このルート・パスは、`butterfly` および `dragonfly` をマッチングしますが、`butterflyman`、`dragonfly man` などはマッチングしません。 ```js -app.get(/.*fly$/, function (req, res) { +app.get(/.*fly$/, (req, res) => { res.send('/.*fly$/') }) ``` -

    ルート・パラメータ

    +

    ルート・パラメータ

    -ルート・パラメータは、URL内の指定された値を取得するために使用されるURLセグメントのことを言います。捕捉された値は`req.params`オブジェクトの中で、パスに指定されたルート・パラメータの名前をそれぞれのキーとして設定されます。 +Route parameters are named URL segments that are used to capture the values specified at their position in the URL. ルート・パラメータは、URL内の指定された値を取得するために使用されるURLセグメントのことを言います。捕捉された値は`req.params`オブジェクトの中で、パスに指定されたルート・パラメータの名前をそれぞれのキーとして設定されます。 ``` -ルート・パス: /users/:userId/books/:bookId -リクエストURL: http://localhost:3000/users/34/books/8989 +Route path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 req.params: { "userId": "34", "bookId": "8989" } ``` ルート・パラメータを使用してルートを定義するには、以下に示すようにルートのパスにルート・パラメータを指定するだけです。 ```js -app.get('/users/:userId/books/:bookId', function (req, res) { +app.get('/users/:userId/books/:bookId', (req, res) => { res.send(req.params) }) ``` @@ -180,158 +202,173 @@ app.get('/users/:userId/books/:bookId', function (req, res) { ハイフン(`-`)とドット(`.`)は文字通りに解釈されるので、有用な目的のためにルート・パラメータとともに使用することができます。 ``` -ルート・パス: /flights/:from-:to -リクエストURL: http://localhost:3000/flights/LAX-SFO +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO req.params: { "from": "LAX", "to": "SFO" } ``` ``` -ルート・パス: /plantae/:genus.:species -リクエストURL: http://localhost:3000/plantae/Prunus.persica +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica req.params: { "genus": "Prunus", "species": "persica" } ``` +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + ルート・パラメータで一致させることができる正確な文字列をより詳細に制御するために、括弧(`()`)内で正規表現を追加できます: ``` -ルート・パス: /user/:userId(\d+) -リクエストURL: http://localhost:3000/user/42 +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 req.params: {"userId": "42"} ``` -
    -正規表現は通常リテラル文字列の一部なので、\\d+のように\文字をバックスラッシュでエスケープしてください。 -
    +{% capture escape-advisory %} -
    -Express 4.xでは、正規表現の*文字は通常の方法で解釈されません。回避策として、*の代わりに{0,}を使用してください。これは、Express 5で修正される可能性があります。 -
    +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %}

    ルート・ハンドラー

    -リクエストを処理するために、[ミドルウェア](/{{ page.lang }}/guide/using-middleware.html)のように動作する複数のコールバック関数を指定できます。唯一の例外は、これらのコールバックが `next('route')` を呼び出して、残りのルート・コールバックをバイパスすることです。このメカニズムを使用して、ルートに事前条件を適用し、現在のルートで続行する理由がない場合に後続のルートに制御を渡すことができます。 +リクエストを処理するために、[ミドルウェア](/{{ page.lang }}/guide/using-middleware.html)のように動作する複数のコールバック関数を指定できます。唯一の例外は、これらのコールバックが `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. 次の例に示すように、ルート・ハンドラーの形式は、関数、関数の配列、または両方の組み合わせにすることができます。 -単一のコールバック関数で 1 つのルートを処理できます。次に例を示します。 +単一のコールバック関数で 1 つのルートを処理できます。次に例を示します。 For example: ```js -app.get('/example/a', function (req, res) { +app.get('/example/a', (req, res) => { res.send('Hello from A!') }) ``` -複数のコールバック関数で1つのルートを処理できます (必ず、`next` オブジェクトを指定してください)。次に例を示します。 +複数のコールバック関数で1つのルートを処理できます (必ず、`next` オブジェクトを指定してください)。次に例を示します。 For example: ```js -app.get('/example/b', function (req, res, next) { +app.get('/example/b', (req, res, next) => { console.log('the response will be sent by the next function ...') next() -}, function (req, res) { +}, (req, res) => { res.send('Hello from B!') }) ``` -コールバック関数の配列で 1 つのルートを処理できます。次に例を示します。 +コールバック関数の配列で 1 つのルートを処理できます。次に例を示します。 For example: ```js -var cb0 = function (req, res, next) { +const cb0 = function (req, res, next) { console.log('CB0') next() } -var cb1 = function (req, res, next) { +const cb1 = function (req, res, next) { console.log('CB1') next() } -var cb2 = function (req, res) { +const cb2 = function (req, res) { res.send('Hello from C!') } app.get('/example/c', [cb0, cb1, cb2]) ``` -独立した関数と、関数の配列の組み合わせで1つのルートを処理できます。次に例を示します。 +独立した関数と、関数の配列の組み合わせで1つのルートを処理できます。次に例を示します。 For example: ```js -var cb0 = function (req, res, next) { +const cb0 = function (req, res, next) { console.log('CB0') next() } -var cb1 = function (req, res, next) { +const cb1 = function (req, res, next) { console.log('CB1') next() } -app.get('/example/d', [cb0, cb1], function (req, res, next) { +app.get('/example/d', [cb0, cb1], (req, res, next) => { console.log('the response will be sent by the next function ...') next() -}, function (req, res) { +}, (req, res) => { res.send('Hello from D!') }) ```

    レスポンスメソッド

    -次の表に示すレスポンスオブジェクト (`res`) のメソッドは、レスポンスをクライアントに送信して、リクエストとレスポンスのサイクルを終了することができます。これらのメソッドのいずれもルート・ハンドラーから呼び出されない場合、クライアントリクエストはハングしたままになります。 +次の表に示すレスポンスオブジェクト (`res`) のメソッドは、レスポンスをクライアントに送信して、リクエストとレスポンスのサイクルを終了することができます。これらのメソッドのいずれもルート・ハンドラーから呼び出されない場合、クライアントリクエストはハングしたままになります。 If none of these methods are called from a route handler, the client request will be left hanging. -| メソッド | 説明 -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | ファイルのダウンロードのプロンプトを出します。 -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | レスポンスプロセスを終了します。 -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | JSON レスポンスを送信します。 -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | JSONP をサポートする JSON レスポンスを送信します。 -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | リクエストをリダイレクトします。 -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | ビュー・テンプレートをレンダリングします。 -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | さまざまなタイプのレスポンスを送信します。 -| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | ファイルをオクテット・ストリームとして送信します。 -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | レスポンスのステータスコードを設定して、そのストリング表現をレスポンス本文として送信します。 +| メソッド | 説明 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | ファイルのダウンロードのプロンプトを出します。 | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | レスポンスプロセスを終了します。 | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | JSON レスポンスを送信します。 | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | JSONP をサポートする JSON レスポンスを送信します。 | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | リクエストをリダイレクトします。 | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | ビュー・テンプレートをレンダリングします。 | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | さまざまなタイプのレスポンスを送信します。 | +| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | ファイルをオクテット・ストリームとして送信します。 | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | レスポンスのステータスコードを設定して、そのストリング表現をレスポンス本文として送信します。 |

    app.route()

    -`app.route()` を使用して、ルート・パスの連結可能なルート・ハンドラーを作成できます。 -パスは単一の場所で指定されるため、モジュール式のルートを作成すると、便利であるほか、冗長性とタイプミスを減らすことができます。ルートについて詳しくは、[Router() 資料](/{{ page.lang }}/4x/api.html#router)を参照してください。 +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](/{{ page.lang }}/5x/api.html#router). 次に、`app.route()` を使用して定義された、チェーニングされたルート・ハンドラーの例を示します。 ```js app.route('/book') - .get(function (req, res) { + .get((req, res) => { res.send('Get a random book') }) - .post(function (req, res) { + .post((req, res) => { res.send('Add a book') }) - .put(function (req, res) { + .put((req, res) => { res.send('Update the book') }) ```

    express.Router

    -モジュール式のマウント可能なルート・ハンドラーを作成するには、`express.Router` クラスを使用します。`Router` インスタンスは、完全なミドルウェアおよびルーティング・システムです。そのため、よく「ミニアプリケーション」と呼ばれます。 +モジュール式のマウント可能なルート・ハンドラーを作成するには、`express.Router` クラスを使用します。`Router` インスタンスは、完全なミドルウェアおよびルーティング・システムです。そのため、よく「ミニアプリケーション」と呼ばれます。 A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app". 次の例では、ルーターをモジュールとして作成し、その中にミドルウェア関数をロードして、いくつかのルートを定義し、ルート・モジュールをメインアプリケーションのパスにマウントします。 アプリケーション・ディレクトリーに次の内容で `birds.js` というルーター・ファイルを作成します。 ```js -var express = require('express') -var router = express.Router() +const express = require('express') +const router = express.Router() // middleware that is specific to this router -router.use(function timeLog (req, res, next) { +const timeLog = (req, res, next) => { console.log('Time: ', Date.now()) next() -}) +} +router.use(timeLog) + // define the home page route -router.get('/', function (req, res) { +router.get('/', (req, res) => { res.send('Birds home page') }) // define the about route -router.get('/about', function (req, res) { +router.get('/about', (req, res) => { res.send('About birds') }) @@ -341,9 +378,17 @@ module.exports = router 次に、ルーター・モジュールをアプリケーションにロードします。 ```js -var birds = require('./birds') +const birds = require('./birds') + // ... + app.use('/birds', birds) ``` これで、アプリケーションは、`/birds` および `/birds/about` に対するリクエストを処理するほか、ルートに固有の `timeLog` ミドルウェア関数を呼び出すことができるようになります。 + +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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/ja/guide/using-middleware.md b/ja/guide/using-middleware.md old mode 100755 new mode 100644 index aa47a00e91..1210706ee1 --- a/ja/guide/using-middleware.md +++ b/ja/guide/using-middleware.md @@ -1,118 +1,150 @@ --- layout: page title: Express ミドルウェアの使用 +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: ja +redirect_from: " " --- # ミドルウェアの使用 Express は、それ自体では最小限の機能を備えたルーティングとミドルウェアの Web フレームワークです。Express アプリケーションは基本的に一連のミドルウェア関数呼び出しです。 -*ミドルウェア* 関数は、[requestオブジェクト](/{{ page.lang }}/4x/api.html#req) (`req`)、[responseオブジェクト](/{{ page.lang }}/4x/api.html#res) (`res`)、およびアプリケーションのリクエストレスポンスサイクルにおける次のミドルウェア関数に対するアクセス権限を持つ関数です。次のミドルウェア関数は一般的に、`next` という変数で表されます。 +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#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`. ミドルウェア関数は以下のタスクを実行できます。 -* 任意のコードを実行する。 -* リクエストオブジェクトとレスポンスオブジェクトを変更する。 -* リクエストレスポンスサイクルを終了する。 -* スタック内の次のミドルウェア関数を呼び出す。 +- 任意のコードを実行する。 +- リクエストオブジェクトとレスポンスオブジェクトを変更する。 +- リクエストレスポンスサイクルを終了する。 +- スタック内の次のミドルウェア関数を呼び出す。 -現在のミドルウェア関数がリクエストレスポンスサイクルを終了しない場合は、`next()` を呼び出して、次のミドルウェア関数に制御を渡す必要があります。そうしないと、リクエストはハングしたままになります。 +現在のミドルウェア関数がリクエストレスポンスサイクルを終了しない場合は、`next()` を呼び出して、次のミドルウェア関数に制御を渡す必要があります。そうしないと、リクエストはハングしたままになります。 Otherwise, the request will be left hanging. Express アプリケーションは、以下のタイプのミドルウェアを使用できます。 - - [アプリケーション・レベルのミドルウェア](#middleware.application) - - [ルーター・レベルのミドルウェア](#middleware.router) - - [エラー処理ミドルウェア](#middleware.error-handling) - - [標準装備のミドルウェア](#middleware.built-in) - - [サード・パーティー・ミドルウェア](#middleware.third-party) +- [アプリケーション・レベルのミドルウェア](#middleware.application) +- [ルーター・レベルのミドルウェア](#middleware.router) +- [エラー処理ミドルウェア](#middleware.error-handling) +- [標準装備のミドルウェア](#middleware.built-in) +- [サード・パーティー・ミドルウェア](#middleware.third-party) アプリケーション・レベルとルーター・レベルのミドルウェアは、オプションのマウント・パスを指定してロードできます。 また、一連のミドルウェア関数を一緒にロードできます。こうすると、マウント・ポイントにミドルウェア・システムのサブスタックが作成されます。 +You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point.

    アプリケーション・レベルのミドルウェア

    -`app.use()` 関数と `app.METHOD()` 関数を使用して、アプリケーション・レベルのミドルウェアを [appオブジェクト](/{{ page.lang }}/4x/api.html#app) のインスタンスにバインドします。ここで、`METHOD` は、ミドルウェア関数が小文字で処理するリクエスト (GET、PUT、POST など) の HTTP メソッドです。 +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. -次の例は、マウント・パスを指定しないミドルウェア関数を示しています。この関数は、アプリケーションがリクエストを受け取るたびに実行されます。 +This example shows a middleware function with no mount path. The function is executed every time the app receives a request. ```js -var app = express() +const express = require('express') +const app = express() -app.use(function (req, res, next) { +app.use((req, res, next) => { console.log('Time:', Date.now()) next() }) ``` -次の例は、`/user/:id` パスにマウントされたミドルウェア関数を示しています。この関数は、`/user/:id` パスに対するすべてのタイプの HTTP リクエストで実行されます。 +This example shows a middleware function mounted on the `/user/:id` path. 次の例は、`/user/:id` パスにマウントされたミドルウェア関数を示しています。この関数は、`/user/:id` パスに対するすべてのタイプの HTTP リクエストで実行されます。 ```js -app.use('/user/:id', function (req, res, next) { +app.use('/user/:id', (req, res, next) => { console.log('Request Type:', req.method) next() }) ``` -次の例は、ルートとそのハンドラー関数 (ミドルウェア・システム) を示しています。この関数は、`/user/:id` パスへの GET リクエストを処理します。 +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', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { res.send('USER') }) ``` -次に、マウント・パスを指定して、一連のミドルウェア関数をマウント・ポイントにロードする例を示します。 -`/user/:id` パスへのすべてのタイプの HTTP リクエストに関するリクエスト情報を出力するミドルウェア・サブスタックを示しています。 +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. ```js -app.use('/user/:id', function (req, res, next) { +app.use('/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl) next() -}, function (req, res, next) { +}, (req, res, next) => { console.log('Request Type:', req.method) next() }) ``` -ルート・ハンドラーを使用すると、パスに複数のルートを定義できます。下記の例では、`/user/:id` パスへの GET リクエストに 2 つのルートを定義しています。2 番目のルートは、問題を発生させるものではありませんが、最初のルートがリクエストレスポンスサイクルを終了するため、呼び出されることはありません。 +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. 次の例は、`/user/:id` パスへの GET リクエストを処理するミドルウェア・サブスタックを示しています。 ```js -app.get('/user/:id', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { console.log('ID:', req.params.id) next() -}, function (req, res, next) { +}, (req, res, next) => { res.send('User Info') }) // handler for the /user/:id path, which prints the user ID -app.get('/user/:id', function (req, res, next) { - res.end(req.params.id) +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) }) ``` ルーター・ミドルウェア・スタックの残りのミドルウェア関数をスキップするには、`next('route')` を呼び出して、次のルートに制御を渡します。 **注**: `next('route')` は、`app.METHOD()` 関数または `router.METHOD()` 関数を使用してロードされたミドルウェア関数でのみ機能します。 +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} + 次の例は、`/user/:id` パスへの GET リクエストを処理するミドルウェア・サブスタックを示しています。 ```js -app.get('/user/:id', function (req, res, next) { +app.get('/user/:id', (req, res, next) => { // if the user ID is 0, skip to the next route - if (Number(req.params.id) === 0) next('route') + if (req.params.id === '0') next('route') // otherwise pass the control to the next middleware function in this stack else next() -}, function (req, res, next) { - // render a regular page - res.render('regular') +}, (req, res, next) => { + // send a regular response + res.send('regular') }) -// handler for the /user/:id path, which renders a special page -app.get('/user/:id', function (req, res, next) { - res.render('special') +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +次の例は、ルートとそのハンドラー関数 (ミドルウェア・システム) を示しています。この関数は、`/user/:id` パスへの GET リクエストを処理します。 + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') }) ``` @@ -121,7 +153,7 @@ app.get('/user/:id', function (req, res, next) { ルーター・レベルのミドルウェアは、`express.Router()` のインスタンスにバインドされる点を除き、アプリケーション・レベルのミドルウェアと同じように動作します。 ```js -var router = express.Router() +const router = express.Router() ``` `router.use()` 関数と `router.METHOD()` 関数を使用して、ルーター・レベルのミドルウェアをロードします。 @@ -129,37 +161,38 @@ var router = express.Router() 次のコードの例では、ルーター・レベルのミドルウェアを使用して、上記のアプリケーション・レベルのミドルウェアで示されているミドルウェア・システムを複製します。 ```js -var app = express() -var router = express.Router() +const express = require('express') +const app = express() +const router = express.Router() // a middleware function with no mount path. This code is executed for every request to the router -router.use(function (req, res, next) { +router.use((req, res, next) => { console.log('Time:', Date.now()) next() }) // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path -router.use('/user/:id', function (req, res, next) { +router.use('/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl) next() -}, function (req, res, next) { +}, (req, res, next) => { console.log('Request Type:', req.method) next() }) // a middleware sub-stack that handles GET requests to the /user/:id path -router.get('/user/:id', function (req, res, next) { +router.get('/user/:id', (req, res, next) => { // if the user ID is 0, skip to the next router - if (Number(req.params.id) === 0) next('route') + if (req.params.id === '0') next('route') // otherwise pass control to the next middleware function in this stack else next() -}, function (req, res, next) { +}, (req, res, next) => { // render a regular page res.render('regular') }) // handler for the /user/:id path, which renders a special page -router.get('/user/:id', function (req, res, next) { +router.get('/user/:id', (req, res, next) => { console.log(req.params.id) res.render('special') }) @@ -170,24 +203,25 @@ app.use('/', router) ルータのミドルウェア機能の残りの部分をスキップするには、`next('router')`を呼び出してルータインスタンスから制御を戻します。 -この例は、`/user/:id`パスに対するGET要求を処理するミドルウェアサブスタックを示しています。 +次の例は、`/user/:id` パスへの GET リクエストを処理するミドルウェア・サブスタックを示しています。 ```js -var app = express() -var router = express.Router() +const express = require('express') +const app = express() +const router = express.Router() // predicate the router with a check and bail out when needed -router.use(function (req, res, next) { +router.use((req, res, next) => { if (!req.headers['x-auth']) return next('router') next() }) -router.get('/', function (req, res) { +router.get('/user/:id', (req, res) => { res.send('hello, user!') }) // use the router and 401 anything falling through -app.use('/admin', router, function (req, res) { +app.use('/admin', router, (req, res) => { res.sendStatus(401) }) ``` @@ -195,14 +229,13 @@ app.use('/admin', router, function (req, res) {

    エラー処理ミドルウェア

    - -エラー処理ミドルウェアは常に *4つ* の引数を使用します。エラー処理ミドルウェア関数として識別されるように 4 つの引数を指定する必要があります。`next` オブジェクトは、使用する必要がない場合でも、シグニチャーを維持するために指定する必要があります。指定しないと、`next` オブジェクトは通常のミドルウェアとして解釈され、エラーを処理できなくなります。 +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 -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) @@ -210,17 +243,17 @@ app.use(function (err, req, res, next) { エラー処理ミドルウェアについて詳しくは、[エラー処理](/{{ page.lang }}/guide/error-handling.html)を参照してください。 -

    標準装備のミドルウェア

    +

    Built-in middleware

    -バージョン 4.x 以降、Express は [Connect](https://github.com/senchalabs/connect) に依存しなくなりました。以前に Express に組み込まれていたすべてのミドルウェア関数は個別のモジュールになりました。[ミドルウェア関数のリスト](https://github.com/senchalabs/connect#middleware)を参照してください。 +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) に依存しなくなりました。以前に Express に組み込まれていたすべてのミドルウェア関数は個別のモジュールになりました。[ミドルウェア関数のリスト](https://github.com/senchalabs/connect#middleware)を参照してください。 Expressには、次のミドルウェア機能が組み込まれています。 -- [express.static](/en/4x/api.html#express.static) は、HTMLファイルや画像などの静的リソースを提供します -- [express.json](/en/4x/api.html#express.json) はJSONペイロードで受信したリクエストを解析します。**注:Express 4.16.0以降で利用可能** -- [express.urlencoded](/en/4x/api.html#express.urlencoded) は、URLエンコードされたペイロードで受信したリクエストを解析します。**注:Express 4.16.0以降で利用可能** +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** -

    サード・パーティー・ミドルウェア

    +

    Third-party middleware

    Express アプリケーションに機能を追加するには、サード・パーティー・ミドルウェアを使用します。 @@ -228,14 +261,14 @@ Express アプリケーションに機能を追加するには、サード・パ 次の例は、Cookie 解析ミドルウェア関数 `cookie-parser` のインストールおよびロードを示しています。 -```sh +```bash $ npm install cookie-parser ``` ```js -var express = require('express') -var app = express() -var cookieParser = require('cookie-parser') +const express = require('express') +const app = express() +const cookieParser = require('cookie-parser') // load the cookie-parsing middleware app.use(cookieParser()) diff --git a/ja/guide/using-template-engines.md b/ja/guide/using-template-engines.md old mode 100755 new mode 100644 index b0c3e51e84..d02b0c6410 --- a/ja/guide/using-template-engines.md +++ b/ja/guide/using-template-engines.md @@ -1,40 +1,36 @@ --- layout: page title: Express でのテンプレート・エンジンの使用 +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: ja +redirect_from: " " --- # Express でのテンプレート・エンジンの使用 -_テンプレートエンジン_ を使用すると、アプリケーションで静的なテンプレートファイルを使用できます。実行時に、テンプレートエンジンはテンプレートファイルの変数を実際の値に置き換え、テンプレートをクライアントに送信するHTMLファイルに変換します。このアプローチにより、HTMLページの設計が容易になります。 +A _template engine_ enables you to use static template files in your application. _テンプレートエンジン_ を使用すると、アプリケーションで静的なテンプレートファイルを使用できます。実行時に、テンプレートエンジンはテンプレートファイルの変数を実際の値に置き換え、テンプレートをクライアントに送信するHTMLファイルに変換します。このアプローチにより、HTMLページの設計が容易になります。 +This approach makes it easier to design an HTML page. Expressで動作する一般的なテンプレートエンジンには、[Pug](https://pugjs.org/api/getting-started.html)、[Mustache](https://www.npmjs.com/package/mustache)、[EJS](https://www.npmjs.com/package/ejs)があります。[Expressアプリケーションジェネレータ](/{{ page.lang }}/starter/generator.html)は[Jade](https://www.npmjs.com/package/jade)をデフォルトとして使用しますが、いくつかの他のものもサポートしています。 -Expressで使用できるテンプレートエンジンのリストについては、[テンプレートエンジン (Express wiki)](https://github.com/expressjs/express/wiki#template-engines)を参照してください。また、[JavaScript テンプレートエンジンの比較: Jade, Mustache, Dust など](https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/)も参照してください。 - -
    - -**注**:Jadeは[Pug](https://www.npmjs.com/package/pug)に改名されました。あなたはアプリで引き続きJadeを使うことができ、うまく動くでしょう。しかしながら、テンプレートエンジンを最新のバージョンにアップデートしたい場合は、アプリでJadeをPugに置き換える必要があります。 - -
    - テンプレートファイルをレンダリングするには、次の[アプリケーション設定プロパティ](/{{ page.lang }}/4x/api.html#app.set)を設定し、ジェネレータで作成されたデフォルトアプリの`app.js`にセットします。 -* `views`はテンプレートファイルが置かれているディレクトリ。例:`app.set('views', './views')`。これは、デフォルトではアプリケーションのルートディレクトリ内の`views`ディレクトリになります -* `view engine`は使用するテンプレートエンジン。たとえば、Pugテンプレートエンジンを使用するには、`app.set('view engine', 'pug')`を使用します +- `views`, the directory where the template files are located. `views`はテンプレートファイルが置かれているディレクトリ。例:`app.set('views', './views')`。これは、デフォルトではアプリケーションのルートディレクトリ内の`views`ディレクトリになります + This defaults to the `views` directory in the application root directory. +- `view engine`, the template engine to use. `view engine`は使用するテンプレートエンジン。たとえば、Pugテンプレートエンジンを使用するには、`app.set('view engine', 'pug')`を使用します 次に、対応するテンプレートエンジンnpmパッケージをインストールします。たとえばPugをインストールするには: -```sh +```bash $ npm install pug --save ``` -
    - -Pug などの Express 対応テンプレート・エンジンは、`__express(filePath, options, callback)` という関数をエクスポートします。この関数は、テンプレート・コードをレンダリングするために `res.render()` 関数によって呼び出されます。 +
    Pug などの Express 対応テンプレート・エンジンは、`__express(filePath, options, callback)` という関数をエクスポートします。この関数は、テンプレート・コードをレンダリングするために `res.render()` 関数によって呼び出されます。 一部のテンプレート・エンジンは、この規則に従いません。[Consolidate.js](https://www.npmjs.org/package/consolidate) ライブラリーは、すべての一般的な Node.js テンプレート・エンジンをマップすることで、この規則に従います。そのため、Express 内でシームレスに動作します。 +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. +
    ビュー・エンジンが設定された後は、アプリケーションでエンジンを指定したり、テンプレート・エンジンをロードしたりする必要はありません。(上記の例に対応した) 下記のように、Express がモジュールを内部的にロードします。 @@ -53,16 +49,15 @@ html h1= message ``` -次に、`index.pug` ファイルをレンダリングするためのルートを作成します。`view engine` プロパティーが設定されていない場合は、`view` ファイルの拡張子を指定する必要があります。そうでない場合は、省略できます。 +Create a route to render the `index.pug` file. If the `view engine` property is not set, +you must specify the extension of the `view` file. Otherwise, you can omit it. ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index', { title: 'Hey', message: 'Hello there!' }) }) ``` ホーム・ページに要求すると、`index.pug` ファイルは HTML としてレンダリングされます。 -注:view engine のキャッシュは、テンプレートの出力内容をキャッシュしません。基本となるテンプレート自体だけです。このビューは、キャッシュがオンの場合でも、すべてのリクエストで再レンダリングされます。 - -Express でのテンプレート・エンジンの動作について詳しくは、[Express 用のテンプレート・エンジンの開発](/{{ page.lang }}/advanced/developing-template-engines.html)を参照してください。 +注:view engine のキャッシュは、テンプレートの出力内容をキャッシュしません。基本となるテンプレート自体だけです。このビューは、キャッシュがオンの場合でも、すべてのリクエストで再レンダリングされます。 The view is still re-rendered with every request even when the cache is on. diff --git a/ja/guide/writing-middleware.md b/ja/guide/writing-middleware.md old mode 100755 new mode 100644 index 65aac1d49b..265b6b9c52 --- a/ja/guide/writing-middleware.md +++ b/ja/guide/writing-middleware.md @@ -1,33 +1,35 @@ --- layout: page title: Express アプリケーションで使用するミドルウェアの作成 +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: ja +redirect_from: " " --- # Express アプリケーションで使用するミドルウェアの作成

    概説

    -*ミドルウェア* 関数は、[リクエストオブジェクト](/{{ page.lang }}/4x/api.html#req) (`req`)、[レスポンスオブジェクト](/{{ page.lang }}/4x/api.html#res) (`res`)、およびアプリケーションのリクエストレスポンスサイクルにおける次のミドルウェア関数に対するアクセス権限を持つ関数です。次のミドルウェア関数は一般的に、`next` という変数で表されます。 +_ミドルウェア_ 関数は、[リクエストオブジェクト](/{{ page.lang }}/4x/api.html#req) (`req`)、[レスポンスオブジェクト](/{{ page.lang }}/4x/api.html#res) (`res`)、およびアプリケーションのリクエストレスポンスサイクルにおける次のミドルウェア関数に対するアクセス権限を持つ関数です。次のミドルウェア関数は一般的に、`next` という変数で表されます。 The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware. ミドルウェア関数は以下のタスクを実行できます。 -* 任意のコードを実行する。 -* リクエストオブジェクトとレスポンスオブジェクトを変更する。 -* リクエストレスポンスサイクルを終了する。 -* スタック内の次のミドルウェアを呼び出す。 +- 任意のコードを実行する。 +- リクエストオブジェクトとレスポンスオブジェクトを変更する。 +- リクエストレスポンスサイクルを終了する。 +- スタック内の次のミドルウェアを呼び出す。 -現在のミドルウェア関数がリクエストレスポンスサイクルを終了しない場合は、`next()` を呼び出して、次のミドルウェア関数に制御を渡す必要があります。そうしないと、リクエストはハングしたままになります。 +現在のミドルウェア関数がリクエストレスポンスサイクルを終了しない場合は、`next()` を呼び出して、次のミドルウェア関数に制御を渡す必要があります。そうしないと、リクエストはハングしたままになります。 Otherwise, the request will be left hanging. 次の例は、ミドルウェア関数呼び出しの要素を示しています。 +
    -
    ミドルウェア関数が適用されるパス (ルート)。
    @@ -40,16 +42,22 @@ lang: ja
    ミドルウェア関数への HTTP リクエスト引数 (慣習的に「req」と呼ばれます)。
    - +
    +Elements of a middleware function call -
    ミドルウェア関数が適用される HTTP メソッド。
    +
    ミドルウェア関数が適用される HTTP メソッド。
    +
    + +Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error.

    -次に、簡単な「Hello World」Expressアプリケーションの例を示します。 この記事の残りの部分では、アプリケーションに2つのミドルウェア関数、つまり単純なログメッセージを出力する`myLogger`と、HTTP要求のタイムスタンプを表示する`requestTime`という2つのミドルウェア関数を定義して追加します。 +Here is an example of a simple "Hello World" Express application. +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. ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('Hello World!') }) @@ -57,37 +65,37 @@ app.listen(3000) ```

    ミドルウェア関数 myLogger

    - -次に、"myLogger"というミドルウェア関数の簡単な例を示します。この関数は、アプリケーションへのリクエストがそれを通過するときに、単に "LOGGED"を出力します。ミドルウェア関数は、`myLogger`という名前の変数に割り当てられます。 +Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. 次に、"myLogger"というミドルウェア関数の簡単な例を示します。この関数は、アプリケーションへのリクエストがそれを通過するときに、単に "LOGGED"を出力します。ミドルウェア関数は、`myLogger`という名前の変数に割り当てられます。 ```js -var myLogger = function (req, res, next) { +const myLogger = function (req, res, next) { console.log('LOGGED') next() } ```
    - -上記の `next()` の呼び出しに注意してください。この関数を呼び出すと、アプリケーション内の次のミドルウェア関数が呼び出されます。 -`next()` 関数は、Node.js または Express API の一部ではありませんが、ミドルウェア関数に渡される 3 番目の引数です。`next()` 関数に任意の名前を付けることは可能ですが、慣習的に常に「next」と呼ばれます。混乱を避けるために、常にこの規則に従ってください。 +Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. +The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next". +To avoid confusion, always use this convention.
    +To load the middleware function, call `app.use()`, specifying the middleware function. ミドルウェア関数をロードするには、ミドルウェア関数を指定して `app.use()` を呼び出します。 例えば、次のコードは、ルート・パス (/) へのルートの前に `myLogger` ミドルウェア関数をロードします。 ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() -var myLogger = function (req, res, next) { +const myLogger = function (req, res, next) { console.log('LOGGED') next() } app.use(myLogger) -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.send('Hello World!') }) @@ -107,28 +115,28 @@ app.listen(3000) 次に、「requestTime」というミドルウェア関数を作成し、`requestTime`というプロパティとしてリクエストオブジェクトに追加します。 ```js -var requestTime = function (req, res, next) { +const requestTime = function (req, res, next) { req.requestTime = Date.now() next() } ``` -これで、アプリケーションが `requestTime` ミドルウェア関数を使用するようになります。また、ルート・パス・ルートのコールバック関数は、ミドルウェア関数が `req` (リクエストオブジェクト) に追加するプロパティーを使用します。 +The app now uses the `requestTime` middleware function. これで、アプリケーションが `requestTime` ミドルウェア関数を使用するようになります。また、ルート・パス・ルートのコールバック関数は、ミドルウェア関数が `req` (リクエストオブジェクト) に追加するプロパティーを使用します。 ```js -var express = require('express') -var app = express() +const express = require('express') +const app = express() -var requestTime = function (req, res, next) { +const requestTime = function (req, res, next) { req.requestTime = Date.now() next() } app.use(requestTime) -app.get('/', function (req, res) { - var responseText = 'Hello World!
    ' - responseText += 'Requested at: ' + req.requestTime + '' +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` res.send(responseText) }) @@ -137,6 +145,52 @@ app.listen(3000) アプリケーションのルートにリクエストすると、アプリケーションは、リクエストのタイムスタンプをブラウザーに表示します。 +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    + リクエストオブジェクト、レスポンスオブジェクト、スタック内の次のミドルウェア関数、および Node.js API を利用できるため、ミドルウェア関数が持つ可能性は無限です。 Express ミドルウェアについて詳しくは、[Express ミドルウェアの使用](/{{ page.lang }}/guide/using-middleware.html)を参照してください。 @@ -159,7 +213,7 @@ module.exports = function (options) { ミドルウェアは以下のように使用できるようになりました。 ```js -var mw = require('./my-middleware.js') +const mw = require('./my-middleware.js') app.use(mw({ option1: '1', option2: '2' })) ``` diff --git a/ja/index.md b/ja/index.md index 9ce7d9fd2a..7699460f5e 100644 --- a/ja/index.md +++ b/ja/index.md @@ -1,53 +1,61 @@ --- layout: home -title: Express - Node.js Web アプリケーション・フレームワーク +title: Express - Node.js web application framework +description: "Express is a fast, unopinionated, minimalist web framework for Node.js, providing a robust set of features for web and mobile applications." menu: home -lang: ja +redirect_from: " " ---
    - {% include header/header-{{ page.lang }}.html %} -
    - - Node.js のための高速で、革新的な、最小限のWebフレームワーク + +

    Fast, unopinionated, minimalist web framework for Node.js

    -
    $ npm install express --save
    +
    $ npm install express --save
    -
    - + +
    + +```javascript +const express = require('express') +const app = express() +const port = 3000 + +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` +
    - -
    - Express の資料は、他の言語 ([スペイン語](/es)、[日本語](/ja)、[ロシア語](/ru)、[中国語](/zh-cn)、[韓国語](/ko)、[ポルトガル語](/pt-br)) でも提供されています。 +{% if site.announcement %} +
    + {% include announcement.html %}
    +{% endif %}
    -
    -
    -

    Web アプリケーション

    Express は、Web アプリケーションとモバイル・アプリケーション向けの一連の堅固な機能を提供する最小限で柔軟な Node.js Web アプリケーション・フレームワークです。 -
    - -
    -

    API

    無数の HTTP ユーティリティー・メソッドとミドルウェアを自由に使用できるため、堅固な API を迅速かつ容易に作成できます。 -
    - -
    -

    パフォーマンス

    Express は、ユーザーが使い慣れている Node.js の機能をわかりやすくし、基礎的な Web アプリケーション機能をシンプルな階層で提供します。 -
    - - +
    +

    Web Applications

    Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. +
    +
    +

    APIs

    With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy. +
    +
    +

    Performance

    Express provides a thin layer of fundamental web application features, without obscuring Node.js features that you know and love. +
    +
    +

    ミドルウェア

    + Express is a lightweight and flexible routing framework with minimal core features + meant to be augmented through the use of Express middleware modules. +
    -
    diff --git a/ja/resources/community.md b/ja/resources/community.md old mode 100755 new mode 100644 index 19fd48fd19..34772bb7ef --- a/ja/resources/community.md +++ b/ja/resources/community.md @@ -1,34 +1,88 @@ --- layout: page title: Express のコミュニティー +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: ja +redirect_from: " " --- # コミュニティー -## メーリング・リスト +## Technical committee -[Google グループ](https://groups.google.com/group/express-js)で、2000 名を超える Express ユーザーの中に参加したり、5000 件を超えるディスカッションを参照したりすることができます。 +The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, +and other issues relevant to the Express project. Each meeting is typically announced in an +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is +open to all observers. -## Gitter +The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -[expressjs/express chatroom](https://gitter.im/expressjs/express) は、Express に関連する日常的なディスカッションに参加したい開発者に適しています。 +Members of the Express technical committee are: -## IRC チャネル +**Active:** -毎日、数百名の開発者が #express on freenode で時間を過ごしています。 -フレームワークに関する質問がある場合は、すぐに参加してください。フィードバックを素早く得られます。 +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida -## 例 +**Inactive:** -API の設計や認証からテンプレート・エンジンの統合まで、あらゆるものを扱っている数十の Express アプリケーションの[例](https://github.com/expressjs/express/tree/master/examples)をリポジトリーでご覧ください。 +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express is made of many modules + +この活気あるコミュニティーでは、さまざまな拡張機能、[ミドルウェア・モジュール](/{{ page.lang }}/resources/middleware.html)、高水準のフレームワークが作成されています。[Wiki](https://github.com/expressjs/express/wiki) で確認してください。 + +Additionally, the Express community maintains modules in these two GitHub orgs: + +- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. + +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). ## 問題 バグに思われるものが見つかったり、単に機能を要求したりする場合は、[問題のキュー](https://github.com/expressjs/express/issues)でチケットをオープンしてください。 -## サード・パーティー +## 例 -この活気あるコミュニティーでは、さまざまな拡張機能、[ミドルウェア・モジュール](/{{ page.lang }}/resources/middleware.html)、高水準のフレームワークが作成されています。[Wiki](https://github.com/expressjs/express/wiki) で確認してください。 +API の設計や認証からテンプレート・エンジンの統合まで、あらゆるものを扱っている数十の Express アプリケーションの[例](https://github.com/expressjs/express/tree/master/examples)をリポジトリーでご覧ください。 + +## Github Discussions + +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. + +# Branding of Express.js + +## Express.js Logo + +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/ja/resources/contributing.md b/ja/resources/contributing.md new file mode 100644 index 0000000000..e37cee3122 --- /dev/null +++ b/ja/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/ja/resources/glossary.md b/ja/resources/glossary.md old mode 100755 new mode 100644 index ed030d4541..b305a8b759 --- a/ja/resources/glossary.md +++ b/ja/resources/glossary.md @@ -1,55 +1,64 @@ --- layout: page title: Express の用語集 +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: ja +redirect_from: " " --- # 用語集 ### アプリケーション -一般に、特定の目的で操作を実行するよう設計された 1 つ以上のプログラム。Express のコンテキストでは、Node.js プラットフォームで稼働する Express API を使用するプログラム。[アプリケーション・オブジェクト](/{{ page.lang }}/api.html#express)と呼ばれることもある。 +In general, one or more programs that are designed to carry out operations for a specific purpose. 一般に、特定の目的で操作を実行するよう設計された 1 つ以上のプログラム。Express のコンテキストでは、Node.js プラットフォームで稼働する Express API を使用するプログラム。[アプリケーション・オブジェクト](/{{ page.lang }}/api.html#express)と呼ばれることもある。 Might also refer to an [app object](/{{ page.lang }}/api.html#express). ### API -アプリケーション・プログラミング・インターフェース。最初に使用するときは、略語のスペルを略さない。 +Application programming interface. Spell out the abbreviation when it is first used. ### Express -特定の意見に固執しない、Node.js アプリケーション向けの高速で最小限の Web フレームワーク。一般に、「Express」の望ましい呼び方は「Express.js」であるが、後者でも問題はない。 +特定の意見に固執しない、Node.js アプリケーション向けの高速で最小限の Web フレームワーク。一般に、「Express」の望ましい呼び方は「Express.js」であるが、後者でも問題はない。 In general, "Express" is preferred to "Express.js," though the latter is acceptable. ### libuv 主に Node.js で使用するために開発された、非同期入出力に重点を置いたマルチプラットフォーム・サポート・ライブラリー。 -### ミドルウェア +### middleware -最後のリクエストハンドラーの前に Express ルーティング層によって呼び出される関数。そのため、未加工要求と最後の目的のルートの間に配置される。ミドルウェアの用語に関しては、微妙な点がいくつかある。 +最後のリクエストハンドラーの前に Express ルーティング層によって呼び出される関数。そのため、未加工要求と最後の目的のルートの間に配置される。ミドルウェアの用語に関しては、微妙な点がいくつかある。 A few fine points of terminology around middleware: - * `var foo = require('middleware')` は、Node.js モジュールを*要求* または*使用* することで呼び出される。その後、通常はステートメント `var mw = foo()` がミドルウェアを返す。 - * `app.use(mw)` は、*グローバル処理スタックにミドルウェアを追加* することで呼び出される。 - * `app.get('/foo', mw, function (req, res) { ... })` は、*「GET /foo」処理スタックにミドルウェアを追加* することで呼び出される。 +- `var foo = require('middleware')` は、Node.js モジュールを_要求_ または_使用_ することで呼び出される。その後、通常はステートメント `var mw = foo()` がミドルウェアを返す。 Then the statement `var mw = foo()` typically returns the middleware. +- `app.use(mw)` は、_グローバル処理スタックにミドルウェアを追加_ することで呼び出される。 +- `app.get('/foo', mw, function (req, res) { ... })` は、_「GET /foo」処理スタックにミドルウェアを追加_ することで呼び出される。 ### Node.js -スケーラブルなネットワーク・アプリケーションを作成するために使用されるソフトウェア・プラットフォーム。Node.js は、スクリプト言語として JavaScript を使用し、ノンブロッキング入出力と単一スレッドのイベント・ループを通して高スループットを実現する。[nodejs.org](http://nodejs.org/) を参照。**使用上の注意**: 初回は「Node.js」を使用し、その後は「Node」を使用する。 +A software platform that is used to build scalable network applications. スケーラブルなネットワーク・アプリケーションを作成するために使用されるソフトウェア・プラットフォーム。Node.js は、スクリプト言語として JavaScript を使用し、ノンブロッキング入出力と単一スレッドのイベント・ループを通して高スループットを実現する。[nodejs.org](http://nodejs.org/) を参照。**使用上の注意**: 初回は「Node.js」を使用し、その後は「Node」を使用する。 See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". ### オープン・ソース -形容詞として使用する場合は、ハイフンを付ける (例:「This is open-source software.」)。[Wikipedia の「Open-source software」](http://en.wikipedia.org/wiki/Open-source_software)を参照。注: 一般的にはこの用語にハイフンを付けないが、ここでは複合形容詞にハイフンを付けるという標準英語の規則に従う。 +When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). + +{% capture english-rules %} + +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. + +{% endcapture %} + +{% include admonitions/note.html content=english-rules %} ### リクエスト -HTTP リクエスト。クライアントは HTTP リクエストメッセージをサーバーに送信して、サーバーはレスポンスを返す。リクエストでは、いずれかの[リクエストメソッド](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) (GET、POST など) を使用する必要がある。 +An HTTP request. HTTP レスポンス。サーバーは、HTTP レスポンスメッセージをクライアントに返す。レスポンスにはリクエストの完了状況情報が含まれ、リクエストされた内容がメッセージの本文に入っている場合もある。 HTTP リクエスト。クライアントは HTTP リクエストメッセージをサーバーに送信して、サーバーはレスポンスを返す。リクエストでは、いずれかの[リクエストメソッド](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) (GET、POST など) を使用する必要がある。 ### レスポンス -HTTP レスポンス。サーバーは、HTTP レスポンスメッセージをクライアントに返す。レスポンスにはリクエストの完了状況情報が含まれ、リクエストされた内容がメッセージの本文に入っている場合もある。 +An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body. ### ルート -リソースを識別する URL の一部。例えば、`http://foo.com/products/id` の中では「/products/id」がルートである。 +Part of a URL that identifies a resource. リソースを識別する URL の一部。例えば、`http://foo.com/products/id` の中では「/products/id」がルートである。 ### ルーター diff --git a/ja/resources/learning.md b/ja/resources/learning.md deleted file mode 100755 index ccb165dda4..0000000000 --- a/ja/resources/learning.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: page -title: 追加学習 -menu: resources -lang: ja ---- - -# 追加学習 - -
    Disclaimer: Unendorsed community content.
    - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Node-tricks Blog: Express category](http://node-tricks.com/category/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/ja/resources/middleware.md b/ja/resources/middleware.md old mode 100755 new mode 100644 index 003bceaaa6..f6e625cbb8 --- a/ja/resources/middleware.md +++ b/ja/resources/middleware.md @@ -1,63 +1,44 @@ --- -layout: page +layout: middleware title: Express のミドルウェア +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: ja +redirect_from: " " +module: mw-home --- -# サード・パーティー・ミドルウェア +## Express のミドルウェア -下記に、いくつかの Express ミドルウェア・モジュールを挙げます。 +The Express middleware modules listed here are maintained by the +[Expressjs team](https://github.com/orgs/expressjs/people). - - [body-parser](https://github.com/expressjs/body-parser): 以前の `express.bodyParser`、`json`、`urlencoded`。以下も参照してください。 - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): 以前の `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): 最適なイメージ・サービス提供を実現する Connect/Express ミドルウェア・モジュール。可能な場合は、イメージを `.webp` または `.jxr` に切り替えてください。 - - [connect-timeout](https://github.com/expressjs/timeout): 以前の `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): 以前の `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): 以前の `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): 以前の `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): 以前の `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): テンプレート変数 (ローカル)、現行セッション、有用な要求データなどに関する情報を示すタブをアプリケーションに追加する小規模な開発ツール。 - - [express-partial-response](https://github.com/nemtsov/express-partial-response): Google API の Partial Response を使用することで、`fields` 照会ストリングに基づいて JSON 応答の一部をフィルターで除去するための Express ミドルウェア・モジュール。 - - [express-session](https://github.com/expressjs/session): 以前の `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): 複数ホストのサポート (例えば、cdn1.host.com、cdn2.host.com) を備え、静的資産に CDN を使用するための Express ミドルウェア・モジュール。 - - [express-slash](https://github.com/ericf/express-slash): 末尾スラッシュを厳密に処理するユーザー向けの Express ミドルウェア・モジュール。 - - [express-stormpath](https://github.com/stormpath/stormpath-express): ユーザー・ストレージ、認証、許可、SSO、データ・セキュリティーのための Express ミドルウェア・モジュール。 - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): 大文字を含む HTTP 要求を正規の小文字形式に変換するためのミドルウェア・モジュール。 - - [helmet](https://github.com/helmetjs/helmet): さまざまな HTTP ヘッダーを設定することでアプリケーションを保護する上で役立つモジュール。 - - [join-io](https://github.com/coderaiser/join-io "join-io"): 要求数を減らすために処理中にファイルを結合するモジュール。 - - [method-override](https://github.com/expressjs/method-override): 以前の `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): 以前の `logger` - - [passport](https://github.com/jaredhanson/passport): 認証のための Express ミドルウェア・モジュール。 - - [response-time](https://github.com/expressjs/response-time): 以前の `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): 以前の `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): 以前の `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): 静的コンテンツを提供するためのモジュール。 - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): 1 つ以上の外部ドメインに対するサポートを含む、静的資産の指紋認証 URL またはキャッシング・ヘッダー。 - - [vhost](https://github.com/expressjs/vhost): 以前の `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): ビューに共通ヘルパー・メソッドを提供する Express ミドルウェア・モジュール。 - - [sriracha-admin](https://github.com/hdngr/siracha): Mongoose 用の管理サイトを動的に生成する Express ミドルウェア・モジュール。 +| Middleware module | 説明 | +| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | -以前は Connect に組み込まれていた一部のミドルウェア・モジュールは、Connect/Express チームによってサポートされなくなっています。これらのモジュールは、代替のモジュールに置き換えられているか、より優れたモジュールに置き換えられる必要があります。以下のいずれかの代替モジュールを使用してください。 +## Additional middleware modules - - express.cookieParser - - [cookies](https://github.com/jed/cookies) および [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) +These are some additional popular middleware modules. -その他のミドルウェア・モジュールについては、下記を参照してください。 +{% include community-caveat.html %} - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| Middleware module | 説明 | +| ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet): さまざまな HTTP ヘッダーを設定することでアプリケーションを保護する上で役立つモジュール。 | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport): 認証のための Express ミドルウェア・モジュール。 | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/ja/resources/middleware/body-parser.md b/ja/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/ja/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/ja/resources/middleware/compression.md b/ja/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/ja/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/ja/resources/middleware/connect-rid.md b/ja/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/ja/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/ja/resources/middleware/cookie-parser.md b/ja/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/ja/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/ja/resources/middleware/cookie-session.md b/ja/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/ja/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/ja/resources/middleware/cors.md b/ja/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/ja/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/ja/resources/middleware/errorhandler.md b/ja/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/ja/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/ja/resources/middleware/method-override.md b/ja/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/ja/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/ja/resources/middleware/morgan.md b/ja/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/ja/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/ja/resources/middleware/multer.md b/ja/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/ja/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/ja/resources/middleware/response-time.md b/ja/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/ja/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/ja/resources/middleware/serve-favicon.md b/ja/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/ja/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/ja/resources/middleware/serve-index.md b/ja/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/ja/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/ja/resources/middleware/serve-static.md b/ja/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/ja/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/ja/resources/middleware/session.md b/ja/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/ja/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/ja/resources/middleware/timeout.md b/ja/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/ja/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/ja/resources/middleware/vhost.md b/ja/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/ja/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/ja/resources/utils.md b/ja/resources/utils.md new file mode 100644 index 0000000000..b4e0712dff --- /dev/null +++ b/ja/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/ja/starter/basic-routing.md b/ja/starter/basic-routing.md old mode 100755 new mode 100644 index 019ad12588..6acae388a9 --- a/ja/starter/basic-routing.md +++ b/ja/starter/basic-routing.md @@ -1,24 +1,24 @@ --- layout: page title: Express の基本的なルーティング +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: ja +redirect_from: " " --- # 基本的なルーティング -*ルーティング* とは、アプリケーションが特定のエンドポイントに対するクライアント要求に応答する方法として、URI (またはパス) と特定の HTTP 要求メソッド (GET、POST など) を決定することです。 +_ルーティング_ とは、アプリケーションが特定のエンドポイントに対するクライアント要求に応答する方法として、URI (またはパス) と特定の HTTP 要求メソッド (GET、POST など) を決定することです。 各ルートには、1 つ以上のハンドラー関数があり、それらはルートが一致したときに実行されます。 ルート定義では、次の構造を使用します。 -
    -
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` -各部分の意味は次のとおりです。 +Where: - `app` は、`express` のインスタンスです。 - `METHOD` は、[HTTP 要求メソッド](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) です。 @@ -26,49 +26,45 @@ app.METHOD(PATH, HANDLER) - `HANDLER` は、ルートが一致したときに実行される関数です。
    +This tutorial assumes that an instance of `express` named `app` is created and the server is running. このチュートリアルでは、`app` という名前の `express` のインスタンスが作成されていて、サーバーが稼働中であることを想定しています。アプリケーションの作成と開始に慣れていない場合は、[Hello World の例](/{{ page.lang }}/starter/hello-world.html) を参照してください。 +
    以下の例は、単純なルートの定義を示しています。 ホーム・ページで `Hello World!` と応答します。 -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -アプリケーションのホーム・ページであるルートのルート (`/`) で POST 要求に応答します。 +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` `/user` ルートに対する PUT 要求に応答します。 -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` `/user` ルートに対する DELETE 要求に応答します。 -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` ルーティングについて詳しくは、[ルーティング・ガイド](/{{ page.lang }}/guide/routing.html)を参照してください。 + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/ja/starter/examples.md b/ja/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/ja/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/ja/starter/faq.md b/ja/starter/faq.md old mode 100755 new mode 100644 index f3afdb96a2..fd51f13b05 --- a/ja/starter/faq.md +++ b/ja/starter/faq.md @@ -1,72 +1,98 @@ --- layout: page title: Express に関する FAQ +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: ja +redirect_from: " " --- -# FAQ +# よくある質問 ## どのようにしてアプリケーションを構成するのですか? -この質問に対する決定的な答えはありません。ご使用のアプリケーションや関与するチームの規模によって答えは異なります。可能な限り柔軟であるために、Express には、構造に関する前提がありません。 +There is no definitive answer to this question. The answer depends +on the scale of your application and the team that is involved. To be as +flexible as possible, Express makes no assumptions in terms of structure. -ルートやその他のアプリケーション固有のロジックは、必要な数だけのファイルや、任意のディレクトリー構造に存在できます。参考のために、以下の例を参照してください。 +ルートやその他のアプリケーション固有のロジックは、必要な数だけのファイルや、任意のディレクトリー構造に存在できます。参考のために、以下の例を参照してください。 View the following +examples for inspiration: -* [ルートのリスト](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [ルートのマップ](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [MVC スタイルのコントローラー](https://github.com/expressjs/express/tree/master/examples/mvc) +- [ルートのリスト](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [ルートのマップ](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [MVC スタイルのコントローラー](https://github.com/expressjs/express/tree/master/examples/mvc) また、これらのパターンを簡素化する、サード・パーティー製の Express 拡張版があります。 -* [Resourceful ルーティング](https://github.com/expressjs/express-resource) +- [Resourceful ルーティング](https://github.com/expressjs/express-resource) ## どのようにしてモデルを定義するのですか? -Express には、データベースの概念がありません。この概念はサード・パーティーの Node モジュールに任せられているため、ほとんどのデータベースとやりとりできます。 +Express には、データベースの概念がありません。この概念はサード・パーティーの Node モジュールに任せられているため、ほとんどのデータベースとやりとりできます。 This concept is +left up to third-party Node modules, allowing you to +interface with nearly any database. モデルに関する Express ベースのフレームワークについては、[LoopBack](http://loopback.io) を参照してください。 ## どのようにしてユーザーを認証するのですか? +Authentication is another opinionated area that Express does not +venture into. You may use any authentication scheme you wish. 認証は、Express が足を踏み入れていないもう 1 つの分野です。任意の認証スキームを使用できます。 単純なユーザー名/パスワードのスキームについては、[この例](https://github.com/expressjs/express/tree/master/examples/auth)を参照してください。 - ## Express はどのテンプレート・エンジンをサポートしているのですか? Express は、`(パス、ロケール、コールバック)` シグニチャーに準拠するすべてのテンプレート・エンジンをサポートします。 テンプレート・エンジンのインターフェースとキャッシングを正規化するには、[consolidate.js](https://github.com/visionmedia/consolidate.js) プロジェクトでサポートを参照してください。リストされていないテンプレート・エンジンでも Express シグニチャーをサポートしている可能性があります。 +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](/{{page.lang}}/guide/using-template-engines.html). ## どのようにして 404 応答に対応するのですか? -Express では、404 応答はエラーの結果ではありません。そのため、エラー・ハンドラー・ミドルウェアはそれらをキャプチャーしません。このように動作するのは、404 応答は単に追加の処理が存在しないことを示しているためです。つまり、Express は、すべてのミドルウェア関数とルートを実行して、そのいずれも応答しなかったことを検出したということです。404 応答に対応するには、スタックの最下部 (他のすべての関数の下) にミドルウェア関数を追加するだけですみます。 +Express では、404 応答はエラーの結果ではありません。そのため、エラー・ハンドラー・ミドルウェアはそれらをキャプチャーしません。このように動作するのは、404 応答は単に追加の処理が存在しないことを示しているためです。つまり、Express は、すべてのミドルウェア関数とルートを実行して、そのいずれも応答しなかったことを検出したということです。404 応答に対応するには、スタックの最下部 (他のすべての関数の下) にミドルウェア関数を追加するだけですみます。 This behavior is +because a 404 response simply indicates the absence of additional work to do; +in other words, Express has executed all middleware functions and routes, +and found that none of them responded. All you need to +do is add a middleware function at the very bottom of the stack (below all other functions) +to handle a 404 response: + +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## どのようにしてエラー・ハンドラーをセットアップするのですか? エラー処理ミドルウェアの定義方法は、他のミドルウェアと同じですが、引数の数が 3 つではなく 4 つである点が異なります。具体的には、シグニチャー `(err、req、res、next)` です。 -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` 詳細については、[エラー処理](/{{ page.lang }}/guide/error-handling.html)を参照してください。 ## どのようにしてプレーン HTML をレンダリングするのですか? -レンダリングしません。`res.render()` 関数で HTML を「レンダリング」する必要はありません。 +You don't! レンダリングしません。`res.render()` 関数で HTML を「レンダリング」する必要はありません。 特定のファイルがある場合は、`res.sendFile()` 関数を使用します。 ディレクトリーから多数の資産を提供する場合は、`express.static()` ミドルウェア関数を使用します。 +If you have a specific file, use the `res.sendFile()` function. +If you are serving many assets from a directory, use the `express.static()` +middleware function. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) には Node.js 0.10 以上が必要です。 +- [Express 5.x](/{{ page.lang }}/5x/api.html) には Node.js 18 以上が必要です。 + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/ja/starter/generator.md b/ja/starter/generator.md old mode 100755 new mode 100644 index c49a74625d..ff4c74552c --- a/ja/starter/generator.md +++ b/ja/starter/generator.md @@ -1,29 +1,34 @@ --- layout: page title: Express のアプリケーション生成プログラム +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: ja +redirect_from: " " --- # Express のアプリケーション生成プログラム アプリケーション生成プログラム・ツールの `express` を使用すると、アプリケーション・スケルトンを素早く作成できます。 -次のコマンドを使用して、`express` をインストールします。 +You can run the application generator with the `npx` command (available in Node.js 8.2.0). -
    -
    -$ npm install express-generator -g
    -
    -
    +```bash +$ npx express-generator +``` + +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` `-h` オプションを指定してコマンド・オプションを表示します。 -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -34,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` -例えば、以下のコマンドでは、現行作業ディレクトリーに _myapp_ という Express アプリケーションを作成します。 +例えば、以下のコマンドでは、現行作業ディレクトリーに _myapp_ という Express アプリケーションを作成します。 The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -64,40 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` 次に、依存関係をインストールします。 -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` -MacOS または Linux では、次のコマンドによってアプリケーションを実行します。 +Windows では、次のコマンドを使用します。 -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` -Windows では、次のコマンドを使用します。 +On Windows Command Prompt, use this command: -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` + +On Windows PowerShell, use this command: + +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` 次に、ブラウザーに `http://localhost:3000/` をロードして、アプリケーションにアクセスします。 生成されたアプリケーションには、以下のディレクトリー構造があります。 -
    -
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -117,9 +118,10 @@ Windows では、次のコマンドを使用します。
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    -ここで生成プログラムによって作成されたアプリケーション構造は、Express アプリケーションを作成するための数多くの方法の 1 つにすぎません。この構造を自由に使用したり、ニーズに合わせて変更したりしてください。 +The app structure created by the generator is just one of many ways to structure Express apps. Feel free to use this structure or modify it to best suit your needs.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/ja/starter/hello-world.md b/ja/starter/hello-world.md old mode 100755 new mode 100644 index d105c58d08..c572898b06 --- a/ja/starter/hello-world.md +++ b/ja/starter/hello-world.md @@ -1,22 +1,18 @@ --- layout: page title: Express の「Hello World」の例 +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: ja +redirect_from: " " --- # Hello World の例
    -ここで紹介するのは基本的に、作成できる最も単純な Express アプリケーションです。このアプリケーションは単一ファイル・アプリケーションであり、[Express ジェネレーター](/{{ page.lang }}/starter/generator.html) を使用して得られるものでは *ありません* 。このジェネレーターは、さまざまな目的で多数の JavaScript ファイル、Jade テンプレート、サブディレクトリーを使用する完全なアプリケーション用のスキャフォールディングを作成します。 +Embedded below is essentially the simplest Express app you can create. It is a single file app — _not_ what you'd get if you use the [Express generator](/{{ page.lang }}/starter/generator.html), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes.
    -最初に、`myapp` という名前のディレクトリーを作成して、そのディレクトリーに移動し、`npm init` を実行します。次に、[インストール・ガイド](/{{ page.lang }}/starter/installing.html)に従い、依存関係として `express` をインストールします。 - -`myapp` ディレクトリーで、`app.js` というファイルを作成して、以下のコードを追加します。 - -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -26,12 +22,17 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    -
    +``` + +This app starts a server and listens on port 3000 for connections. アプリケーションは、サーバーを始動して、ポート 3000 で接続を listen します。アプリケーションは、ルート URL (`/`) または_ルート_ に対する要求に「Hello World!」と応答します。その他すべてのパスについては、「**404 Not Found**」と応答します。 For every other path, it will respond with a **404 Not Found**. -アプリケーションは、サーバーを始動して、ポート 3000 で接続を listen します。アプリケーションは、ルート URL (`/`) または*ルート* に対する要求に「Hello World!」と応答します。その他すべてのパスについては、「**404 Not Found**」と応答します。 +### Running Locally + +最初に、`myapp` という名前のディレクトリーを作成して、そのディレクトリーに移動し、`npm init` を実行します。次に、[インストール・ガイド](/{{ page.lang }}/starter/installing.html)に従い、依存関係として `express` をインストールします。 Then, install `express` as a dependency, as per the [installation guide](/{{ page.lang }}/starter/installing.html). + +`myapp` ディレクトリーで、`app.js` というファイルを作成して、以下のコードを追加します。
    `req` (要求) と `res` (応答) は、Node が提供するのとまったく同じオブジェクトであるため、Express が関与しない場合と同じように、`req.pipe()`、`req.on('data', callback)` などを呼び出すことができます。 @@ -39,11 +40,10 @@ app.listen(port, () => { 次のコマンドを使用してアプリケーションを実行します。 -
    -
    +```bash
     $ node app.js
    -
    -
    +``` 次に、ブラウザーに [http://localhost:3000/](http://localhost:3000/) をロードして、出力を確認します。 +### ここで紹介するのは基本的に、作成できる最も単純な Express アプリケーションです。このアプリケーションは単一ファイル・アプリケーションであり、[Express ジェネレーター](/{{ page.lang }}/starter/generator.html) を使用して得られるものでは _ありません_ 。このジェネレーターは、さまざまな目的で多数の JavaScript ファイル、Jade テンプレート、サブディレクトリーを使用する完全なアプリケーション用のスキャフォールディングを作成します。 diff --git a/ja/starter/installing.md b/ja/starter/installing.md old mode 100755 new mode 100644 index f4338f4cab..6814a7e858 --- a/ja/starter/installing.md +++ b/ja/starter/installing.md @@ -1,49 +1,56 @@ --- layout: page title: Express のインストール +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: ja +redirect_from: " " --- # インストール 既に [Node.js](https://nodejs.org/) をインストールしてあることを想定して、ここではアプリケーションを作成するディレクトリーを作り、それを作業ディレクトリーにします。 -```sh +- [Express 4.x](/{{ page.lang }}/4x/api.html) には Node.js 0.10 以上が必要です。 +- [Express 5.x](/{{ page.lang }}/5x/api.html) には Node.js 18 以上が必要です。 + +```bash $ mkdir myapp $ cd myapp ``` `npm init` コマンドを使用して、アプリケーション用の `package.json` ファイルを作成します。 `package.json` の機能について詳しくは、[Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json) を参照してください。 +For more information on how `package.json` works, see [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). -```sh +```bash $ npm init ``` -次のコマンドは、アプリケーションの名前やバージョンなど、いくつかのことを要求します。 -ここでは、以下の例外を除いて、RETURN キーを押して単にそれらのデフォルトのほとんどを受け入れることができます。 +This command prompts you for a number of things, such as the name and version of your application. +For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception: -```sh +``` entry point: (index.js) ``` -`app.js` と入力するか、メインファイルの名前にしたいものを何か入力してください。もしそれを `index.js` にしたいのなら、RETURN キーを押して提案されたデフォルトのファイル名を受け入れてください。 +`app.js` と入力するか、メインファイルの名前にしたいものを何か入力してください。もしそれを `index.js` にしたいのなら、RETURN キーを押して提案されたデフォルトのファイル名を受け入れてください。 If you want it to be `index.js`, hit RETURN to accept the suggested default file name. -Expressを `myapp` ディレクトリにインストールし、それを依存関係リストに保存してください。例えば: +Expressを `myapp` ディレクトリにインストールし、それを依存関係リストに保存してください。例えば: For example: -```sh -$ npm install express --save +```bash +$ npm install express ``` Express を一時的にインストールし、それを依存関係リストに追加しないようにするには、次のようにします。 -```sh +```bash $ npm install express --no-save ```
    + npm 5.0 以降のデフォルトでは、npm install はモジュールを `package.json` ファイルの `dependencies` リストに追加します。以前のバージョンの npm では、`--save` オプションを明示的に指定しなければなりません。その後、app ディレクトリで `npm install` を実行すると、依存関係リストにモジュールが自動的にインストールされます。 + Then, afterwards, running `npm install` in the app directory will automatically install modules in the dependencies list.
    -### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/ja/starter/static-files.md b/ja/starter/static-files.md old mode 100755 new mode 100644 index ccd66655fb..204e330e6f --- a/ja/starter/static-files.md +++ b/ja/starter/static-files.md @@ -1,33 +1,39 @@ --- layout: page title: Express での静的ファイルの提供 +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: ja +redirect_from: " " --- # Express での静的ファイルの提供 イメージ、CSS ファイル、JavaScript ファイルなどの静的ファイルを提供するには、Express に標準実装されている `express.static` ミドルウェア関数を使用します。 -静的アセットファイルを格納しているディレクトリーの名前を `express.static` ミドルウェア関数に渡して、ファイルの直接提供を開始します。例えば、`public` というディレクトリー内のイメージ、CSS ファイル、JavaScript ファイルを提供するには、次のコードを使用します。 +The function signature is: -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +For example, use the following code to serve images, CSS files, and JavaScript files in a directory named `public`: + +```js +app.use(express.static('public')) +``` これで、`public` ディレクトリーに入っているファイルをロードできます。 -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +```
    Express は、静的ディレクトリーから相対的なファイルを検索するため、静的ディレクトリーの名前は URL の一部ではありません。 @@ -35,39 +41,41 @@ Express は、静的ディレクトリーから相対的なファイルを検索 複数の静的アセットディレクトリーを使用するには、`express.static` ミドルウェア関数を複数回呼び出します。 -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` Express は、`express.static` ミドルウェア関数に静的ディレクトリーが設定された順序でファイルを検索します。 -`express.static` 関数によって提供されるファイルの仮想パスのプレフィックス (パスは実際にはファイル・システムに存在しません) を作成するには、次に示すように、静的ディレクトリーの[マウント・パスを指定](/{{ page.lang }}/4x/api.html#app.use)します。 +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` これで、`public` ディレクトリー内のファイルを `/static` パス・プレフィックスからロードできます。 -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` + +ただし、`express.static` 関数に指定するパスは、`node` プロセスを起動するディレクトリーに対して相対的です。別のディレクトリーから Express アプリケーションを実行する場合は、提供するディレクトリーの絶対パスを使用する方が安全です。 If you run the express app from another directory, it's safer to use the absolute path of the directory that you want to serve: + +```js +const path = require('path') +app.use('/static', express.static(path.join(__dirname, 'public'))) +``` -ただし、`express.static` 関数に指定するパスは、`node` プロセスを起動するディレクトリーに対して相対的です。別のディレクトリーから Express アプリケーションを実行する場合は、提供するディレクトリーの絶対パスを使用する方が安全です。 +For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static.html). -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/ja/support/index.md b/ja/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/ja/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/js/app.js b/js/app.js index 5e02c41265..b8888e0642 100644 --- a/js/app.js +++ b/js/app.js @@ -1,267 +1,102 @@ -/* - Copyright (c) 2016 StrongLoop, IBM, and Express Contributors - License: MIT -*/ - -$(function(){ - - var isSmallScreen = checkSmallScreen() - - $(window).resize(function () { - isSmallScreen = checkSmallScreen() - }) - - function checkSmallScreen() { - return window.innerWidth < 899 ? true : false - } - - var doc = $(document); - var lang = document.location.pathname.split('/')[1] - - // hilight the menu item of the current page - $('#navmenu ul ul').find('a[href="'+ document.location.pathname + '"]').addClass('current') - - // top link - $('#top').click(function(e){ - $('html, body').animate({scrollTop : 0}, 500); - return false; - }); - - // scrolling links - var added; - doc.scroll(function(e){ - if (doc.scrollTop() > 5) { - if (added) return; - added = true; - $('body').addClass('scroll'); +const i18nMsgBox = document.getElementById("i18n-notice-box"); + +// add/remove class 'scroll' on scroll by 5px +const scrollTarget = document.querySelector('.logo-container'); +const scrollObserver = new IntersectionObserver( + ([entry]) => { + if (!entry.isIntersecting) { + document.body.classList.add('scroll'); } else { - $('body').removeClass('scroll'); - added = false; - } - }) - - // edit page link - var latest = ''; - var branchPath = 'https://github.com/expressjs/expressjs.com'; - var pathName = document.location.pathname; - - var currentVersion = (pathName.match(/^(?:\/[a-z]{2})?\/([0-9]x|)/) || [])[1] || '4x'; // defaults to current version - var fileName = pathName.split('/').splice(-2)[1]; - var pagePath; - var editPath; - - // the api doc cannot be edited individually, we'll have to link to the dir instead - if (fileName == 'api.html') { - editPath = branchPath + '/tree/gh-pages/_includes/api/en/'+ currentVersion; - } - // link to individual doc files - else { - pagePath = pathName.replace(/\.html$/, '.md'); - editPath = branchPath + '/blob/gh-pages' + pagePath; - } - - var editLink; - - if (lang === 'en') { - if (pathName == '/') editLink = 'Fork the website on GitHub.'; - else editLink = 'Edit this page on GitHub.'; - $('#fork').html(editLink); - } - - // code highlight - - $('code.language-js').each(function(){ - $(this).addClass('language-javascript').removeClass('language-js') - }) - - $('code.language-sh').each(function(){ - $(this).parent().addClass('language-sh') - }) - - Prism.highlightAll() - - // menu bar - - var prev; - var n = 0; - - var headings = $('h2, h3').map(function(i, el){ - return { - top: $(el).offset().top - 200, - id: el.id - } - }); - - function closest() { - var h; - var top = $(window).scrollTop(); - var i = headings.length; - while (i--) { - h = headings[i]; - if (top >= h.top) return h; + document.body.classList.remove('scroll'); } + }, + { + root: null, + threshold: 0, + rootMargin: '0px 0px 0px 0px' } - - var currentApiPrefix; - var parentMenuSelector; - var lastApiPrefix; - - $(window).bind('load resize', function() { - - $('#menu').css('height', ($(this).height() - 150) + 'px'); - - }); - - $(document).scroll(function() { - - var h = closest(); - if (!h) return; - - - if (window.location.pathname == '/3x/api.html') { - - if (prev) { - prev.removeClass('active'); - prev.parent().parent().removeClass('active'); +); + +if (scrollTarget) scrollObserver.observe(scrollTarget); + +// heighlight current Menu on scroll +const headings = Array.from(document.querySelectorAll("h2, h3")); +const menuLinks = document.querySelectorAll("#menu li a"); + +const observerOptions = { + root: null, + rootMargin: "-10% 0px -65% 0px", + threshold: 1, +}; + +const menuObserver = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const currentApiPrefix = entry.target.id.split(".")[0]; + const parentMenuSelector = `#${currentApiPrefix}-menu`; + const parentMenuEl = document.querySelector(parentMenuSelector); + + // open submenu on scroll + if (parentMenuEl) parentMenuEl.classList.add("active"); + + // Remove active class from last menu item + const lastActiveMenu = document.querySelector(".active[id$='-menu']"); + if (lastActiveMenu && lastActiveMenu.id !== parentMenuEl.id) { + lastActiveMenu.classList.remove("active"); } - var a = $('a[href="#' + h.id + '"]'); - a.addClass('active'); - a.parent().parent().addClass('active'); - prev = a; + // Update active link + menuLinks.forEach((link) => link.classList.remove("active")); + const activeLink = document.querySelector(`a[href="#${entry.target.id}"]`); + if (activeLink && !activeLink.classList.contains("active")) activeLink.classList.add("active"); } + }); +}, observerOptions); + +headings.forEach((heading) => menuObserver.observe(heading)); + +// i18n message box : this box appears hidden for all page.lang != 'en' +const isI18nCookie = readCookie('i18nClose'); +if (i18nMsgBox && !isI18nCookie) { + const closeI18nBtn = document.getElementById("close-i18n-notice-box"); + // show notice box + i18nMsgBox.hidden = false; + // close notice box + if (closeI18nBtn) { + closeI18nBtn.addEventListener("click", () => { + // hide notice + i18nMsgBox.hidden = true; + // set session cookie + createCookie('i18nClose', 1); + }); - else { - - currentApiPrefix = h.id.split('.')[0]; - parentMenuSelector = '#'+ currentApiPrefix + '-menu'; - - $(parentMenuSelector).addClass('active'); - - if (lastApiPrefix && (lastApiPrefix != currentApiPrefix)) { - $('#'+ lastApiPrefix + '-menu').removeClass('active'); + // keyboard a11y + closeI18nBtn.addEventListener("keydown", (e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + closeI18nBtn.click(); } - - $('#menu li a').removeClass('active'); - - var a = $('a[href="#' + h.id + '"]'); - a.addClass('active'); - - lastApiPrefix = currentApiPrefix.split('.')[0]; - - } - - }) - - // show mobile menu - $('#nav-button, #overlay').click(function () { - $('#navmenu').toggle() - $('#overlay').toggle() - }) - - // dropdown menu - - if ('ontouchstart' in document.documentElement) { - $('#application-menu').dropit({ action: 'click' }) - $('#getting-started-menu').dropit({ action: 'click' }) - $('#guide-menu').dropit({ action: 'click' }) - $('#advanced-topics-menu').dropit({ action: 'click' }) - $('#resources-menu').dropit({ action: 'click' }) - $('#lb-menu').dropit({ action: 'click' }) - $('#changelog-menu').dropit({ action: 'click' }) + }); } - else { - $('#application-menu').dropit({ action: 'mouseenter' }) - $('#getting-started-menu').dropit({ action: 'mouseenter' }) - $('#guide-menu').dropit({ action: 'mouseenter' }) - $('#advanced-topics-menu').dropit({ action: 'mouseenter' }) - $('#resources-menu').dropit({ action: 'mouseenter' }) - $('#lb-menu').dropit({ action: 'mouseenter' }) - $('#changelog-menu').dropit({ action: 'mouseenter' }) - } - - // mobile - - // main menu - $('#navmenu > li').click(function () { - - // applicable only if it has a menu - if ($(this).find('ul').length) { - - if ($(this).hasClass('active-mobile-menu')) { - $(this).removeClass('active-mobile-menu') - $(this).find('.dropit .dropit-submenu').hide() - } - else { - $('.dropit .dropit-submenu').hide() - $(this).find('.dropit .dropit-submenu').show() - $('#navmenu li.active-mobile-menu').removeClass('active-mobile-menu') - $(this).addClass('active-mobile-menu') - } - } - else if (isMobile.any || isSmallScreen) { - var path = $(this).find('a').attr('href') - document.location = path - } - - }) - - // when in mobile mode, menu names should open the submenu - $('.dropit-trigger a').click(function (e) { - - if (window.matchMedia('(max-width: 899px)').matches) { - e.preventDefault() - } - - }) - - // sub menu navigation - $('.dropit-submenu li').click(function () { - if (isMobile.any || isSmallScreen) { - var path = $(this).find('a').attr('href') - document.location = path - } - }) - - // i18n notice - if (readCookie('i18nClose')) { - $('#i18n-notice-box').hide() - } - else { - $('#close-i18n-notice-box').on('click', function () { - $('#i18n-notice-box').hide() - createCookie('i18nClose', 1); - }) - } - -}) - - +}; function createCookie(name, value, days) { - var expires; - + let expires = ""; if (days) { - var date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires=" + date.toGMTString(); - } else { - expires = ""; + const date = new Date(); + date.setTime(date.getTime() + (days * 864e5)); + expires = "; expires=" + date.toUTCString(); } - document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/"; + document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${expires}; path=/; SameSite=Lax; Secure`; } function readCookie(name) { - var nameEQ = encodeURIComponent(name) + "="; - var ca = document.cookie.split(';'); - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; + const nameEQ = encodeURIComponent(name) + "="; + const ca = document.cookie.split(';'); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length, c.length)); } return null; } - -function eraseCookie(name) { - createCookie(name, "", -1); -} diff --git a/js/copycode.js b/js/copycode.js new file mode 100644 index 0000000000..2174710746 --- /dev/null +++ b/js/copycode.js @@ -0,0 +1,59 @@ +const codeBlocks = document.querySelectorAll("pre:has(code)"); + +codeBlocks.forEach((block) => { + // Only add button if browser supports Clipboard API + if (!navigator.clipboard) return; + + const button = createCopyButton(); + block.appendChild(button); + block.setAttribute("tabindex", 0); // Add keyboard a11y for
    
    +
    +  button.addEventListener("click", async () => {
    +    await copyCode(block, button);
    +  });
    +});
    +
    +function createCopyButton() {
    +  const button = document.createElement("button");
    +  setButtonAttributes(button, {
    +    type: "button", // button doesn't act as a submit button
    +    title: "copy code",
    +    "aria-label": "click to copy code",
    +  });
    +  return button;
    +}
    +
    +function setButtonAttributes(button, attributes) {
    +  for (const [key, value] of Object.entries(attributes)) {
    +    button.setAttribute(key, value);
    +  }
    +}
    +
    +async function copyCode(block, button) {
    +  const code = block.querySelector("code");
    +  let text = code.innerText;
    +  // remove "$" and space if exists at the beginning of the code
    +  text = text.replace(/^\$\s?/,"");
    +
    +  try {
    +    await navigator.clipboard.writeText(text);
    +    updateButtonState(button, "copied", "code is copied!");
    +  } catch {
    +    updateButtonState(button, "failed", "failed!");
    +  }
    +}
    +
    +function updateButtonState(button, statusClass, ariaLabel) {
    +  button.setAttribute("aria-live", "polite");
    +  button.setAttribute("aria-label", ariaLabel);
    +  button.classList.add(statusClass);
    +
    +  // Clear any existing timer
    +  if (button.dataset.timerId) clearTimeout(Number(button.dataset.timerId));
    +  const timer = setTimeout(() => {
    +    button.classList.remove(statusClass);
    +    button.setAttribute("aria-label", "click to copy code");
    +  }, 1000);
    +
    +  button.dataset.timerId = timer;
    +}
    diff --git a/js/dropit.js b/js/dropit.js
    deleted file mode 100644
    index a13abe3cb1..0000000000
    --- a/js/dropit.js
    +++ /dev/null
    @@ -1,109 +0,0 @@
    -/*
    - * Dropit v1.1.0
    - * http://dev7studios.com/dropit
    - *
    - * Copyright 2012, Dev7studios
    - * Free to use and abuse under the MIT license.
    - * http://www.opensource.org/licenses/mit-license.php
    - */
    -
    -;(function($) {
    -
    -    $.fn.dropit = function(method, minWidth) {
    -
    -        minWidth = minWidth || '770px';
    -
    -        var methods = {
    -
    -            init : function(options) {
    -                this.dropit.settings = $.extend({}, this.dropit.defaults, options);
    -                return this.each(function() {
    -                    var $el = $(this),
    -                         el = this,
    -                         settings = $.fn.dropit.settings;
    -
    -                    // Hide initial submenus
    -                    $el.addClass('dropit')
    -                    .find('>'+ settings.triggerParentEl +':has('+ settings.submenuEl +')').addClass('dropit-trigger')
    -                    .find(settings.submenuEl).addClass('dropit-submenu').hide();
    -
    -                    // Open on click
    -                    $el.on(settings.action, settings.triggerParentEl +':has('+ settings.submenuEl +') > '+ settings.triggerEl +'', function(){
    -
    -                        if (!window.matchMedia('(min-width: '+ minWidth +')').matches) return;
    -
    -                        // Close click menu's if clicked again
    -                        if(settings.action == 'click' && $(this).parents(settings.triggerParentEl).hasClass('dropit-open')){
    -                            settings.beforeHide.call(this);
    -                            $(this).parents(settings.triggerParentEl).removeClass('dropit-open');
    -                            $(this).find(settings.submenuEl).hide();
    -                            settings.afterHide.call(this);
    -                            return false;
    -                        }
    -
    -                        // Hide open menus
    -                        settings.beforeHide.call(this);
    -                        $('.dropit-open').removeClass('dropit-open').find('.dropit-submenu').hide();
    -                        settings.afterHide.call(this);
    -
    -                        // Open this menu
    -                        settings.beforeShow.call(this);
    -                        $(this).parents(settings.triggerParentEl).addClass('dropit-open').find(settings.submenuEl).show();
    -                        settings.afterShow.call(this);
    -
    -                        return false;
    -                    });
    -
    -                    // Close if outside click
    -                    $(document).on('click', function(){
    -
    -                        if (!window.matchMedia('(min-width: '+ minWidth +')').matches) return;
    -
    -                        settings.beforeHide.call(this);
    -                        $('.dropit-open').removeClass('dropit-open').find('.dropit-submenu').hide();
    -                        settings.afterHide.call(this);
    -                    });
    -
    -                    // If hover
    -                    if(settings.action == 'mouseenter'){
    -
    -                        if (!window.matchMedia('(min-width: '+ minWidth +')').matches) return;
    -
    -                        $el.on('mouseleave', function(){
    -                            settings.beforeHide.call(this);
    -                            $(this).removeClass('dropit-open').find(settings.submenuEl).hide();
    -                            settings.afterHide.call(this);
    -                        });
    -                    }
    -
    -                    settings.afterLoad.call(this);
    -                });
    -            }
    -
    -        };
    -
    -        if (methods[method]) {
    -            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    -        } else if (typeof method === 'object' || !method) {
    -            return methods.init.apply(this, arguments);
    -        } else {
    -            $.error( 'Method "' +  method + '" does not exist in dropit plugin!');
    -        }
    -
    -    };
    -
    -    $.fn.dropit.defaults = {
    -        action: 'click', // The open action for the trigger
    -        submenuEl: 'ul', // The submenu element
    -        triggerEl: 'a', // The trigger element
    -        triggerParentEl: 'li', // The trigger parent element
    -        afterLoad: function(){}, // Triggers when plugin has loaded
    -        beforeShow: function(){}, // Triggers before submenu is shown
    -        afterShow: function(){}, // Triggers after submenu is shown
    -        beforeHide: function(){}, // Triggers before submenu is hidden
    -        afterHide: function(){} // Triggers before submenu is hidden
    -    };
    -
    -    $.fn.dropit.settings = {};
    -
    -})(jQuery);
    diff --git a/js/ismobile.js b/js/ismobile.js
    deleted file mode 100644
    index 0de144d707..0000000000
    --- a/js/ismobile.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/Windows Phone/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");if("undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window)return this},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);
    diff --git a/js/menu.js b/js/menu.js
    new file mode 100644
    index 0000000000..5ee91a6016
    --- /dev/null
    +++ b/js/menu.js
    @@ -0,0 +1,195 @@
    +// It uses `window.matchMedia` instead of `window.addEventListener('resize')` because `matchMedia` performs better by not changing its value with every screen resize.
    +const mobileScreen = window.matchMedia("(max-width: 1110px)");
    +let isSmallScreen = mobileScreen?.matches;
    +const tocScreen = window.matchMedia("(max-width: 800px)");
    +let isTocScreen = tocScreen.matches;
    +
    +mobileScreen?.addEventListener("change", (event) => {
    +	isSmallScreen = event.matches
    +
    +  if (!isSmallScreen) {
    +		document.body.classList.remove("no-scroll")
    +	}
    +});
    +
    +// Desktop Menu
    +
    +const itemsMenu = document.querySelectorAll(".submenu");
    +const navDrawers = document.querySelectorAll('#navmenu > li')
    +let activeDrawer // active dropdown nav link
    +
    +
    +for (const el of itemsMenu) {
    +	el.addEventListener("click", (e) => {
    +		if (e.target.parentNode === el && e.pointerType === "touch" && el.querySelector("a.active")) {
    +			e.preventDefault(); // Tapping active menu on touchscreen tablet should open menu, not click
    +		}
    +		if (isSmallScreen || 'ontouchstart' in document.documentElement) {
    +		// HANDLE ACTIVE LINKS IN DROPDOWN NAV	
    +		// if no activeDrawer set then page was set in md logic
    +		if (!activeDrawer) {
    +			// remove default active link
    +			removeActiveFromDrawers(navDrawers)
    +			// set new active drawer to clicked
    +			activeDrawer = el
    +			// add active class
    +			addActiveToDrawer(el)
    +		// remove prev activeDrawer and set current to active
    +		} else if (activeDrawer.id !== el.id) {
    +			activeDrawer.querySelector('a').classList.remove('active')
    +			addActiveToDrawer(el)
    +			activeDrawer = el
    +		}
    +
    +			for (const item of itemsMenu) {
    +        // close any open drawers on click next drawer
    +				if (item.id !== el.id) {
    +					item.classList.remove("open");
    +				}
    +			}
    +			el.classList.toggle("open");
    +		}
    +	});
    +
    +	el.addEventListener("mouseenter", () => {
    +		if (!isSmallScreen) {
    +			el.classList.add("open");
    +		}
    +	});
    +
    +	el.addEventListener("mouseleave", () => {
    +		if (!isSmallScreen) {
    +			el.classList.remove("open");
    +		}
    +	});
    +}
    +
    +// Mobile Menu and Language Picker
    +const langBtn = document.getElementById("langBtn");
    +const langList = document.getElementById("langList");
    +const linkItemsMenu = document.querySelectorAll(".submenu > a");
    +const menu = document.querySelector("#navmenu");
    +const overlay = document.querySelector("#overlay");
    +const navButton = document.querySelector("#nav-button");
    +
    +function closeLangList() {
    +  langList.classList.remove("open");
    +  langBtn.setAttribute("aria-expanded", false);
    +}
    +
    +function toggleLangList() {
    +  const isOpen = langList.classList.toggle("open");
    +  langBtn.setAttribute("aria-expanded", isOpen);
    +}
    +
    +// toggle on button click
    +langBtn.addEventListener("click", (e) => {
    +  e.stopPropagation();
    +  toggleLangList();
    +});
    +
    +// close on outside click except for lang btn
    +document.body.addEventListener("click", (e) => {
    +  if (!langList.contains(e.target)) {
    +    closeLangList();
    +  }
    +});
    +
    +for (const el of linkItemsMenu) {
    +	el.addEventListener("click", (e) => {
    +		if (el.classList.contains("open")) {
    +			el.classList.remove("open");
    +		}
    +		
    +		if (isSmallScreen || 'ontouchstart' in document.documentElement) {
    +			e.preventDefault();
    +		}
    +	});
    +}
    +
    +navButton?.addEventListener("click", () => {
    +	menu?.classList.toggle("opens");
    +	overlay?.classList.toggle("blurs");
    +	document.body.classList.toggle("no-scroll");
    +});
    +
    +overlay?.addEventListener("click", () => {
    +	if (menu?.classList.contains("opens")) {
    +		menu.classList.remove("opens");
    +	}
    +	overlay.classList.remove("blurs");
    +	document.body.classList.remove("no-scroll");
    +	// TODO : write helper function 
    +	const isOpen = langList.classList.toggle("open");
    +	langBtn.setAttribute("aria-expanded", isOpen);
    +});
    +
    +document
    +	.querySelector(`.submenu-content a[href="{document.location.pathname}"]`)
    +	?.classList.add("current");
    +
    +// when active is unknown, loop over and remove any active link
    +function removeActiveFromDrawers(navDrawers) {
    +  for (const item of navDrawers) {
    +    item.querySelector('a').classList.remove('active')
    +  }
    +}
    +// add active to known link
    +function addActiveToDrawer(drawer) {
    +	drawer.querySelector('a').classList.add('active')
    +}
    +
    +// TOC 
    +const toggleBtn = document.getElementById("menu-toggle");
    +const tocList = document.getElementById("menu");
    +
    +function updateTocVisibility() {
    +	if (isTocScreen) {
    +	  toggleBtn?.classList.add("show");
    +	} else {
    +	  toggleBtn?.classList.remove("show");
    +	}
    +  }
    +
    +// toc button on page load
    +updateTocVisibility();
    +
    +// Listen for changes in screen size
    +tocScreen.addEventListener("change", (event) => {
    +  isTocScreen = event.matches;
    +  updateTocVisibility();
    +});
    +
    +// Toggle toc menu on button click
    +toggleBtn?.addEventListener("click", (e) => {
    +	toggleBtn.classList.toggle("rotate");
    +  if(tocList?.classList.contains("open")) {
    +	tocList.classList.remove("open");
    +  } else {
    +	tocList.classList.add("open");
    +  }
    +});
    +  
    +// Open/Close sub TOC content on click
    +document.querySelectorAll("#menu > li > a").forEach((link) => {
    +	link.addEventListener("click", function (event) {
    +      event.preventDefault(); // stop navigation to submenu
    +
    +	  // Find the closest parent 
  • + const closestLiParent = link.closest("li"); + const childUlSubMenu = closestLiParent.children[1]; + + // If submenu is already active, remove "active" class (toggle behavior) + if (childUlSubMenu?.classList.contains("active")) { + childUlSubMenu.classList.remove("active"); + } else { + // Remove "active" from all other submenus + document.querySelectorAll("#menu > li > ul").forEach((subMenu) => { + subMenu.classList.remove("active"); + }); + + // Add "active" to the clicked submenu + childUlSubMenu?.classList.add("active"); + } + }); + }); diff --git a/js/prism.js b/js/prism.js deleted file mode 100644 index 5b80618286..0000000000 --- a/js/prism.js +++ /dev/null @@ -1,7 +0,0 @@ -/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash */ -self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){c.lastIndex=0;var m=c.exec(d);if(m){u&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=s+'="'+(i.attributes[s]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; -Prism.languages.markup={comment://g,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/\&#?[\da-z]{1,8};/gi},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});; -Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/gi,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,punctuation:/[\{\};:]/g,"function":/[-a-z0-9]+(?=\()/gi},Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/gi,inside:{tag:{pattern:/|<\/style>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});; -Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//g,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*?(\r?\n|$)/g,lookbehind:!0}],string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; -Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; -Prism.languages.bash=Prism.languages.extend("clike",{comment:{pattern:/(^|[^"{\\])(#.*?(\r?\n|$))/g,lookbehind:!0},string:{pattern:/("|')(\\?[\s\S])*?\1/g,inside:{property:/\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^\}]+\})/g}},keyword:/\b(if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)\b/g}),Prism.languages.insertBefore("bash","keyword",{property:/\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^}]+\})/g}),Prism.languages.insertBefore("bash","comment",{important:/(^#!\s*\/bin\/bash)|(^#!\s*\/bin\/sh)/g});; diff --git a/js/retina.js b/js/retina.js deleted file mode 100644 index a926142960..0000000000 --- a/js/retina.js +++ /dev/null @@ -1,3 +0,0 @@ -// retina.js, a high-resolution image swapper (http://retinajs.com), v0.0.2 - -(function(){function t(e){this.path=e;var t=this.path.split("."),n=t.slice(0,t.length-1).join("."),r=t[t.length-1];this.at_2x_path=n+"@2x."+r}function n(e){this.el=e,this.path=new t(this.el.getAttribute("src"));var n=this;this.path.check_2x_variant(function(e){e&&n.swap()})}var e=typeof exports=="undefined"?window:exports;e.RetinaImagePath=t,t.confirmed_paths=[],t.prototype.is_external=function(){return!!this.path.match(/^https?\:/i)&&!this.path.match("//"+document.domain)},t.prototype.check_2x_variant=function(e){var n,r=this;if(this.is_external())return e(!1);if(this.at_2x_path in t.confirmed_paths)return e(!0);n=new XMLHttpRequest,n.open("HEAD",this.at_2x_path),n.onreadystatechange=function(){return n.readyState!=4?e(!1):n.status>=200&&n.status<=399?(t.confirmed_paths.push(r.at_2x_path),e(!0)):e(!1)},n.send()},e.RetinaImage=n,n.prototype.swap=function(e){function n(){t.el.complete?(t.el.setAttribute("width",t.el.offsetWidth),t.el.setAttribute("height",t.el.offsetHeight),t.el.setAttribute("src",e)):setTimeout(n,5)}typeof e=="undefined"&&(e=this.path.at_2x_path);var t=this;n()},e.devicePixelRatio>1&&(window.onload=function(){var e=document.getElementsByTagName("img"),t=[],r,i;for(r=0;r { + if (!hasLocalStorage()) { + // If localStorage is not supported, use system preference + document?.addEventListener('DOMContentLoaded', () => { + // remove icon + document.querySelector('#theme-toggle').remove() + setTheme(colorScheme); + }) + } else { + // user's PS system theme settings + const systemTheme = localStorage.getItem('system-theme') + // setting stored in local storage + const localTheme = localStorage.getItem('local-theme') + // if no local theme set - system is default + if (localTheme === null) { + setTheme(colorScheme) + localStorage.setItem('system-theme', colorScheme) + // page load - load any stored themes or set theme + } else { + // listen for system changes, update if any + if (colorScheme != systemTheme) { + setTheme(colorScheme) + localStorage.setItem('system-theme', colorScheme) + } else { + // else load local theme + setTheme(localTheme); + } + } + // wait for load then and add listener on button + document.addEventListener('DOMContentLoaded', () => { + const themeToggle = document?.querySelector('#theme-toggle'); + themeToggle.addEventListener('click', toggleLocalStorageTheme); + // set area-label for screen readers + themeToggle.setAttribute('aria-label', colorScheme ? 'Switch to light mode' : 'Switch to dark mode'); + }) + } +}) +// apply current theme +function setTheme(theme) { + if (theme === 'dark') { + darkModeOn() + } else { + lightModeOn() + } +} +// toggle btn themes +function toggleLocalStorageTheme() { + const localTheme = localStorage.getItem('local-theme'); + if (localTheme === 'light') { + setTheme('dark'); + } else { + setTheme('light'); + } +} +function darkModeOn() { + document?.documentElement?.classList.remove('light-mode') + document?.documentElement?.classList.add('dark-mode') + updateThemeIcon('dark'); + localStorage.setItem('local-theme', 'dark'); +} +function lightModeOn() { + document?.documentElement?.classList.remove('dark-mode') + document?.documentElement?.classList.add('light-mode') + updateThemeIcon('light'); + localStorage.setItem('local-theme', 'light'); +} +function hasLocalStorage() { + return typeof Storage !== 'undefined' +} +function watchColorSchemeChange(callback) { + // get system theme preference + const darkMediaQuery = window?.matchMedia('(prefers-color-scheme: dark)') + + const handleChange = (event) => { + const newColorScheme = event?.matches ? 'dark' : 'light' + callback(newColorScheme) + } + darkMediaQuery.addEventListener('change', handleChange) + // initial call : if system theme is not dark then light mode is choosen + callback(darkMediaQuery.matches ? 'dark' : 'light') + // remove event from window + return () => darkMediaQuery.removeEventListener('change', handleChange) +} + +function updateThemeIcon (theme) { + const sun = document?.getElementById('icon-sun'); + const moon = document?.getElementById('icon-moon'); + const themeToggle = document?.getElementById('theme-toggle'); + if (!sun || !moon || !themeToggle) return; + const isDark = theme === 'dark'; + // improve accessibility for screen readers + sun.setAttribute('aria-hidden', isDark ? 'false' : 'true'); + moon.setAttribute('aria-hidden', isDark ? 'true' : 'false'); + themeToggle.setAttribute('aria-label', isDark ? 'Switch to light mode' : 'Switch to dark mode'); +}; diff --git a/ko/3x/api.md b/ko/3x/api.md old mode 100755 new mode 100644 index ba542c9a98..1e7377cfa5 --- a/ko/3x/api.md +++ b/ko/3x/api.md @@ -1,23 +1,29 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - API 참조 +description: Express.js 3.x 버전의 API 참조에 접근할 수 있습니다. 이 버전은 지원이 종료되었으며 더 이상 유지보수되지 않습니다. 모듈과 메소드에 대한 상세한 정보가 포함되어 있습니다. menu: api -lang: ko +redirect_from: " " --- +
    **Express 3.x은 더 이상 유지보수되지 않습니다.** - 3.x의 알려진 또는 알려지지 않은 보안 및 성능 문제는 마지막 업데이트(2015년 8월 1일) 이후로 처리되지 않고 있습니다. 최신 버전의 Express를 사용할 것을 강력히 권장합니다. +3.x의 알려진 또는 알려지지 않은 보안 및 성능 문제는 마지막 업데이트(2015년 8월 1일) 이후로 처리되지 않고 있습니다. 최신 버전의 Express를 사용할 것을 강력히 권장합니다. + +버전 3.x 이상으로 업그레이드할 수 없는 경우, [상업적 지원 옵션](/{{ page.lang }}/support#commercial-support-options)을 고려해주시기 바랍니다. +

    3.x API

    - {% include api/en/3x/express.md %} - {% include api/en/3x/app.md %} - {% include api/en/3x/req.md %} - {% include api/en/3x/res.md %} - {% include api/en/3x/middleware.md %} +{% include api/en/3x/express.md %} +{% include api/en/3x/app.md %} +{% include api/en/3x/req.md %} +{% include api/en/3x/res.md %} +{% include api/en/3x/middleware.md %}
    diff --git a/ko/4x/api.md b/ko/4x/api.md old mode 100755 new mode 100644 index 68068a6b03..e11b15eb29 --- a/ko/4x/api.md +++ b/ko/4x/api.md @@ -1,17 +1,28 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - API 참조 +description: Express.js 4.x의 API 레퍼런스를 확인하여, 이 버전으로 웹 애플리케이션을 구축할 때 사용할 수 있는 모든 모듈, 메서드, 속성에 대해 자세히 알아봅니다. menu: api -lang: ko +redirect_from: " " --- +

    4.x API

    - {% include api/en/4x/express.md %} - {% include api/en/4x/app.md %} - {% include api/en/4x/req.md %} - {% include api/en/4x/res.md %} - {% include api/en/4x/router.md %} +{% capture node-version %} + +Express 4.0에는 Node.js 0.10 이상이 필요합니다. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/4x/express.md %} +{% include api/en/4x/app.md %} +{% include api/en/4x/req.md %} +{% include api/en/4x/res.md %} +{% include api/en/4x/router.md %}
    diff --git a/ko/5x/api.md b/ko/5x/api.md new file mode 100644 index 0000000000..a1467ece9c --- /dev/null +++ b/ko/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - API 참조 +description: Express.js 5.x의 API 레퍼런스를 확인하여, 이 버전으로 웹 애플리케이션을 구축할 때 사용할 수 있는 모든 모듈, 메서드, 속성에 대해 자세히 알아봅니다. +menu: api +redirect_from: " " +--- + +
    + +

    5.x API

    + +{% capture node-version %} + +Express 5.0에는 Node.js 18 이상이 필요합니다. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
    diff --git a/ko/advanced/best-practice-performance.md b/ko/advanced/best-practice-performance.md old mode 100755 new mode 100644 index 6af7ba7bc1..373816c548 --- a/ko/advanced/best-practice-performance.md +++ b/ko/advanced/best-practice-performance.md @@ -1,82 +1,72 @@ --- layout: page title: 프로덕션 환경에서의 Express 사용을 위한 성능 우수 사례 +description: Express 애플리케이션의 프로덕션 환경에서 성능과 안정성을 최적화하기 위한 모범 사례를 알아봅니다. 여기에는 코드 최적화와 최적의 성능을 위한 환경 설정이 포함됩니다. menu: advanced -lang: ko +redirect_from: " " --- # 프로덕션 우수 사례: 성능 및 신뢰성 -## 개요 - 이 문서에서는 프로덕션 환경에 배치된 Express 애플리케이션을 위한 성능 및 신뢰성 관련 우수 사례에 대해 논의합니다. 이 주제는 명백하게 "DevOps" 분야로 구분할 수 있으며 종래의 개발 및 운영 모두를 다룹니다. 따라서, 정보는 다음과 같은 두 개의 파트로 나뉘어 있습니다. - -* [코드에서 수행할 항목](#code) (개발 파트): - * [gzip 압축 사용](#use-gzip-compression) - * [동기식 함수 사용하지 않기](#dont-use-synchronous-functions) - * [정확한 로깅](#do-logging-correctly) - * [올바른 예외 처리](#handle-exceptions-properly) -* [환경/설정에서 수행할 항목](#env) (운영 파트): - * [NODE_ENV를 "production"으로 설정](#set-node_env-to-production) - * [앱이 자동으로 다시 시작되도록 보장](#ensure-your-app-automatically-restarts) - * [앱을 클러스터에서 실행](#run-your-app-in-a-cluster) - * [요청 결과를 캐싱](#cache-request-results) - * [로드 밸런서 사용](#use-a-load-balancer) - * [역방향 프록시 사용](#use-a-reverse-proxy) - - - -## 코드에서 수행할 항목 +- [코드에서 수행할 항목](#code) (개발 파트): + - [gzip 압축 사용](#use-gzip-compression) + - [동기식 함수 사용하지 않기](#dont-use-synchronous-functions) + - [정확한 로깅](#do-logging-correctly) + - [올바른 예외 처리](#exceptions) +- [환경/설정에서 수행할 항목](#env) (운영 파트): + - [NODE_ENV를 "production"으로 설정](#set-node_env-to-production) + - [앱이 자동으로 다시 시작되도록 보장](#ensure-your-app-automatically-restarts) + - [앱을 클러스터에서 실행](#run-your-app-in-a-cluster) + - [요청 결과를 캐싱](#cache-request-results) + - [로드 밸런서 사용](#use-a-load-balancer) + - [역방향 프록시 사용](#proxy) + +## 코드에서 해야 할 일 {#in-code} 애플리케이션의 성능을 향상시키기 위해서 코드를 통해 할 수 있는 몇 가지는 다음과 같습니다. - * [gzip 압축 사용](#use-gzip-compression) - * [동기식 함수 사용하지 않기](#dont-use-synchronous-functions) - * [정확한 로깅](#do-logging-correctly) - * [올바른 예외 처리](#exceptions) - +- [gzip 압축 사용](#use-gzip-compression) +- [동기식 함수 사용하지 않기](#dont-use-synchronous-functions) +- [정확한 로깅](#do-logging-correctly) +- [올바른 예외 처리](#exceptions) - ### gzip 압축 사용 Gzip 압축을 사용하면 응답 본문의 크기를 크게 줄일 수 있으며, 따라서 웹 앱의 속도를 높일 수 있습니다. Express 앱에서 gzip 압축을 사용하려면 [compression](https://www.npmjs.com/package/compression) 미들웨어를 사용하십시오. 예를 들면 다음과 같습니다. ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` 많은 트래픽이 발생하는 프로덕션 환경의 웹사이트의 경우, 압축을 실행하는 가장 좋은 방법은 역방향 프록시 레벨에서 압축을 구현하는 것입니다([역방향 프록시 사용](#proxy) 참조). 그러한 경우에는 compression 미들웨어를 사용할 필요가 없습니다. Nginx에서 gzip 압축을 사용하는 방법에 대한 자세한 내용은 Nginx 문서의 [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html)을 참조하십시오. - - ### 동기식 함수 사용하지 않기 동기식 함수 및 메소드는 리턴될 때까지 실행 프로세스를 묶어 둡니다. 동기식 함수에 대한 한 건의 호출은 몇 마이크로초 또는 밀리초 내에 리턴될 수도 있지만, 많은 트래픽이 발생하는 웹사이트에서 이러한 동기식 호출들이 합산되면 앱의 성능이 낮아집니다. 프로덕션 환경에서는 동기식 함수의 사용을 피하십시오. Node 및 다수의 모듈은 동기식 및 비동기식 버전의 함수를 제공하지만, 프로덕션 환경에서는 항상 비동기식 버전을 사용하십시오. 동기식 함수의 사용이 정당화되는 유일한 경우는 초기 시작 시에 사용되는 경우입니다. -Node.js 4.0 이상 또는 io.js 2.1.0 이상을 사용하는 경우, `--trace-sync-io` 명령행 플래그를 사용하면 애플리케이션이 동기식 API를 사용할 때마다 경고 및 스택 추적이 출력되도록 수 있습니다. 물론, 프로덕션 환경에서 이러한 플래그를 실제로 사용해서는 안 되며, 이는 코드가 프로덕션 환경에서 사용될 준비가 되었다는 것을 보장하기 위한 것입니다. 자세한 정보는 [node 커맨드라인 옵션 문서](https://nodejs.org/api/cli.html#cli_trace_sync_io)를 참조하십시오. +애플리케이션이 동기 API를 사용할 때마다 경고 메시지와 스택 트레이스를 출력하려면 --trace-sync-io 명령줄 플래그를 사용할 수 있습니다. 물론, 프로덕션 환경에서 이러한 플래그를 실제로 사용해서는 안 되며, 이는 코드가 프로덕션 환경에서 사용될 준비가 되었다는 것을 보장하기 위한 것입니다. 자세한 정보는 [node 커맨드라인 옵션 문서](https://nodejs.org/api/cli.html#cli_trace_sync_io)를 참조하십시오. - -### 정확한 로깅 +### 올바른 로깅 방법을 사용해야 합니다 -일반적으로 앱은 디버깅 그리고 앱 활동 로깅(사실상 디버깅 이외의 모든 것)이라는 두 가지 이유로 인해 로깅을 실행합니다. `console.log()` 또는 `console.err()`을 사용하여 터미널에 로그 메시지를 출력하는 것이 일반적인 개발 작업 방식입니다. 그러나 대상이 터미널 또는 파일인 경우 [이들 함수는 동기식으로 작동하며](https://nodejs.org/api/console.html#console_console_1), 따라서 다른 프로그램으로 출력을 전송하는 경우가 아니라면 이러한 함수는 프로덕션 환경에 적합하지 않습니다. +일반적으로 앱은 디버깅 그리고 앱 활동 로깅(사실상 디버깅 이외의 모든 것)이라는 두 가지 이유로 인해 로깅을 실행합니다. `console.log()` 또는 `console.err()`을 사용하여 터미널에 로그 메시지를 출력하는 것이 일반적인 개발 작업 방식입니다. 단, [이 함수들은](https://nodejs.org/api/console.html#console) 출력 대상이 터미널이나 파일일 경우 동기적으로 동작하므로, 출력 결과를 다른 프로그램으로 파이프하지 않는 이상 프로덕션 환경에서는 적합하지 않습니다. -#### 디버깅을 위한 로깅 +#### 디버깅의 경우 디버깅을 위해 로깅하는 경우에는 `console.log()`를 사용하는 대신 [debug](https://www.npmjs.com/package/debug)와 같은 특별한 디버깅 모듈을 사용하십시오. 이러한 모듈을 이용하면 DEBUG 환경 변수를 사용하여 디버그 메시지 발생 시 어떠한 디버그 메시지가 `console.err()`로 전송되는지 제어할 수 있습니다. 앱을 순수한 비동기식으로 유지하려면 `console.err()`을 다른 프로그램으로 전송해야 합니다. 그러나 아마도 프로덕션 단계에서 디버그를 수행할 필요는 없을 것입니다. -#### 앱 활동에 대한 로깅 - -앱 활동을 로깅하는 경우(예: 트래픽 또는 API 호출을 추적)에는 `console.log()`를 사용하는 대신 [Winston](https://www.npmjs.com/package/winston) 또는 [Bunyan](https://www.npmjs.com/package/bunyan)과 같은 로깅 라이브러리를 사용하십시오. 이 두 라이브러리에 대한 자세한 비교는 StrongLoop 블로그 게시물 [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/)을 참조하십시오. +#### 앱 활동의 경우 - +애플리케이션 활동(예: 트래픽 추적 또는 API 호출 기록)을 로깅할 때는 console.log() 대신 [Pino](https://www.npmjs.com/package/pino)와 같은 로깅 라이브러리를 사용하는 것이 좋습니다. Pino는 가장 빠르고 효율적인 옵션입니다. ### 올바른 예외 처리 @@ -84,32 +74,19 @@ Node 앱은 처리되지 않은 예외가 발생할 때 충돌이 발생합니 모든 예외를 처리하도록 보장하려면 다음의 기법을 사용하십시오. -* [try-catch 사용](#try-catch) -* [프미스 사용](#promises) +- [try-catch 사용](#try-catch) +- [프로미스 사용](#promises) 이 주제에 대해 자세히 살펴보기 전에 먼저 Node/Express의 오류 처리, 즉 오류 우선(error-first) 콜백의 사용 및 미들웨어를 통한 오류의 전파에 대한 기본적인 사항을 이해해야 합니다. Node는 비동기식 함수로부터 오류를 리턴하기 위해 "오류 우선 콜백" 방식을 사용하며, 여기서 콜백 함수의 첫 번째 매개변수는 오류 오브젝트이고 그 후속 매개변수에 결과 데이터가 뒤따릅니다. 오류가 없음을 나타낼 때는 첫 번째 매개변수로 널(null)을 전달합니다. 의미 있는 방식으로 오류를 처리하려면 콜백 함수는 이에 맞게 오류 우선 콜백 방식을 따라야 합니다. 그리고 Express에서의 우수 사례는 next() 함수를 사용하여 미들웨어 체인을 통해 오류를 전파하는 것입니다. 오류 처리의 기본사항 대한 자세한 내용은 다음을 참조하십시오. -* [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/)(StrongLoop 블로그) - -#### 수행하지 않아야 하는 항목 - -수행하지 *않아야* 할 한 가지 항목은 예외가 이벤트 루프에까지 발생할 때 생성되는 `uncaughtException` 이벤트를 청취하는 것입니다. `uncaughtException`에 대한 이벤트 리스너를 추가하면 예외가 발생하는 프로세스의 기본 작동을 변경할 수 있으며, 해당 프로세스는 예외가 발생하더라도 계속하여 실행될 것입니다. 이러한 방법은 앱에서 충돌이 발생하는 것을 방지하는 좋은 방법인 것처럼 보일 수 있지만, 처리되지 않은 예외가 발생한 후에도 앱이 계속하여 실행되면 프로세스가 불안정하고 예측할 수 없는 상태가 되므로 이러한 방법은 위험한 작업 방식이며 권장되지 않습니다. - -또한 `uncaughtException`을 사용하는 것은 [세련되지 못한 방식](https://nodejs.org/api/process.html#process_event_uncaughtexception)인 것으로 공식적으로 인식되고 있으며, 코어로부터 이러한 방식을 제거하는 방법이 [제안](https://github.com/nodejs/node-v0.x-archive/issues/2582)되어 있습니다. 따라서 `uncaughtException`을 청취하는 것은 좋은 생각이 아닙니다. 따라서 여러 프로세스 및 수퍼바이저의 사용 등을 권장하며, 오류로부터 복구되는 가장 안정적인 방법은 충돌이 발생한 후 다시 시작하는 것인 경우가 많습니다. - -[도메인](https://nodejs.org/api/domain.html)의 사용 또한 권장하지 않습니다. 일반적으로 도메인은 문제를 해결하지 못하며, 더 이상 사용되지 않는 모듈입니다. - - +- [Node.js의 오류 처리](https://www.tritondatacenter.com/node-js/production/design/errors) #### try-catch 사용 Try-catch는 동기식 코드에서 예외를 처리하는 데 사용할 수 있는 JavaScript 언어 구조체입니다. 예를 들면, try-catch를 사용하여 아래와 같이 JSON 구문 분석 오류를 처리할 수 있습니다. -[JSHint](http://jshint.com/) 또는 [JSLint](http://www.jslint.com/)와 같은 도구를 사용하면 [정의되지 않은 변수에 대한 참조 오류](http://www.jshint.com/docs/options/#undef)와 같은 암시적인 예외를 발견하는 데 도움이 됩니다. - 아래에는 try-catch를 사용하여 잠재적인 프로세스 충돌 예외를 처리하는 예가 표시되어 있습니다. 이 미들웨어 함수는 JSON 오브젝트이자 "params"라는 이름을 갖는 조회 필드를 수락합니다. @@ -117,9 +94,9 @@ Try-catch는 동기식 코드에서 예외를 처리하는 데 사용할 수 있 app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -130,89 +107,69 @@ app.get('/search', (req, res) => { 그러나 try-catch는 동기식 코드에 대해서만 작동합니다. Node 플랫폼은 기본적으로 비동기식이므로(특히, 프로덕션 환경의 경우), try-catch를 통해 많은 예외를 처리할 수는 없을 것입니다. - - #### 프로미스 사용 -`then()`을 사용하는 비동기식 코드 블록 내에서는 프로미스를 통해 모든 예외(명시적 예외 및 암시적 예외 모두)를 처리할 수 있습니다. 프로미스 체인의 끝에 `.catch(next)`만 추가하면 됩니다. 예를 들면 다음과 같습니다. +async 함수 내에서 에러가 발생하거나, async 함수 안에서 거부된(rejected) 프로미스를 await 할 경우, 해당 에러는`next(err)`를 호출한 것과 동일하게 에러 핸들러로 전달됩니다. +자세한 내용은 Node.js 에러 처리 문서를 참고하시기 바랍니다. ```js -app.get('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -이제 모든 비동기식 오류 및 동기식 오류는 error 미들웨어로 전파됩니다. - -그러나 주의해야 할 사항이 두 가지 있습니다. - -1. 모든 비동기식 코드는 프로미스를 리턴해야 합니다(이미터 제외). 특정한 라이브러리가 프로미스를 리턴하지 않는 경우에는 [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html)과 같은 헬퍼 함수를 사용하여 기본 오브젝트를 변환하십시오. -2. 이벤트 이미터(스트림 등)는 여전히 처리되지 않은 예외를 발생시킬 수 있습니다. 따라서 오류 이벤트를 올바르게 처리하고 있는지 확인하십시오. 예를 들면 다음과 같습니다. +또한 미들웨어에 비동기 함수를 사용할 수 있으며, 만약 프로미스가 실패할 경우 라우터가 자동으로 에러를 처리합니다 예를 들면 다음과 같습니다. ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` +성능과 유지 보수 측면에서 가장 좋은 방법은 에러를 가능한 발생 지점 가까이에서 처리하는 것입니다. 따라서 라우터가 에러를 처리할 수 있더라도 별도의 에러 처리 미들웨어에 의존하기보다 미들웨어 내에서 에러를 직접 잡아 처리하는 것이 권장됩니다. -`wrap()` 함수는 거부된 프로미스를 캐치해서 에러를 첫번째 인수로 두고 `next()`를 호출합니다. 자세한 정보는 다음을 참조하십시오. -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) +#### 하지 말아야 할 일 -프로미스를 사용한 오류 처리에 대한 자세한 정보는 다음을 참조하십시오. -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +수행하지 _않아야_ 할 한 가지 항목은 예외가 이벤트 루프에까지 발생할 때 생성되는 `uncaughtException` 이벤트를 청취하는 것입니다. `uncaughtException`에 대한 이벤트 리스너를 추가하면 예외가 발생하는 프로세스의 기본 작동을 변경할 수 있으며, 해당 프로세스는 예외가 발생하더라도 계속하여 실행될 것입니다. 이러한 방법은 앱에서 충돌이 발생하는 것을 방지하는 좋은 방법인 것처럼 보일 수 있지만, 처리되지 않은 예외가 발생한 후에도 앱이 계속하여 실행되면 프로세스가 불안정하고 예측할 수 없는 상태가 되므로 이러한 방법은 위험한 작업 방식이며 권장되지 않습니다. - +또한 `uncaughtException`을 사용하는 것은 [세련되지 못한 방식](https://nodejs.org/api/process.html#process_event_uncaughtexception)인 것으로 공식적으로 인식되고 있으며, 코어로부터 이러한 방식을 제거하는 방법이 [제안](https://github.com/nodejs/node-v0.x-archive/issues/2582)되어 있습니다. 따라서 `uncaughtException`을 청취하는 것은 좋은 생각이 아닙니다. 따라서 여러 프로세스 및 수퍼바이저의 사용 등을 권장하며, 오류로부터 복구되는 가장 안정적인 방법은 충돌이 발생한 후 다시 시작하는 것인 경우가 많습니다. + +[도메인](https://nodejs.org/api/domain.html)의 사용 또한 권장하지 않습니다. 일반적으로 도메인은 문제를 해결하지 못하며, 더 이상 사용되지 않는 모듈입니다. ## 환경/설정에서 수행할 항목 앱의 성능을 향상시키기 위해서 시스템 환경에서 할 수 있는 몇 가지는 다음과 같습니다. -* [NODE_ENV를 "production"으로 설정](#set-node_env-to-production) -* [앱이 자동으로 다시 시작되도록 보장](#ensure-your-app-automatically-restarts) -* [앱을 클러스터에서 실행](#run-your-app-in-a-cluster) -* [요청 결과를 캐싱](#cache-request-results) -* [로드 밸런서 사용](#use-a-load-balancer) -* [역방향 프록시 사용](#proxy) +- [NODE_ENV를 "production"으로 설정](#set-node_env-to-production) +- [앱이 자동으로 다시 시작되도록 보장](#ensure-your-app-automatically-restarts) +- [앱을 클러스터에서 실행](#run-your-app-in-a-cluster) +- [요청 결과를 캐싱](#cache-request-results) +- [로드 밸런서 사용](#use-a-load-balancer) +- [역방향 프록시 사용](#proxy) - ### NODE_ENV를 "production"으로 설정 -NODE_ENV 환경 변수는 애플리케이션이 실행되는 환경(일반적으로 개발 환경 또는 프로덕션 환경)을 지정합니다. 성능을 향상시키기 위해 할 수 있는 가장 간단한 일 중 하나는 NODE_ENV를 "production"으로 설정하는 것입니다. +NODE_ENV 환경 변수는 애플리케이션이 실행되는 환경(일반적으로 개발 환경 또는 프로덕션 환경)을 지정합니다. 성능을 향상하는 가장 간단한 방법 중 하나는 환경 변수 NODE_ENV를 `production`으로 설정하는 것입니다. NODE_ENV를 "production"으로 설정하면 Express는 다음과 같이 동작합니다. -* 보기 템플리트를 캐싱. -* CSS 확장기능을 통해 생성된 CSS 파일을 캐싱. -* 더 간결한 오류 메시지를 생성. +- 보기 템플리트를 캐싱. +- CSS 확장기능을 통해 생성된 CSS 파일을 캐싱. +- 더 간결한 오류 메시지를 생성. -[테스트 결과,](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) NODE_ENV를 "production"으로 설정하기만 해도 앱 성능이 3배 향상되는 것으로 나타났습니다! +[테스트 결과에 따르면]((https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) NODE_ENV를 production으로 설정하는 것만으로도 애플리케이션 성능이 3배 향상될 수 있음이 확인되었습니다. 특정한 환경을 위한 코드를 작성하는 경우, `process.env.NODE_ENV`를 통해 NODE_ENV의 값을 확인할 수 있습니다. 환경 변수의 값을 확인하는 작업은 성능 저하를 유발하므로 이러한 작업은 낮은 빈도로 실행해야 한다는 점에 주의하십시오. -일반적으로 개발 시에는, 예를 들면 `export` 또는 `.bash_profile` 파일을 이용하여 대화식 쉘에서 환경 변수를 설정할 수 있습니다. 그러나 일반적으로 프로덕션 서버에서 이러한 방식을 이용해서는 안 되며, 대신 해당 OS의 init 시스템(systemd 또는 Upstart)을 사용해야 합니다. 다음 섹션에서 일반적인 init 시스템의 사용에 대한 자세한 내용을 확인할 수 있지만, NODE_ENV를 설정하는 것은 성능에 매우 중요하므로(또한 쉽게 실행할 수 있으므로) NODE_ENV의 설정을 여기서 강조합니다. - -Upstart를 이용하는 경우, 작업 파일에 `env` 키워드를 사용하십시오. 예를 들면 다음과 같습니다. - - -```sh -# /etc/init/env.conf - env NODE_ENV=production -``` - -자세한 정보는 [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables)를 참조하십시오. +일반적으로 개발 시에는, 예를 들면 `export` 또는 `.bash_profile` 파일을 이용하여 대화식 쉘에서 환경 변수를 설정할 수 있습니다. 하지만 일반적으로 프로덕션 서버에서는 직접 설정하지 않고, 대신 운영체제의 초기화 시스템(systemd 등) 사용하는 것이 권장됩니다. 다음 섹션에서 일반적인 init 시스템의 사용에 대한 자세한 내용을 확인할 수 있지만, NODE_ENV를 설정하는 것은 성능에 매우 중요하므로(또한 쉽게 실행할 수 있으므로) NODE_ENV의 설정을 여기서 강조합니다. systemd를 이용하는 경우, 유닛 파일에 `Environment` 지시문을 사용하십시오. 예를 들면 다음과 같습니다. @@ -221,17 +178,14 @@ systemd를 이용하는 경우, 유닛 파일에 `Environment` 지시문을 사 Environment=NODE_ENV=production ``` -자세한 정보는 [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html)를 참조하십시오. +자세한 내용은 [systemd 유닛에서 환경 변수 사용하기를](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/) 참고하시기 바랍니다. -StrongLoop Process Manager를 이용하는 경우에는 [StrongLoop PM을 서비스로 설치할 때 환경 변수를 설정](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables)할 수도 있습니다. - - ### 앱이 자동으로 다시 시작되도록 보장 프로덕션 환경에서 애플리케이션이 오프라인 상태가 되어서는 절대로 안 됩니다. 따라서 앱에서 충돌이 발생하거나 서버 자체에서 충돌이 발생하는 경우 모두 앱이 다시 시작되도록 해야 합니다. 이러한 일 중 어느 하나라도 발생하지 않는 것이 바람직하지만, 현실적으로는 다음과 같은 방법을 통해 이 두 가지 만일의 사태를 처리해야 합니다. -* 앱에서 충돌이 발생하는 경우 프로세스 관리자를 사용하여 앱(및 Node)을 다시 시작. -* OS에서 충돌이 발생하는 경우 해당 OS에서 제공하는 init 시스템을 사용하여 프로세스 관리자를 다시 시작. 프로세스 관리자 없이도 init 시스템을 사용할 수 있습니다. +- 앱에서 충돌이 발생하는 경우 프로세스 관리자를 사용하여 앱(및 Node)을 다시 시작. +- OS에서 충돌이 발생하는 경우 해당 OS에서 제공하는 init 시스템을 사용하여 프로세스 관리자를 다시 시작. 프로세스 관리자 없이도 init 시스템을 사용할 수 있습니다. 처리되지 않은 예외가 발생하는 경우 Node 애플리케이션에서 충돌이 발생합니다. 가장 먼저 해야 할 일은 앱의 테스트가 잘 이루어지도록 하고 앱이 모든 예외를 처리하도록 하는 것입니다(자세한 내용은 [올바른 예외 처리](#exceptions)를 참조). 그러나 하나의 안전 장치로서, 앱에서 충돌이 발생하는 경우에 앱이 자동으로 다시 시작되도록 하는 메커니즘을 실행하십시오. @@ -241,54 +195,35 @@ StrongLoop Process Manager를 이용하는 경우에는 [StrongLoop PM을 서비 앱에서 충돌이 발생할 때 앱이 다시 시작되도록 하는 것 이외에도, 프로세스 관리자를 통해 다음을 실행할 수 있습니다. -* 런타임 성능 및 자원 소비에 대한 통찰력을 획득. -* 성능 향상을 위해 설정을 동적으로 수정. -* 클러스터링을 제어(StrongLoop PM 및 pm2). - -가장 널리 사용되는 Node용 프로세스 관리자는 다음과 같습니다. - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -위 세 개의 프로세스 관리자에 대한 기능별 비교를 확인하려면 [http://strong-pm.io/compare/](http://strong-pm.io/compare/)를 참조하십시오. 세 프로세스 관리자 모두에 대한 자세한 내용은 [Express 앱용 프로세스 관리자](/{{ page.lang }}/advanced/pm.html)를 참조하십시오. - -이러한 프로세스 관리자 중 어느 하나를 사용하면, 때때로 앱에서 충돌이 발생하는 경우에도, 충분히 앱이 지속적으로 작동하도록 할 수 있습니다. - -그러나 StrongLoop PM은 구체적으로 프로덕션 배치 환경을 대상으로 하는 여러 기능을 갖추고 있습니다. StrongLoop PM 및 관련된 StrongLoop 도구를 사용하면 다음을 실행할 수 있습니다. +- 런타임 성능 및 자원 소비에 대한 통찰력을 획득. +- 성능 향상을 위해 설정을 동적으로 수정. +- 제어 클라스터링 (pm2) -* 로컬 환경에서 앱을 빌드 및 패키징한 후 프로덕션 시스템에 안전하게 앱을 배치. -* 어떠한 이유로라도 앱에서 충돌이 발생할 경우 앱을 자동으로 다시 시작. -* 클러스터를 원격으로 관리. -* CPU 프로파일 및 힙 스냅샷을 확인하여 성능을 최적화하고 메모리 누수를 진단. -* 애플리케이션에 대한 성능 지표를 확인. -* Nginx 로드 밸런서에 대한 내장된 제어 기능을 통해 여러 호스트로 쉽게 확장. - -아래에 설명된 것과 같이, init 시스템을 이용해 StrongLoop PM을 운영 체제 시스템으로서 설치하면 StrongLoop PM은 시스템이 다시 시작될 때 자동으로 다시 시작됩니다. 따라서 애플리케이션 프로세스 및 클러스터는 항상 작동 상태를 유지할 수 있습니다. +과거에는 [PM2](https://github.com/Unitech/pm2)와 같은 Node.js 프로세스 매니저를 사용하는 것이 널리 퍼져 있었습니다. 원하신다면 해당 문서를 참고하시기 바랍니다. 하지만 프로세스 관리를 위해서는 init 시스템을 사용하는 것을 권장합니다. #### init 시스템 사용 -신뢰성의 다음 단계는 서버가 다시 시작될 때 애플리케이션이 다시 시작되도록 하는 것입니다. 시스템은 여전히 여러 이유로 작동이 중단될 수 있습니다. 서버에서 충돌이 발생할 때 앱이 다시 시작되도록 하려면 OS에 내장된 init 시스템을 사용하십시오. 현재 사용되고 있는 두 가지 주요 init 시스템은 [systemd](https://wiki.debian.org/systemd) 및 [Upstart](http://upstart.ubuntu.com/)입니다. +신뢰성의 다음 단계는 서버가 다시 시작될 때 애플리케이션이 다시 시작되도록 하는 것입니다. 시스템은 여전히 여러 이유로 작동이 중단될 수 있습니다. 서버에서 충돌이 발생할 때 앱이 다시 시작되도록 하려면 OS에 내장된 init 시스템을 사용하십시오. 현재 가장 널리 사용되는 init 시스템은 [systemd](https://wiki.debian.org/systemd)입니다. Express 앱에 init 시스템을 사용하는 데에는 다음과 같은 두 가지 방법이 있습니다. -* 프로세스 관리자에서 앱을 실행한 후, init 시스템을 통해 프로세스 관리자를 서비스로서 설치하십시오. 프로세스 관리자는 앱에서 충돌이 발생할 때 앱을 자동으로 시작하고, init 시스템은 OS가 다시 시작될 때 프로세스 관리자를 다시 시작할 것입니다. 이러한 접근법은 권장되는 접근법입니다. -* init 시스템을 통해 직접 앱(및 Node)을 실행하십시오. 이 방법은 조금 더 간편하지만, 프로세스 관리자의 사용을 통한 추가적인 이점을 얻을 수 없습니다. +- 프로세스 관리자에서 앱을 실행한 후, init 시스템을 통해 프로세스 관리자를 서비스로서 설치하십시오. 프로세스 관리자는 앱에서 충돌이 발생할 때 앱을 자동으로 시작하고, init 시스템은 OS가 다시 시작될 때 프로세스 관리자를 다시 시작할 것입니다. 이러한 접근법은 권장되는 접근법입니다. +- init 시스템을 통해 직접 앱(및 Node)을 실행하십시오. 이 방법은 조금 더 간편하지만, 프로세스 관리자의 사용을 통한 추가적인 이점을 얻을 수 없습니다. ##### Systemd Systemd는 Linux용 시스템 및 서비스 관리자입니다. 대부분의 주요 Linux 배포판은 systemd를 기본 init 시스템으로 도입했습니다. -systemd 서비스 구성 파일은 *유닛 파일(unit file)*로 불리며, 파일 이름이 .service로 끝납니다. Node 앱을 직접 관리하기 위한 유닛 파일의 예는 다음과 같습니다(굵은체로 표시된 텍스트를 해당 시스템 및 앱에 대한 값으로 바꾸십시오). +systemd 서비스 구성 파일은 \*유닛 파일(unit file)\*로 불리며, 파일 이름이 .service로 끝납니다. 아래는 Node 애플리케이션을 직접 관리하기 위한 파일 예시입니다. 시스템과 애플리케이션에 맞게 `` 로 표시된 값을 교체하시기 바랍니다. ```sh [Unit] -Description=Awesome Express App +Description= [Service] Type=simple -ExecStart=/usr/local/bin/node /projects/myapp/index.js -WorkingDirectory=/projects/myapp +ExecStart=/usr/local/bin/node +WorkingDirectory= User=nobody Group=nogroup @@ -310,105 +245,14 @@ Restart=always [Install] WantedBy=multi-user.target ``` -systemd에 대한 자세한 정보는 [systemd 참조 자료(man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html)를 참조하십시오. - -##### systemd의 서비스로서의 StrongLoop PM - -StrongLoop Process Manager는 쉽게 systemd의 서비스로서 설치할 수 있습니다. StrongLoop PM을 systemd의 서비스로서 설치한 후 서버가 다시 시작되면 StrongLoop PM이 자동으로 다시 시작되며, 이후 StrongLoop PM이 관리 중인 모든 앱이 다시 시작됩니다. - -StrongLoop PM을 systemd의 서비스로서 설치하는 방법은 다음과 같습니다. - -
    -
    -$ sudo sl-pm-install --systemd
    -
    -
    - -이후 다음과 같이 서비스를 시작하십시오. - -```sh -$ sudo sl-pm-install --systemd -``` - -자세한 정보는 [Setting up a production host(StrongLoop 문서)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10)를 참조하십시오. - -##### Upstart - -Upstart는 시스템 시작 시에 태스크 및 서비스를 시작하고, 시스템 종료 시에 태스크 및 서비스를 중지하고, 태스크 및 서비스를 감시할 수 있는 시스템 도구이며, 여러 Linux 배포판에서 사용할 수 있습니다. Express 앱 또는 프로세스 관리자를 서비스로서 구성하면, Express 앱 또는 프로세스 관리자에서 충돌이 발생할 때 Upstart가 Express 앱 또는 프로세스 관리자를 자동으로 다시 시작할 수 있습니다. - -Upstart 서비스는 파일 이름이 `.conf`로 끝나는 작업 구성 파일("작업(job)"으로도 불림)에 정의됩니다. 다음 예는 기본 파일의 위치가 `/projects/myapp/index.js`인 "myapp"이라는 이름의 앱에 대해 "myapp"이라는 이름의 작업을 작성하는 방법을 나타냅니다. - -다음의 내용이 입력된 `myapp.conf`라는 이름의 파일을 `/etc/init/`에 작성하십시오(굵은체로 표시된 텍스트를 해당 시스템 및 앱에 대한 값으로 바꾸십시오). - -```sh -# When to start the process -start on runlevel [2345] - -# When to stop the process -stop on runlevel [016] - -# Increase file descriptor limit to be able to handle more requests -limit nofile 50000 50000 - -# Use production mode -env NODE_ENV=production - -# Run as www-data -setuid www-data -setgid www-data - -# Run from inside the app dir -chdir /projects/myapp - -# The process to start -exec /usr/local/bin/node /projects/myapp/index.js - -# Restart the process if it is down -respawn - -# Limit restart attempt to 10 times within 10 seconds -respawn limit 10 10 -``` - -참고: 이 스크립트를 실행하려면 Ubuntu 12.04-14.10에서 지원되는 Upstart 1.4 이상이 필요합니다. - -이 작업은 시스템이 시작될 때 실행되도록 구성되었으므로 앱은 운영 체제와 함께 시작되며, 앱에서 충돌이 발생하거나 시스템의 작동이 중단되는 경우 앱이 자동으로 다시 시작됩니다. - -앱을 자동으로 다시 시작하는 것 이외에도, Upstart를 이용하면 다음과 같은 명령을 사용할 수 있습니다. - -* `start myapp` – 앱을 시작 -* `restart myapp` – 앱을 다시 시작 -* `stop myapp` – 앱을 중지 - -Upstart에 대한 자세한 정보는 [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook)를 참조하십시오. - -##### Upstart의 서비스로서의 StrongLoop PM - -StrongLoop Process Manager는 쉽게 Upstart의 서비스로 설치할 수 있습니다. StrongLoop PM을 Upstart의 서비스로 설치한 후 서버가 다시 시작되면 StrongLoop PM이 자동으로 다시 시작되며, 이후 StrongLoop PM이 관리 중인 모든 앱이 다시 시작됩니다. - -StrongLoop PM을 Upstart 1.4의 서비스로서 설치하는 방법은 다음과 같습니다. - - -```sh -$ sudo sl-pm-install -``` - -이후 다음과 같이 서비스를 실행하십시오. - - -```sh -$ sudo /sbin/initctl start strong-pm -``` - -참고: Upstart 1.4를 지원하지 않는 시스템에서는 약간 다른 명령이 사용됩니다. 자세한 정보는 [Setting up a production host(StrongLoop 문서)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10)를 참조하십시오. +systemd에 대한 자세한 정보는 [systemd 참조 자료(man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html)를 참조하십시오. - ### 앱을 클러스터에서 실행 멀티코어 시스템에서는 프로세스 클러스터를 실행하여 Node 앱의 성능을 여러 배 높일 수 있습니다. 클러스터는 해당 앱의 인스턴스를 여러 개 실행하여(이상적인 경우 각 CPU 코어에서 하나의 인스턴스를 실행) 인스턴스들 사이에서 로드 및 태스크를 분배합니다. - +![클러스터 API를 사용한 애플리케이션 인스턴스간 부하 분산](/images/clustering.png) 중요: 앱 인스턴스들은 별도의 프로세스로서 실행되므로 이러한 인스턴스들은 동일한 메모리 공간을 공유하지 않습니다. 즉, 오브젝트는 해당 앱의 각 인스턴스에 대한 로컬 오브젝트입니다. 따라서 애플리케이션 코드 내의 상태를 유지보수할 수 없습니다. 그러나 [Redis](http://redis.io/)와 같은 인메모리 데이터 저장소를 사용하면 세션과 관련된 데이터 및 상태를 저장할 수 있습니다. 이러한 주의사항은 기본적으로 여러 프로세스를 이용한 클러스터링 또는 여러 대의 실제 서버를 이용한 클러스터링 등 모든 형태의 수평적 확장에 적용됩니다. @@ -416,74 +260,53 @@ $ sudo /sbin/initctl start strong-pm #### Node의 cluster 모듈 사용 -Node의 [cluster 모듈](https://nodejs.org/docs/latest/api/cluster.html)을 사용하면 클러스터링이 가능합니다. 이러한 클러스터링을 통해 마스터 프로세스는 여러 작업자 프로세스를 복제생성하고, 수신되는 연결을 여러 작업자 사이에서 분배할 수 있습니다. 그러나 이러한 모듈을 직접 사용하는 대신, 이를 자동으로 실행하는 여러 도구 중 하나를 사용하는 것이 훨씬 더 좋습니다. 이러한 도구의 예로는 [node-pm](https://www.npmjs.com/package/node-pm) 또는 [cluster-service](https://www.npmjs.com/package/cluster-service)가 있습니다. - -#### StrongLoop PM 사용 - -애플리케이션을 StrongLoop Process Manager(PM)에 배치하면, 애플리케이션 코드를 수정하지 *않고도* 클러스터링을 활용할 수 있습니다. - -StrongLoop Process Manager(PM)가 애플리케이션으로서 실행되면, StrongLoop PM은 시스템의 CPU 코어 수와 같은 수의 작업자를 갖는 클러스터 내에서 자신을 실행합니다. 사용자는 앱을 중지시키지 않고도 slc 명령행 도구를 이용해 수동으로 클러스터 내의 작업자 프로세스의 수를 변경할 수 있습니다. - -예를 들어 prod.foo.com에 앱을 배치했으며 StrongLoop PM이 포트 8701(기본값)에서 청취하는 경우를 가정하면, 다음과 같이 slc를 이용해 클러스터의 크기를 8로 설정할 수 있습니다. - -```sh -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8 -``` - -StrongLoop PM을 이용한 클러스터링에 대한 자세한 정보는 StrongLoop 문서 내의 [Clustering](https://docs.strongloop.com/display/SLC/Clustering)을 참조하십시오. +클러스터링은 Node의 [cluster 모듈](https://nodejs.org/api/cluster.html)을 통해 가능합니다. 이러한 클러스터링을 통해 마스터 프로세스는 여러 작업자 프로세스를 복제생성하고, 수신되는 연결을 여러 작업자 사이에서 분배할 수 있습니다. #### PM2 사용 -애플리케이션을 PM2에 배치하면, 애플리케이션 코드를 수정하지 *않고도* 클러스터링을 활용할 수 있습니다. 먼저 여러분의 [애플리케이션이 stateless인지](http://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) 확실하게 해야합니다. 어떠한 로컬 데이터도 프로세스에 저장되지 않아야 합니다. (세션이나 웹소켓 같은 것들 말입니다). +애플리케이션을 PM2에 배치하면, 애플리케이션 코드를 수정하지 _않고도_ 클러스터링을 활용할 수 있습니다. 먼저 [애플리케이션이 상태 비저장(stateless)](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps)인지 확인해야 합니다 즉, 프로세스 내에 세션, 웹소켓 연결 등 로컬 데이터가 저장되어 있지 않아야 합니다. PM2로 애플리케이션을 실행하고 있을 때, 특정한 수의 인스턴스에 실행하는 **클러스터 모드**를 켤 수 있습니다. 머신의 가용 CPU 수같은 것들이 특정한 수입니다. 애플리케이션을 끌 필요 없이 `pm2` 커맨드라인 명령을 이용해 클러스터에 있는 프로세스의 수를 직접 바꿀 수도 있습니다. 아래와 같은 방법으로 클러스터 모드를 킵니다. -```sh +```bash # Start 4 worker processes -$ pm2 start app.js -i 4 +$ pm2 start npm --name my-app -i 4 -- start # Auto-detect number of available CPUs and start that many worker processes -$ pm2 start app.js -i max +$ pm2 start npm --name my-app -i max -- start ``` 이 수는 PM2 프로세스 파일 (`ecosystem.config.js`나 그와 유사한 파일) 안의 `exec_mode`를 `cluster`나 `instances`를 설정해서 수정될 수 있습니다. 실행이 시작되면, `app`으로 이름지어진 애플리케이션을 아래와 같은 방법으로 스케일링 할 수 있습니다. -```sh +```bash # Add 3 more workers -$ pm2 scale app +3 +$ pm2 scale my-app +3 # Scale to a specific number of workers -$ pm2 scale app 2 +$ pm2 scale my-app 2 ``` PM2의 클러스터링에 관한 추가 정보는 PM2 문서의 [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/)를 참고해주세요. - ### 요청 결과를 캐싱 프로덕션 환경 내에서의 성능을 향상시키기 위한 또 다른 전략은 요청의 결과를 캐싱하여 앱이 동일한 요청을 반복적으로 제공하는 작업을 반복하지 않도록 하는 것입니다. -[Varnish](https://www.varnish-cache.org/) 또는 [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/)([Nginx Caching](https://serversforhackers.com/nginx-caching/) 또한 참조)와 같은 캐싱 서버를 이용하면 앱의 속도 및 성능을 크게 향상시킬 수 있습니다. - +애플리케이션의 속도와 성능을 크게 향상시키려면 [Varnish](https://www.varnish-cache.org/) 또는 [Nginx](https://blog.nginx.org/blog/nginx-caching-guide)와 같은 캐싱 서버를 사용하는 것이 좋습니다. +(참고: [Nginx 캐싱 가이드](https://serversforhackers.com/nginx-caching/)) - ### 로드 밸런서 사용 앱의 최적화 수준에 상관없이, 하나의 인스턴스는 제한된 양의 로드 및 트래픽만을 처리할 수 있습니다. 앱을 확장하는 방법 중 하나는 해당 앱의 인스턴스를 여러 개 실행하고 로드 밸런서를 통해 트래픽을 분배하는 것입니다. 로드 밸런서를 설정하면 앱의 성능 및 속도를 향상시킬 수 있으며, 하나의 인스턴스를 이용할 때보다 훨씬 더 높은 수준으로 확장할 수 있습니다. -로드 밸런서는 일반적으로 여러 애플리케이션 인스턴스 및 서버에 대한 트래픽을 오케스트레이션하는 역방향 프록시입니다. [Nginx](http://nginx.org/en/docs/http/load_balancing.html) 또는 [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts)를 이용하면 앱에 대한 로드 밸런서를 쉽게 설정할 수 있습니다. - -로드 밸런싱을 이용하는 경우, 특정한 세션 ID와 연관된 요청이 해당 요청을 발생시킨 프로세스에 연결되도록 해야 할 수도 있습니다. 이러한 경우는 *세션 선호도(session affinity)* 또는 *스티키 세션(sticky session)*으로 알려져 있으며, 세션 데이터를 위해 Redis와 같은 데이터 저장소를 사용하는 위의 제안을 통해 처리할 수도 있습니다(애플리케이션에 따라 다름). 토론을 위해서는 [Using multiple nodes](http://socket.io/docs/using-multiple-nodes/)를 참조하십시오. - -#### Nginx 로드 밸런서와 함께 StrongLoop PM 사용 +로드 밸런서는 일반적으로 여러 애플리케이션 인스턴스 및 서버에 대한 트래픽을 오케스트레이션하는 역방향 프록시입니다. 애플리케이션의 로드 밸런서를 손쉽게 구축하려면 [Nginx](https://nginx.org/en/docs/http/load_balancing.html)또는 [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts)를 활용할 수 있습니다. -[StrongLoop Process Manager](http://strong-pm.io/)는 Nginx Controller와 통합될 수 있으며, 이를 통해 여러 호스트로 이루어진 프로덕션 환경 구성을 쉽게 구성할 수 있습니다. 자세한 정보는 [Scaling to multiple servers](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers)(StrongLoop 문서)를 참조하십시오. - +로드 밸런싱을 이용하는 경우, 특정한 세션 ID와 연관된 요청이 해당 요청을 발생시킨 프로세스에 연결되도록 해야 할 수도 있습니다. 이러한 경우는 _세션 선호도(session affinity)_ 또는 \*스티키 세션(sticky session)\*으로 알려져 있으며, 세션 데이터를 위해 Redis와 같은 데이터 저장소를 사용하는 위의 제안을 통해 처리할 수도 있습니다(애플리케이션에 따라 다름). 토론을 위해서는 [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/)를 참조하십시오. ### 역방향 프록시 사용 역방향 프록시는 웹 앱의 프론트에 위치하며, 요청이 앱으로 전달되도록 할 뿐만 아니라 요청에 대한 지원 연산을 수행합니다. 이는 오류 페이지, 압축, 캐싱, 파일 제공, 로드 밸런싱 및 기타 여러 작업을 처리할 수 있습니다. -애플리케이션 상태를 알아야 할 필요가 없는 태스크를 역방향 프록시로 이양하면 Express는 더 적은 자원을 차지하게 되어 특성화된 애플리케이션 태스크를 수행할 수 있습니다. 따라서 프로덕션 환경에서는 [Nginx](https://www.nginx.com/) 또는 [HAProxy](http://www.haproxy.org/)와 같은 역방향 프록시 뒤에서 Express를 실행할 것을 권장합니다. +애플리케이션 상태를 알아야 할 필요가 없는 태스크를 역방향 프록시로 이양하면 Express는 더 적은 자원을 차지하게 되어 특성화된 애플리케이션 태스크를 수행할 수 있습니다. 이러한 이유로 프로덕션환경에서는 Express를 [Nginx](https://www.nginx.org/) 또는 [HAProxy](https://www.haproxy.org/)와 같은 리버스 프록시 뒤에서 실행하는 것을 권장합니다. diff --git a/ko/advanced/best-practice-security.md b/ko/advanced/best-practice-security.md old mode 100755 new mode 100644 index 6c34f8a90c..43155eb952 --- a/ko/advanced/best-practice-security.md +++ b/ko/advanced/best-practice-security.md @@ -1,120 +1,184 @@ --- layout: page title: 프로덕션 환경의 Express를 위한 보안 우수 사례 +description: Express 애플리케이션을 프로덕션 환경에서 운영할 때 반드시 지켜야 할 중요한 보안 모범 사례를 알아봅니다. 여기에는 TLS 사용, 입력값 검증, 보안 쿠키 설정, 그리고 다양한 취약점 예방 방법이 포함됩니다. menu: advanced -lang: ko +redirect_from: " " --- # 프로덕션 우수 사례: 보안 ## 개요 -__"프로덕션 (production)"__ 이라는 용어는 소프트웨어 라이프사이클 중 애플리케이션 또는 API가 최종 사용자 또는 소비자에게 정식으로 제공되는 단계를 말합니다. 이와 반대로 *"개발(development)"* 단계에서는 아직 코드가 활발하게 작성 및 테스트되며 애플리케이션은 외부 액세스에 개방되지 않습니다. 이에 대응하는 시스템 환경은 각각 *프로덕션* 환경 및 *개발* 환경이라고 부릅니다. +**"프로덕션 (production)"** 이라는 용어는 소프트웨어 라이프사이클 중 애플리케이션 또는 API가 최종 사용자 또는 소비자에게 정식으로 제공되는 단계를 말합니다. 이와 반대로 _"개발(development)"_ 단계에서는 아직 코드가 활발하게 작성 및 테스트되며 애플리케이션은 외부 액세스에 개방되지 않습니다. 이에 대응하는 시스템 환경은 각각 _프로덕션_ 환경 및 _개발_ 환경이라고 부릅니다. 개발 환경 및 프로덕션 환경은 일반적으로 서로 다르게 설정되며 두 환경의 요구사항은 크게 다릅니다. 개발 환경에서는 좋은 것일지라도 프로덕션 환경에서는 허용되지 않을 수도 있습니다. 예를 들면, 개발 환경에서는 디버깅을 위해 상세한 오류 로깅이 선호될 수 있지만, 이러한 행동은 프로덕션 환경에서 보안 우려사항이 될 수 있습니다. 그리고 개발 환경에서는 확장성, 신뢰성 및 성능에 대해 걱정할 필요가 없지만, 이러한 요인들은 프로덕션 환경에서 매우 중요해집니다. -{% include note.html content="Express의 보안 취약점을 발견하신것 같다면, -[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures)를 따라주십시오. -" %} +{% capture security-note %} + +만약 Express에서 보안 취약점을 발견하셨다면, [보안 정책 및 절차](/en/resources/contributing.html#security-policies-and-procedures)를 참고하시기 바랍니다. + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} 이 문서에서는 프로덕션 환경에 배치된 Express 애플리케이션을 위한 몇 가지 보안 우수 사례에 대해 논의합니다. -- [더 이상 사용되지 않거나 취약성이 있는 버전의 Express 사용 중지](#dont-use-deprecated-or-vulnerable-versions-of-express) -- [TLS 사용](#use-tls) -- [Helmet 사용](#use-helmet) -- [쿠키를 안전하게 사용](#use-cookies-securely) -- [인증 체계에 대한 브루스 포트 공격 방지](#prevent-brute-force-attacks-against-authorization) -- [종속 항목이 안전한지 확인](#ensure-your-dependencies-are-secure) -- [그 외의 알려져 있는 취약점 회피](#avoid-other-known-vulnerabilities) -- [추가적인 고려사항](#additional-considerations) +- [프로덕션 모범 사례: 보안](#production-best-practices-security) + - [개요](#overview) + - [Express의 사용 중단되었거나 취약한 버전을 사용하지 않습니다](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [TLS 사용](#use-tls) + - [사용자 입력을 신뢰하지 않습니다](#do-not-trust-user-input) + - [오픈 리다이렉트를 방지합니다](#prevent-open-redirects) + - [Helmet 사용](#use-helmet) + - [지문 인식 감소](#reduce-fingerprinting) + - [쿠키를 안전하게 사용](#use-cookies-securely) + - + - [ieNoOpen](https://github.com/helmetjs/ienoopen)은 IE8 이상에 대해 `X-Download-Options`를 설정합니다. + - [인증 체계에 대한 브루스 포트 공격 방지](#prevent-brute-force-attacks-against-authorization) + - [종속 항목이 안전한지 확인](#ensure-your-dependencies-are-secure) + - [그 외의 알려져 있는 취약점 회피](#avoid-other-known-vulnerabilities) + - [추가적인 고려사항](#additional-considerations) - ## 더 이상 사용되지 않거나 취약성이 있는 버전의 Express를 사용 중지 -Express 2.x 및 3.x에 대한 유지보수는 더 이상 이루어지지 않습니다. 이러한 버전에서의 보안 및 성능 문제는 수정되지 않습니다. 이러한 버전은 사용하지 마십시오! 아직 버전 4로 이전하지 않은 경우에는 [마이그레이션 안내서](/{{ page.lang }}/guide/migrating-4.html)를 따르십시오. +Express 2.x 및 3.x에 대한 유지보수는 더 이상 이루어지지 않습니다. 이러한 버전에서의 보안 및 성능 문제는 수정되지 않습니다. 이러한 버전은 사용하지 마십시오! 아직 버전 4로 이전하지 않은 경우에는 [마이그레이션 안내서](/{{ page.lang }}/guide/migrating-4.html)를 따르십시오. 또한 [보안 업데이트 페이지](/{{ page.lang }}/advanced/security-updates.html)의 목록에 포함된 취약성 있는 Express 버전을 사용하고 있지 않은지 확인하십시오. 취약성 있는 Express 버전을 사용하고 있는 경우에는 안정적인 릴리스 중 하나로 업데이트해야 하며, 가능하면 최신 버전으로 업데이트하는 것이 좋습니다. - - ## 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)에 취약합니다. -여러분은 SSL(Secure Socket Layer) 암호화에 익숙할 것입니다. [TLS는 단순히 SSL이 다음 단계로 발전된 형태입니다](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). 즉, 이전에 SSL을 사용했다면 TLS로의 업그레이드를 고려해야 합니다. 일반적으로 TLS의 처리를 위해서는 Nginx를 권장합니다. Nginx(및 기타 서버)에서 TLS를 구성하는 방법에 대한 좋은 참조 자료를 확인하려면 [Recommended Server Configurations(Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations)를 참조하십시오. +여러분은 SSL(Secure Socket Layer) 암호화에 익숙할 것입니다. [TLS는 단순히 SSL이 다음 단계로 발전된 형태입니다](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx). 즉, 이전에 SSL을 사용했다면 TLS로의 업그레이드를 고려해야 합니다. 일반적으로 TLS의 처리를 위해서는 Nginx를 권장합니다. Nginx(및 기타 서버)에서 TLS를 구성하는 방법에 대한 좋은 참조 자료를 확인하려면 [Recommended Server Configurations(Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations)를 참조하십시오. 또한 무료 TLS 인증서를 얻기 위한 편리한 도구 중 하나는 [Internet Security Research Group(ISRG)](https://letsencrypt.org/isrg/)이 제공하는 무료의 자동 개방형 인증 기관(CA)인 [Let's Encrypt](https://letsencrypt.org/about/)입니다. - +## 사용자 입력을 신뢰하지 않습니다 + +웹 애플리케이션에서 가장 중요한 보안 요구 사항 중 하나는 적절한 사용자 입력 검증 및 처리를 수행하는 것입니다. 이는 여러 형태로 나타나며, 이 문서에서는 모든 경우를 다루지 않습니다. +궁극적으로 애플리케이션이 수용하는 사용자 입력 유형을 검증하고 올바르게 처리하는 책임은 개발자에게 있습니다. + +### 오픈 리다이렉트 방지 + +잠재적으로 위험한 사용자 입력의 예로 오픈 리다이렉트가 있습니다. 이는 애플리케이션이 URL을 사용자 입력으로 받아들여 (예: `?url=https://example.com` 쿼리 문자열)\ +`res.redirect`를 사용해 `location` 헤더를 설정하고 3xx 상태 코드를 반환하는 경우입니다. + +애플리케이션은 악성 링크(예: 피싱 사이트) 로 사용자를 유도하는 위험을 방지하기 위해, 들어오는 URL에 대해 리다이렉트를 허용하는지 반드시 검증해야 합니다. + +아래는 `res.redirect` 또는 `res.location`을 사용하기 전에 URL을 검증하는 예시입니다. + +```js +app.use((req, res) => { + try { + if (new Url(req.query.url).host !== 'example.com') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## Helmet 사용 [Helmet](https://www.npmjs.com/package/helmet)을 이용하면 HTTP 헤더를 적절히 설정하여 몇 가지 잘 알려진 웹 취약성으로부터 앱을 보호할 수 있습니다. -사실 Helmet은 보안 관련 HTTP 헤더를 설정하는 다음과 같은 더 작은 크기의 미들웨어 함수 9개의 모음입니다. +Helmet은 보안 관련 HTTP 응답 헤더를 설정하는 미들웨어 함수입니다. Helmet은 기본적으로 다음 헤더들을 설정합니다. + +- `Content-Security-Policy`: 페이지에서 허용되는 콘텐츠를 강력하게 지정하여 여러 공격을 완화합니다. +- `Cross-Origin-Opener-Policy`: 페이지의 프로세스 격리를 돕습니다. +- `Cross-Origin-Resource-Policy`: 다른 출처가 리소스를 크로스 오리진으로 로드하는 것을 차단합니다. +- `Origin-Agent-Cluster`: 프로세스 격리를 출처(origin) 단위로 변경합니다. +- `Referrer-Policy`: [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) 헤더를 제어합니다. +- `Strict-Transport-Security`: 브라우저에 HTTPS를 우선 사용하도록 지시합니다. +- `X-Content-Type-Options`: [MIME 스니핑](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing)을 방지합니다. +- `X-DNS-Prefetch-Control`: DNS 프리페칭 제어를 담당합니다. +- `X-Download-Options`: 다운로드를 저장하도록 강제합니다 (인터넷 익스플로러 전용) +- `X-Frame-Options`: [클릭재킹](https://en.wikipedia.org/wiki/Clickjacking) 공격을 완화하기 위한 레거시 헤더입니다. +- `X-Permitted-Cross-Domain-Policies`: Acrobat과 같은 Adobe 제품의 크로스 도메인 동작을 제어합니다. +- `X-Powered-By`: 웹 서버 정보에 관한 헤더입니다. 해당 헤더는 단순 공격에 악용될 수 있어 제거되었습니다 +- `X-XSS-Protection`: [XSS 공격](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting)을 완화하려 했던 레거시 헤더이나, 오히려 문제를 악화시키기 때문에 Helmet에서는 비활성화합니다 -* [csp](https://github.com/helmetjs/csp)는 `Content-Security-Policy` 헤더를 설정하여 XSS(Cross-site scripting) 공격 및 기타 교차 사이트 인젝션을 예방합니다. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by)는 `X-Powered-By` 헤더를 제거합니다. -* [hsts](https://github.com/helmetjs/hsts)는 서버에 대한 안전한(SSL/TLS를 통한 HTTP) 연결을 적용하는 `Strict-Transport-Security` 헤더를 설정합니다. -* [ieNoOpen](https://github.com/helmetjs/ienoopen)은 IE8 이상에 대해 `X-Download-Options`를 설정합니다. -* [noCache](https://github.com/helmetjs/nocache)는 `Cache-Control` 및 Pragma 헤더를 설정하여 클라이언트 측에서 캐싱을 사용하지 않도록 합니다. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype)는 `X-Content-Type-Options` 를 설정하여, 선언된 콘텐츠 유형으로부터 벗어난 응답에 대한 브라우저의 MIME 가로채기를 방지합니다. -* [frameguard](https://github.com/helmetjs/frameguard)는 `X-Frame-Options` 헤더를 설정하여 [clickjacking](https://www.owasp.org/index.php/Clickjacking)에 대한 보호를 제공합니다. -* [xssFilter](https://github.com/helmetjs/x-xss-protection)는 `X-XSS-Protection`을 설정하여 대부분의 최신 웹 브라우저에서 XSS(Cross-site scripting) 필터를 사용하도록 합니다. +각 헤더는 필요에 따라 설정하거나 비활성화할 수 있습니다. 자세한 내용은 [Helmet 공식 문서를][helmet] 참고하시기 바랍니다. 다른 모든 모듈처럼 Helmet은 다음과 같이 설치할 수 있습니다. -```sh -$ npm install --save helmet +```bash +$ npm install helmet ``` -이후 코드에서 Helmet을 사용하는 방법은 다음과 같습니다. +코드에서 Helmet을 사용하는 방법은 문서를 참고하세요 ```js // ... -var helmet = require('helmet') +const helmet = require('helmet') app.use(helmet()) // ... ``` -### 적어도 X-Powered-By 헤더는 사용하지 않도록 설정 +## 지문 인식(Fingerprinting) 감소 -Helmet의 사용을 원치 않는 경우에는 적어도 `X-Powered-By` 헤더를 사용하지 마십시오. 공격자는 이 헤더(기본적으로 사용하도록 설정되어 있음)를 이용해 Express를 실행하는 앱을 발견한 후 특정한 대상에 대한 공격을 실행할 수 있습니다. +서버가 사용하는 소프트웨어를 공격자가 식별하는 능력을 줄이는 것은 추가적인 보안 계층을 제공할 수 있습니다. 이를 ‘지문 인식(fingerprinting)’이라 합니다. 비록 지문 인식 자체가 직접적인 보안 문제는 아니지만, 이를 줄임으로써 전체적인 보안 수준이 향상됩니다. +서버 소프트웨어는 특정 요청에 대한 응답 방식, 예를 들어 HTTP 응답 헤더 등에서 특이점을 통해 식별될 수 있습니다. 따라서 우수 사례는 다음과 같이 `app.disable()` 메소드를 이용해 이 헤더를 끄는 것입니다. - ```js app.disable('x-powered-by') ``` -`helmet.js`를 사용하는 경우에는 사용자를 대신하여 `helmet.js`가 위의 작업을 실행합니다. +{% capture powered-advisory %} + +`X-Powered-By` 헤더를 비활성화하는 것만으로는 숙련된 공격자가 Express를 사용하는 앱임을 완전히 차단할 수 없습니다. 이는 단순한 공격 시도를 막는 데는 도움이 되지만, 앱이 Express로 작동함을 식별할 수 있는 다른 방법도 존재합니다. -{% include note.html content="`X-Powered-By header`를 비활성화하는 행위는 고수준의 공격자가 앱이 Express를 사용하고 있는지 확인하는 걸 막을 수 없습니다. 일반적인 취약점은 막을지 모르지만, 앱이 Express를 사용하고 있는지 알아내는 다른 방법은 많이 있습니다. "%} +{% endcapture %} + +{% include admonitions/note.html content=powered-advisory %} + +Express는 자체 포맷의 "404 Not Found" 메시지와 포맷터 오류 응답 메시지도 전송합니다. 이러한 응답은\ +[사용자 정의 404 핸들러 추가](/en/starter/faq.html#how-do-i-handle-404-responses) 및\ +[사용자 정의 에러 핸들러 작성](/en/guide/error-handling.html#writing-error-handlers)을 통해 변경할 수 있습니다. + +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` - ## 쿠키를 안전하게 사용 쿠키로 인해 앱이 악용에 노출되지 않도록 하기 위해 기본 세션 쿠키 이름을 사용하지 말고 쿠키 보안 옵션을 적절히 설정하십시오. 두 개의 기본 미들웨어 쿠키 세션 모듈은 다음과 같습니다. -* [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` 미들웨어 대체). +- [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` 미들웨어 대체). -이 두 모듈의 주요 차이점은 쿠키 세션 데이터를 저장하는 방식입니다. [express-session](https://www.npmjs.com/package/express-session) 미들웨어는 세션 데이터를 서버에 저장하며, 쿠키 자체에는 세션 데이터가 아니라 세션 ID만 저장됩니다. 기본적으로 express-session은 인메모리 스토리지를 이용하며, 프로덕션 환경용으로 설계되지 않았습니다. 프로덕션 환경에서는 확장 가능한 session-store를 설정해야 합니다. [호환 가능한 세션 스토어](https://github.com/expressjs/session#compatible-session-stores)의 목록을 참조하십시오. +이 두 모듈의 주요 차이점은 쿠키 세션 데이터를 저장하는 방식입니다. [express-session](https://www.npmjs.com/package/express-session) 미들웨어는 세션 데이터를 서버에 저장하며, 쿠키 자체에는 세션 데이터가 아니라 세션 ID만 저장됩니다. 기본적으로 express-session은 인메모리 스토리지를 이용하며, 프로덕션 환경용으로 설계되지 않았습니다. 프로덕션 환경에서는 확장 가능한 session-store를 설정해야 합니다. [호환 가능한 세션 스토어](https://github.com/expressjs/session#compatible-session-stores)의 목록을 참조하십시오. -이와 반대로 [cookie-session](https://www.npmjs.com/package/cookie-session) 미들웨어는 쿠키 기반의 스토리지를 구현하며, 하나의 세션 키가 아니라 세션 전체를 쿠키에 직렬화합니다. cookie-session은 세션 데이터의 크기가 상대적으로 작으며 (오브젝트가 아닌) 원시 값으로 쉽게 인코딩 가능할 때에만 사용하십시오. 브라우저는 하나의 쿠키당 4,096바이트 이상을 지원하도록 되어 있지만, 한계를 초과하지 않도록 보장하려면 하나의 도메인당 4,093바이트의 크기를 초과하지 마십시오. 또한, 클라이언트에서 쿠키 데이터를 볼 수 있으므로, 쿠키 데이터를 안전하게 또는 모호하게 유지해야 할 이유가 있는 경우에는 express-session을 선택하는 것이 더 나을 수 있습니다. +이와 반대로 [cookie-session](https://www.npmjs.com/package/cookie-session) 미들웨어는 쿠키 기반의 스토리지를 구현하며, 하나의 세션 키가 아니라 세션 전체를 쿠키에 직렬화합니다. cookie-session은 세션 데이터의 크기가 상대적으로 작으며 (오브젝트가 아닌) 원시 값으로 쉽게 인코딩 가능할 때에만 사용하십시오. 브라우저는 하나의 쿠키당 4,096바이트 이상을 지원하도록 되어 있지만, 한계를 초과하지 않도록 보장하려면 하나의 도메인당 4,093바이트의 크기를 초과하지 마십시오. 또한, 클라이언트에서 쿠키 데이터를 볼 수 있으므로, 쿠키 데이터를 안전하게 또는 모호하게 유지해야 할 이유가 있는 경우에는 express-session을 선택하는 것이 더 나을 수 있습니다. -### 기본 세션 쿠키 이름을 사용하지 않음 +### 기본 세션 쿠키 이름을 사용하지 않음 -기본 세션 쿠키 이름을 사용하면 앱을 공격에 노출시킬 수 있습니다. 이로 인해 제기되는 보안 문제는 `X-Powered-By`와 유사하며, 잠재적인 공격자는 이를 이용해 서버의 지문을 채취한 후 이에 따라 공격 대상을 설정할 수 있습니다. +기본 세션 쿠키 이름을 사용하면 앱을 공격에 노출시킬 수 있습니다. 이로 인해 제기되는 보안 문제는 `X-Powered-By`와 유사하며, 잠재적인 공격자는 이를 이용해 서버의 지문을 채취한 후 이에 따라 공격 대상을 설정할 수 있습니다. -이러한 문제점을 피하려면 일반적인 쿠키 이름을 사용하십시오. 예를 들면 [express-session](https://www.npmjs.com/package/express-session) 미들웨어를 이용해 다음과 같이 하십시오. +다음에는 [cookie-session](https://www.npmjs.com/package/cookie-session) 미들웨어를 사용한 예가 표시되어 있습니다. ```js -var session = require('express-session') +const session = require('express-session') app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 's3Cur3', @@ -126,20 +190,20 @@ app.use(session({ 다음과 같은 쿠키 옵션을 설정하여 보안을 강화하십시오. -* `secure` - 브라우저가 HTTPS를 통해서만 쿠키를 전송하도록 합니다. -* `httpOnly` - 쿠키가 클라이언트 JavaScript가 아닌 HTTP(S)를 통해서만 전송되도록 하며, 이를 통해 XSS(Cross-site scripting) 공격으로부터 보호할 수 있습니다. -* `domain` - 쿠키의 도메인을 표시합니다. URL이 요청되고 있는 서버의 도메인에 대해 비교할 때 사용하십시오. 두 도메인이 일치하는 경우에는 그 다음으로 경로 속성을 확인하십시오. -* `path` - 쿠키의 경로를 표시합니다. 요청 경로에 대해 비교할 때 사용하십시오. 이 경로와 도메인이 일치하는 경우에는 요청되고 있는 쿠키를 전송하십시오. -* `expires` - 지속적 쿠키에 대한 만기 날짜를 설정하는 데 사용됩니다. +- `secure` - 브라우저가 HTTPS를 통해서만 쿠키를 전송하도록 합니다. +- `httpOnly` - 쿠키가 클라이언트 JavaScript가 아닌 HTTP(S)를 통해서만 전송되도록 하며, 이를 통해 XSS(Cross-site scripting) 공격으로부터 보호할 수 있습니다. +- `domain` - 쿠키의 도메인을 표시합니다. URL이 요청되고 있는 서버의 도메인에 대해 비교할 때 사용하십시오. 두 도메인이 일치하는 경우에는 그 다음으로 경로 속성을 확인하십시오. +- `path` - 쿠키의 경로를 표시합니다. 요청 경로에 대해 비교할 때 사용하십시오. 이 경로와 도메인이 일치하는 경우에는 요청되고 있는 쿠키를 전송하십시오. +- `expires` - 지속적 쿠키에 대한 만기 날짜를 설정하는 데 사용됩니다. -다음에는 [cookie-session](https://www.npmjs.com/package/cookie-session) 미들웨어를 사용한 예가 표시되어 있습니다. +[noCache](https://github.com/helmetjs/nocache)는 `Cache-Control` 및 Pragma 헤더를 설정하여 클라이언트 측에서 캐싱을 사용하지 않도록 합니다. ```js -var session = require('cookie-session') -var express = require('express') -var app = express() +const session = require('cookie-session') +const express = require('express') +const app = express() -var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour app.use(session({ name: 'session', keys: ['key1', 'key2'], @@ -153,55 +217,56 @@ app.use(session({ })) ``` - +## 인증에 대한 무차별 대입 공격(Brute-force) 방지 + +로그인 엔드포인트를 보호하여 개인정보를 안전하게 유지해야 합니다. + +간단하면서도 효과적인 방법 중 하나는 다음 두 가지 기준으로 인증 시도를 차단하는 것입니다: + +1. . +2. IP 주소로부터의 오랜 시간 동안의 실패 시도 횟수입니다. 예를 들어, 하루 동안 100번의 실패 시도를 한 경우 해당 IP 주소를 차단할 수 있습니다. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) 패키지는 이 기술을 쉽고 빠르게 구현할 수 있는 도구들을 제공합니다. [문서에서 brute-force 방지 예제](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection)를 참고할 수 있습니다. + ## 종속 항목이 안전한지 확인 -npm을 이용해 애플리케이션의 종속 항목을 관리하는 것은 강력하면서도 편리합니다. 그러나 사용 중인 패키지에는 애플리케이션에 영향을 미칠 수 있는 치명적인 보안 취약성이 포함되어 있을 수도 있습니다. 앱의 보안성은 종속 항목 내의 "가장 약한 링크"의 보안성에 따라 결정됩니다. +npm을 이용해 애플리케이션의 종속 항목을 관리하는 것은 강력하면서도 편리합니다. 그러나 사용 중인 패키지에는 애플리케이션에 영향을 미칠 수 있는 치명적인 보안 취약성이 포함되어 있을 수도 있습니다. 앱의 보안성은 종속 항목 내의 "가장 약한 링크"의 보안성에 따라 결정됩니다. npm@6부터 npm은 자동으로 모든 설치 요청을 검사합니다. 또한 `npm audit`을 이용해 여러분의 의존성 트리를 검사할 수 있습니다. -```sh +```bash $ npm audit ``` 더 강한 보안을 원한다면, [Snyk](https://snyk.io/)를 사용하십시오. -Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github 통합](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: -Sync는 [커맨드라인 도구](https://www.npmjs.com/package/snyk)와 [Snyk's open source vulnerability database](https://snyk.io/vuln/)에 있는 여러분의 의존성들의 알려진 취약성에 대한 검사를 실행하는 [Github integration](https://snyk.io/docs/github)을 제공합니다. 아래 커맨드로 설치합니다. +Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github 통합](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. 다음과 같이 CLI을 설치합니다: -```sh +```bash $ npm install -g snyk $ cd your-app ``` 아래 명령으로 애플리케이션의 취약점을 검사합니다. -```sh +```bash $ snyk test ``` -Use this command to open a wizard that walks you through the process of applying updates or patches to fix the vulnerabilities that were found: -아래 명령으로 찾은 취약점을 고치는 패치나 업데이트를 받는 설치 마법사를 실행합니다. +### 그 외의 알려져 있는 취약점 회피 -```sh -$ snyk wizard -``` - - -## 그 외의 알려져 있는 취약점 회피 +Express에, 또는 앱에 사용되는 다른 모듈에 영향을 미칠 수 있는 [Node Security Project](https://npmjs.com/advisories)의 보안 권고문에 항상 주의를 기울이십시오. 일반적으로 Node Security Project는 Node의 보안과 관련된 지식 및 도구에 대한 훌륭한 자원입니다. -Express에, 또는 앱에 사용되는 다른 모듈에 영향을 미칠 수 있는 [Node Security Project](https://npmjs.com/advisories)의 보안 권고문에 항상 주의를 기울이십시오. 일반적으로 Node Security Project는 Node의 보안과 관련된 지식 및 도구에 대한 훌륭한 자원입니다. +마지막으로, 다른 모든 웹 앱과 마찬가지로 Express 앱은 다양한 웹 기반 공격에 취약할 수 있습니다. 알려져 있는 [웹 취약성](https://www.owasp.org/www-project-top-ten/)을 숙지한 후 이러한 취약성을 피하기 위한 예방 조치를 취하십시오. -마지막으로, 다른 모든 웹 앱과 마찬가지로 Express 앱은 다양한 웹 기반 공격에 취약할 수 있습니다. 알려져 있는 [웹 취약성](https://www.owasp.org/index.php/Top_10_2013-Top_10)을 숙지한 후 이러한 취약성을 피하기 위한 예방 조치를 취하십시오. - - ## 추가적인 고려사항 유용한 [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/)에서 발췌한 몇 가지 추가적인 권장사항은 다음과 같습니다. 아래의 권장사항에 대한 모든 상세 정보를 확인하려면 해당 블로그 게시물을 참조하십시오. -* [csurf](https://www.npmjs.com/package/csurf) 미들웨어를 이용하여 교차 사이트 요청 위조(CSRF)로부터 보호하십시오. -* 항상 사용자 입력을 필터링하고 사용자 입력에서 민감한 데이터를 제거하여 XSS(Cross-site scripting) 및 명령 인젝션 공격으로부터 보호하십시오. -* 매개변수화된 조회 또는 준비된 명령문을 이용하여 SQL 인젝션 공격으로부터 방어하십시오. -* 오픈 소스 방식의 [sqlmap](http://sqlmap.org/) 도구를 이용하여 앱 내의 SQL 인젝션 취약성을 발견하십시오. -* [nmap](https://nmap.org/) 및 [sslyze](https://github.com/nabla-c0d3/sslyze) 도구를 이용하여 SSL 암호, 키 및 재협상의 구성, 그리고 인증서의 유효성을 테스트하십시오. -* [safe-regex](https://www.npmjs.com/package/safe-regex)를 이용하여 정규식이 [정규식 서비스 거부](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) 공격을 쉽게 받지 않도록 하십시오. +- 항상 사용자 입력을 필터링하고 사용자 입력에서 민감한 데이터를 제거하여 XSS(Cross-site scripting) 및 명령 인젝션 공격으로부터 보호하십시오. +- 매개변수화된 조회 또는 준비된 명령문을 이용하여 SQL 인젝션 공격으로부터 방어하십시오. +- 오픈 소스 방식의 [sqlmap](http://sqlmap.org/) 도구를 이용하여 앱 내의 SQL 인젝션 취약성을 발견하십시오. +- [nmap](https://nmap.org/) 및 [sslyze](https://github.com/nabla-c0d3/sslyze) 도구를 이용하여 SSL 암호, 키 및 재협상의 구성, 그리고 인증서의 유효성을 테스트하십시오. +- [safe-regex](https://www.npmjs.com/package/safe-regex)를 이용하여 정규식이 [정규식 서비스 거부](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) 공격을 쉽게 받지 않도록 하십시오. + +[helmet]: https://helmetjs.github.io/ \ No newline at end of file diff --git a/ko/advanced/developing-template-engines.md b/ko/advanced/developing-template-engines.md old mode 100755 new mode 100644 index b8c1f6d14f..6926558ac1 --- a/ko/advanced/developing-template-engines.md +++ b/ko/advanced/developing-template-engines.md @@ -1,8 +1,9 @@ --- layout: page title: Express용 템플릿 엔진 개발 +description: App.engine()을 사용하여 Express.js에서 사용자 정의 템플릿 엔진을 개발하는 방법을 학습합니다. 직접 템플릿 렌더링 로직을 생성하고 통합하는 예제를 함께 제공합니다. menu: advanced -lang: ko +redirect_from: " " --- # Express용 템플릿 엔진 개발 @@ -12,13 +13,14 @@ lang: ko 다음의 코드는 `.ntl` 파일을 렌더링하기 위한 매우 간단한 템플릿 엔진을 구현하는 예입니다. ```js -var fs = require('fs') // this engine requires the fs module -app.engine('ntl', function (filePath, options, callback) { // define the template engine - fs.readFile(filePath, function (err, content) { +const fs = require('fs') // this engine requires the fs module +app.engine('ntl', (filePath, options, callback) => { // define the template engine + fs.readFile(filePath, (err, content) => { if (err) return callback(err) // this is an extremely simple template engine - var rendered = content.toString().replace('#title#', '' + options.title + '') - .replace('#message#', '

    ' + options.message + '

    ') + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

    ${options.message}

    `) return callback(null, rendered) }) }) @@ -28,15 +30,17 @@ app.set('view engine', 'ntl') // register the template engine 앱은 이제 `.ntl` 파일을 렌더링할 수 있습니다. 다음의 내용이 입력된 `index.ntl`이라는 이름의 파일을 `views` 디렉토리에 작성하십시오. -```text +```pug #title# #message# ``` + 이후 앱에 다음과 같은 라우트를 작성하십시오. ```js -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index', { title: 'Hey', message: 'Hello there!' }) }) ``` -홈 페이지에 대한 요청을 실행할 때 `index.ntl`은 HTML로 렌더링됩니다. + +홈 페이지에 대한 요청을 실행할 때 `index.ntl`은 HTML로 렌더링됩니다. \ No newline at end of file diff --git a/ko/advanced/healthcheck-graceful-shutdown.md b/ko/advanced/healthcheck-graceful-shutdown.md index 6167f6e7d9..b57db7d289 100644 --- a/ko/advanced/healthcheck-graceful-shutdown.md +++ b/ko/advanced/healthcheck-graceful-shutdown.md @@ -1,108 +1,34 @@ --- layout: page title: 상태 검사와 우아한 종료 +description: Express 애플리케이션에서 헬스 체크와 그레이스풀 셧다운(Graceful Shutdown)을 구현하는 방법을 학습합니다. 이 기능은 애플리케이션의 신뢰성을 향상시키고, 배포를 원활하게 관리하며, Kubernetes와 같은 로드 밸런서와의 통합을 지원합니다. menu: advanced -lang: ko +redirect_from: " " --- -# 상태 확인와 정상 종료 +# 상태 검사와 우아한 종료 ## 정상 종료 -애플리케이션의 새 버전을 배포할 때, 이전 버전을 교체해야 합니다. 여러분이 사용하는 [프로세스 매니저](pm.html)는 애플리케어션에 SIGTERM 신호를 보내 종료를 통보할 것입니다. 애플리케이션이 신호를 받으면, 신규 요청을 받는걸 중단하고, 진행중인 요청을 끝내고, DB 연결이나 파일 사용을 포함한 사용한 리소스를 정리할 것입니다. +애플리케이션의 새 버전을 배포할 때, 이전 버전을 교체해야 합니다. 여러분이 사용하는 프로세스 매니저 는 애플리케어션에 SIGTERM 신호를 보내 종료를 통보할 것입니다. 애플리케이션이 신호를 받으면, 신규 요청을 받는걸 중단하고, 진행중인 요청을 끝내고, DB 연결이나 파일 사용을 포함한 사용한 리소스를 정리할 것입니다. -## 상태 확인 - -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-probes/): -로드 밸런서는 상태 확인을 애플리케이션이 장상 작동하고 요청을 받을 수 있는지 판단하는데 사용합니다. 예시로, [Kubernetes는 2개의 상태 확인을 가지고 있습니다.](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) - -* `liveness`: 언제 컨테이너를 재시작할지 결정합니다. -* `readiness`: 컨테이너가 트래픽을 받기 시작할 준비가 되었는지 결정합니다. 컨테이너가 준비되지 않았다면, 서비스 로드 밸런서들에게서 제거됩니다. - -## 서드 파티 솔루션 - -{% include community-caveat.html %} - -### Terminus - -[Terminus](https://github.com/godaddy/terminus)는 상용구 코드를 쓸 필요를 제거하기 위해 상태 확인 절차와 정상 종료를 추가하는 오픈소스 프로젝트입니다. 먼저 정상 종료를 위한 자원 청소 로직과 상태 확인 로직만 제공하면 됩니다. 그러면 Terminus가 나머지를 처리할겁니다. - -아래 명령을 사용해 Terminus를 설치합니다. - -```sh -npm i @godaddy/terminus --save -``` - -다음은 Terminus를 사용하는 쉬운 예제입니다. 자세한 정보는 를 참고하세요. +### Example ```js -const http = require('http') -const express = require('express') -const terminus = require('@godaddy/terminus') - -const app = express() - -app.get('/', (req, res) => { - res.send('ok') -}) - -const server = http.createServer(app) - -function onSignal () { - console.log('server is starting cleanup') - // start cleanup of resource, like databases or file descriptors -} - -async function onHealthCheck () { - // checks if the system is healthy, like the db connection is live - // resolves, if health, rejects if not -} +const server = app.listen(port) -terminus(server, { - signal: 'SIGINT', - healthChecks: { - '/healthcheck': onHealthCheck - }, - onSignal +process.on('SIGTERM', () => { + debug('SIGTERM signal received: closing HTTP server') + server.close(() => { + debug('HTTP server closed') + }) }) - -server.listen(3000) -``` - -### Lightship - -[Lightship](https://github.com/gajus/lightship)은 애플리케이션에 상태, 준비, 생존 확인을 추가하는 오픈소스 프로젝트입니다. Lightship은 스탠드얼론 HTTP 서비스로 분리된 HTTP 서비스를 구동합니다. 이를 통해 확인 절차들을 공개적으로 노출시키지 않고 할 수 있게 해줍니다. - -아래 명령을 사용해 Lightship을 설치합니다. - -```sh -npm install lightship - ``` -Lightship을 사용하는 쉬운 예제입니다. - -```js -const http = require('http') -const express = require('express') -const { - createLightship -} = require('lightship') - -// Lightship will start a HTTP service on port 9000. -const lightship = createLightship() - -const app = express() - -app.get('/', (req, res) => { - res.send('ok') -}) - -app.listen(3000, () => { - lightship.signalReady() -}) +## Health checks -// You can signal that the service is not ready using `lightship.signalNotReady()`. -``` +로드 밸런서는 헬스 체크를 통해 애플리케이션 인스턴스가 정상적으로 작동 중이며 요청을 수락할 수 있는지 판단합니다. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/): +로드 밸런서는 상태 확인을 애플리케이션이 장상 작동하고 요청을 받을 수 있는지 판단하는데 사용합니다. -[Lightship 문서](https://github.com/gajus/lightship)에서 [Kubernetes 설정](https://github.com/gajus/lightship#lightship-usage-kubernetes-container-probe-configuration)에 대한 예시와 [Express.js](https://github.com/gajus/lightship#using-with-expressjs)와의 통합 절차에 대한 완전한 예시를 제공합니다. +- `liveness`: 언제 컨테이너를 재시작할지 결정합니다. +- `readiness`: 컨테이너가 트래픽을 받기 시작할 준비가 되었는지 결정합니다. 컨테이너가 준비되지 않았다면, 서비스 로드 밸런서들에게서 제거됩니다. \ No newline at end of file diff --git a/ko/advanced/pm.md b/ko/advanced/pm.md deleted file mode 100755 index eb6808e934..0000000000 --- a/ko/advanced/pm.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -layout: page -title: Express 앱용 프로세스 관리자 -menu: advanced -lang: ko ---- - -# Express 앱용 프로세스 관리자 - -{% include community-caveat.html %} - -프로덕션 환경을 위한 Express를 실행할 때 *프로세스 관리자*를 사용하면 다음과 같은 태스크를 달성하는 데 도움이 됩니다. - -- 앱에서 충돌이 발생할 경우 앱을 자동으로 다시 시작. -- 런타임 성능 및 자원 소비에 대한 통찰력을 획득. -- 성능 향상을 위해 설정을 동적으로 수정. -- 클러스터링을 제어. - -프로세스 관리자는 애플리케이션 서버와 약간 비슷합니다. 프로세스 관리자는 애플리케이션을 위한 "컨테이너"이며, 배치 작업을 용이하게 하고, -높은 가용성을 제공하고, 런타임 시에 애플리케이션을 관리할 수 있도록 합니다. - -가장 널리 사용되는 Express 및 기타 Node.js 애플리케이션용 프로세스 관리자는 다음과 같습니다. - - -- **[Forever](https://github.com/foreverjs/forever){: target="_blank"}**: 주어진 스크립트가 지속적으로(영원히) 실행되도록 하는 간단한 명령행 인터페이스 도구입니다. Forever는 간단한 인터페이스를 갖추고 있으므로 소규모 배치의 Node.js 앱 및 스크립트를 실행하는 데 가장 적합합니다. -- **[PM2](https://github.com/Unitech/pm2){: target="_blank"}**: Node.js 애플리케이션용 프로덕션 프로세스 관리자이며, 여기에는 기본 제공 로드 밸런서가 포함되어 있습니다. PM2를 이용하면 앱을 항상 작동 상태로 유지하고, 시스템 가동 중단 없이 앱을 다시 로드할 수 있으며, 일반적인 시스템 관리 태스크를 쉽게 처리할 수 있습니다. 또한 PM2를 이용하면 애플리케이션 로깅, 모니터링 및 클러스터링을 관리할 수 있습니다. -- **[StrongLoop Process Manager (Strong-PM)](http://strong-pm.io/)**: Node.js 애플리케이션용 프로덕션 프로세스 관리자입니다. 기본 제공 로드 밸런싱, 모니터링, 멀티호스트 배치 및 그래픽 콘솔을 제공합니다. 로컬이나 리모트 시스템에 Node.js 애플리케이션을 빌드, 패키징, 배포하기 위한 CLI를 포함하고 있습니다. -- **SystemD**: 모던 리눅스 배포판의 기본 프로세스 매니저입니다. Node.js 애플리케이션을 서비스로 돌리기 간단하게 만들어 줍니다. 추가 정보는 다음을 참고하세요. ["Run node.js service with systemd" by Ralph Slooten (@axllent)](https://www.axllent.org/docs/view/nodejs-service-with-systemd/) diff --git a/ko/advanced/security-updates.md b/ko/advanced/security-updates.md old mode 100755 new mode 100644 index 28d6659314..27d5094aa5 --- a/ko/advanced/security-updates.md +++ b/ko/advanced/security-updates.md @@ -1,55 +1,87 @@ --- layout: page title: Express 보안 업데이트 +description: |- + Express.js의 최신 보안 업데이트와 패치 사항을 확인합니다. + 각 버전에 대한 상세한 취약점 목록을 포함하여, 애플리케이션의 보안을 유지하는 데 도움이 됩니다. menu: advanced -lang: ko +redirect_from: " " --- # 보안 업데이트
    -Node.js 취약성은 Express에 직접 영향을 미칩니다. 따라서 [Node.js 취약성을 항상 주시해야 하며](http://blog.nodejs.org/vulnerability/), 반드시 안정적인 최신 버전의 Node.js를 사용해야 합니다. +Node.js 취약성은 Express에 직접 영향을 미칩니다. 따라서 [Node.js 취약성을 항상 주시해야 하며](https://nodejs.org +/en/blog/vulnerability/), 반드시 안정적인 최신 버전의 Node.js를 사용해야 합니다.
    아래의 목록에는 지정된 버전 업데이트에서 수정된 Express 취약성이 열거되어 있습니다. +{% capture security-policy %} Express에서 보안 취약점을 발견했다고 생각되면, [보안 정책 및 절차](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures)를 참고해 주시기 바랍니다. +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} + ## 4.x - * 4.16.0 - * 의존성 `forwarded`가 [발견된 취약점](https://npmjs.com/advisories/527)에 따라 업데이트되었습니다. `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`을 사용하는 애플리케이션에 영향을 끼칠 수 있습니다. - * 의존성 `mime`이 [발견된 취약점](https://npmjs.com/advisories/535)에 따라 업데이트되었으나, 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 - * 의존성 `debug`가 [발견된 취약점](https://snyk.io/vuln/npm:debug:20170905)에 따라 업데이트되었으나, Express에 영향을 끼치지는 않습니다. - * 의존성 `fresh`가 [발견된 취약점](https://npmjs.com/advisories/526)에 따라 업데이트되었습니다. `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`를 사용하고 있는 애플리케이션에 영향을 끼칩니다. - * 4.15.3 - * 의존성 `ms`가 [발견된 취약점](https://snyk.io/vuln/npm:ms:20170412)에 따라 업데이트되었습니다. 애플리케이션이 `express.static`, `res.sendfile`, `res.sendFile`의 `maxAge` 옵션에 Untrusted 문자열을 입력받고 있으면 영향을 끼칠 수 있습니다. - * 4.15.2 - * 의존성 `qs`가 [발견된 취약점](https://snyk.io/vuln/npm:qs:20170213)에 따라 업데이트되었으나, Express에 영향을 끼치지는 않습니다. 4.15.2로 업데이트하는 것을 권장하나, 취약점을 막는 업데이트는 아닙니다.. - * 4.11.1 - * `express.static`, `res.sendfile` 및 `res.sendFile`의 루트 경로 노출 취약성을 수정했습니다. - * 4.10.7 - * `express.static`의 개방된 경로 재지정 취약성을 수정했습니다([보안 권고문](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 4.8.8 - * `express.static`의 디렉토리 조회 취약성을 수정했습니다([보안 권고문](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` 오류와 서버 무응답을 초래할 수 있습니다. - * 4.8.0 - * 조회 문자열에서 극단적으로 높은 인덱스를 갖는 스파스 배열은 프로세스가 메모리 부족을 발생시키고 서버에서 충돌이 발생하도록 하는 원인이 될 수 있습니다. - * 극단적인 수준으로 중첩된 조회 문자열 오브젝트는 프로세스가 서버를 차단하고 일시적으로 서버를 무응답 상태로 만드는 원인이 될 수 있습니다. +- 4.21.2 + - `path-to-regexp` 모듈이 [보안 취약점](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w)을 해결하기 위해 업데이트되었습니다. +- 4.21.1 + - `cookie` 모듈이 [보안 취약점](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x)을 해결하기 위해 업데이트되었습니다. 이 취약점은 `res.cookie`를 사용하는 애플리케이션에 영향을 줄 수 있습니다. +- 4.20.0 + - `res.redirect`에서 발생할 수 있는 XSS 취약점이 수정되었습니다 ([권고문](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - `serve-static` 모듈이 [보안 취약점](https://github.com/advisories/GHSA-cm22-4g7w-348p)을 해결하기 위해 업데이트되었습니다. + - `send` 모듈이 [보안 취약점](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg)을 해결하기 위해 업데이트되었습니다. + - `path-to-regexp` 모듈이 [보안 취약점](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j)을 해결하기 위해 추가로 업데이트되었습니다. + - `body-parser` 모듈이 [보안 취약점](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7)을 해결하기 위해 업데이트되었습니다 이 취약점은 URL 인코딩이 활성화된 경우 애플리케이션에 영향을 줄 수 있습니다. +- 4.19.0, 4.19.1 + - `res.location` 및 `res.redirect`에서 발생할 수 있는 오픈 리디렉션(Open Redirect) 취약점이 수정되었습니다 ([권고문](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)을 해결하기 위해 업데이트되었습니다. 이 취약점은 `req.query`, `req.body`, `req.param` API 사용 시 애플리케이션에 영향을 줄 수 있습니다. +- 4.16.0 + - 의존성 `forwarded`가 [발견된 취약점](https://npmjs.com/advisories/527)에 따라 업데이트되었습니다. `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`을 사용하는 애플리케이션에 영향을 끼칠 수 있습니다. + - 의존성 `mime`이 [발견된 취약점](https://npmjs.com/advisories/535)에 따라 업데이트되었으나, 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 + - 의존성 `debug`가 [발견된 취약점](https://snyk.io/vuln/npm:debug:20170905)에 따라 업데이트되었으나, Express에 영향을 끼치지는 않습니다. + - 의존성 `fresh`가 [발견된 취약점](https://npmjs.com/advisories/526)에 따라 업데이트되었습니다. `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`를 사용하고 있는 애플리케이션에 영향을 끼칩니다. +- 4.15.3 + - 의존성 `ms`가 [발견된 취약점](https://snyk.io/vuln/npm:ms:20170412)에 따라 업데이트되었습니다. 애플리케이션이 `express.static`, `res.sendfile`, `res.sendFile`의 `maxAge` 옵션에 Untrusted 문자열을 입력받고 있으면 영향을 끼칠 수 있습니다. +- 4.15.2 + - 의존성 `qs`가 [발견된 취약점](https://snyk.io/vuln/npm:qs:20170213)에 따라 업데이트되었으나, Express에 영향을 끼치지는 않습니다. 4.15.2로 업데이트하는 것을 권장하나, 취약점을 막는 업데이트는 아닙니다.. +- 4.11.1 + - `express.static`, `res.sendfile` 및 `res.sendFile`의 루트 경로 노출 취약성을 수정했습니다. +- 4.10.7 + - `express.static`의 개방된 경로 재지정 취약성을 수정했습니다([보안 권고문](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 4.8.8 + - `express.static`의 디렉토리 조회 취약성을 수정했습니다([보안 권고문](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` 오류와 서버 무응답을 초래할 수 있습니다. +- 4.8.0 + - 조회 문자열에서 극단적으로 높은 인덱스를 갖는 스파스 배열은 프로세스가 메모리 부족을 발생시키고 서버에서 충돌이 발생하도록 하는 원인이 될 수 있습니다. + - 극단적인 수준으로 중첩된 조회 문자열 오브젝트는 프로세스가 서버를 차단하고 일시적으로 서버를 무응답 상태로 만드는 원인이 될 수 있습니다. ## 3.x - * 3.19.1 - * `express.static`, `res.sendfile` 및 `res.sendFile`의 루트 경로 노출 취약성을 수정했습니다. - * 3.19.0 - * `express.static`의 개방된 경로 재지정 취약성을 수정했습니다([보안 권고문](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * `express.static`의 디렉토리 조회 취약성을 수정했습니다. - * 3.16.6 - * Node.js 0.10 이용 시, 특정한 상황에서 `fd` 누수가 발생할 수 있으며, 이는 `express.static` 및 `res.sendfile`에 영향을 미칩니다. 악성 요청은 `fd` 누수를 발생시킬 수 있으며, 결국 `EMFILE` 오류와 서버 무응답을 초래할 수 있습니다. - * 3.16.0 - * 조회 문자열에서 극단적으로 높은 인덱스를 갖는 스파스 배열은 프로세스가 메모리 부족을 발생시키고 서버에서 충돌이 발생하도록 하는 원인이 될 수 있습니다. - * 극단적인 수준으로 중첩된 조회 문자열 오브젝트는 프로세스가 서버를 차단하고 일시적으로 서버를 무응답 상태로 만드는 원인이 될 수 있습니다. - * 3.3.0 - * 지원되지 않는 메소드 대체 시도의 404 응답은 XSS(Cross-site scripting) 공격을 받기 쉬웠습니다. +
    + **Express 3.x은 더 이상 유지보수되지 않습니다.** + +3.x의 알려진 또는 알려지지 않은 보안 및 성능 문제는 마지막 업데이트(2015년 8월 1일) 이후로 처리되지 않고 있습니다. 최신 버전의 Express를 사용할 것을 강력히 권장합니다. + +버전 3.x 이상으로 업그레이드할 수 없는 경우, [상업적 지원 옵션](/{{ page.lang }}/support#commercial-support-options)을 고려해주시기 바랍니다. + +
    + +- 3.19.1 + - `express.static`, `res.sendfile` 및 `res.sendFile`의 루트 경로 노출 취약성을 수정했습니다. +- 3.19.0 + - `express.static`의 개방된 경로 재지정 취약성을 수정했습니다([보안 권고문](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 3.16.10 + - `express.static`의 디렉토리 조회 취약성을 수정했습니다. +- 3.16.6 + - Node.js 0.10 이용 시, 특정한 상황에서 `fd` 누수가 발생할 수 있으며, 이는 `express.static` 및 `res.sendfile`에 영향을 미칩니다. 악성 요청은 `fd` 누수를 발생시킬 수 있으며, 결국 `EMFILE` 오류와 서버 무응답을 초래할 수 있습니다. +- 3.16.0 + - 조회 문자열에서 극단적으로 높은 인덱스를 갖는 스파스 배열은 프로세스가 메모리 부족을 발생시키고 서버에서 충돌이 발생하도록 하는 원인이 될 수 있습니다. + - 극단적인 수준으로 중첩된 조회 문자열 오브젝트는 프로세스가 서버를 차단하고 일시적으로 서버를 무응답 상태로 만드는 원인이 될 수 있습니다. +- 3.3.0 + - 지원되지 않는 메소드 대체 시도의 404 응답은 XSS(Cross-site scripting) 공격을 받기 쉬웠습니다. \ No newline at end of file diff --git a/ko/api.md b/ko/api.md old mode 100755 new mode 100644 index be1481584e..3636ec88d4 --- a/ko/api.md +++ b/ko/api.md @@ -1,16 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - API 참조 -lang: ko +layout: api +version: 5x +title: Express 5.x - API 참조 +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api +redirect_from: " " --- -
    - -

    4.x API

    - - {% include api/en/4x/express.md %} - {% include api/en/4x/app.md %} - {% include api/en/4x/req.md %} - {% include api/en/4x/res.md %} - {% include api/en/4x/router.md %} +
    +

    5.x API

    + {% include api/en/5x/express.md %} + + {% include api/en/5x/app.md %} + + {% include api/en/5x/req.md %} + + {% include api/en/5x/res.md %} + + {% include api/en/5x/router.md %}
    diff --git a/ko/changelog/4x.md b/ko/changelog/4x.md index beefe10a6a..3704618c53 100644 --- a/ko/changelog/4x.md +++ b/ko/changelog/4x.md @@ -2,7 +2,9 @@ layout: page title: Express 4.x 업데이트 기록 menu: changelog -lang: ko +description: Stay updated with the release change log for Express.js 4.x, detailing + new features, bug fixes, and important changes across versions. +sitemap: false --- # 업데이트 기록 diff --git a/ko/changelog/index.md b/ko/changelog/index.md new file mode 100644 index 0000000000..5718e8cc7d --- /dev/null +++ b/ko/changelog/index.md @@ -0,0 +1,630 @@ +--- +layout: page +title: Express changelog +description: Express.js의 릴리스 변경 로그를 통해 새로운 기능, 버그 수정 사항, 그리고 각 버전별 주요 변경 사항을 최신 상태로 확인하세요. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - 릴리즈 날짜: 2025-03-31 + +{: id="5.0.1"} + +5.1.0 마이너 릴리즈에는 다음과 같은 새로운 기능과 개선 사항이 포함되어 있습니다: + +- 응답을 `Uint8Array` 형식으로 전송하는 기능 지원 +- `res.sendFile()`에서 ETag 옵션 지원 추가 +- `res.links()`에서 동일한 `rel` 값을 갖는 여러 링크 추가 지원 +- 성능 향상: `acceptParams`에 루프 사용 +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Brotli 및 `AsyncLocalStorage`에 대한 레거시 Node.js 지원 검사 제거 + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - 릴리즈 날짜: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - 릴리즈 날짜: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - 릴리즈 날짜: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - 릴리즈 날짜: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - 릴리즈 날짜: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`을 사용하는 애플리케이션에 영향을 끼칠 수 있습니다. +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`를 사용하고 있는 애플리케이션에 영향을 끼칩니다. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). 애플리케이션이 `express.static`, `res.sendfile`, `res.sendFile`의 `maxAge` 옵션에 Untrusted 문자열을 입력받고 있으면 영향을 끼칠 수 있습니다. +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/ko/guide/behind-proxies.md b/ko/guide/behind-proxies.md old mode 100755 new mode 100644 index 5aa530d685..baa77d017b --- a/ko/guide/behind-proxies.md +++ b/ko/guide/behind-proxies.md @@ -1,18 +1,21 @@ --- layout: page title: 프록시 환경에서 Express 사용 +description: Express.js 애플리케이션을 리버스 프록시 뒤에서 올바르게 작동하도록 설정하는 방법을 알아보십시오. 클라이언트 IP 주소를 처리하기 위해 `trust proxy` 설정을 사용하는 것을 포함합니다. menu: guide -lang: ko +redirect_from: " " --- # 프록시 환경에서 Express 사용 -프록시 뒤에서 Express 앱을 실행할 때는, ([app.set()](/{{ page.lang }}/4x/api.html#app.set)을 이용하여) 애플리케이션 변수 `trust proxy`를 다음 표에 나열된 값 중 하나로 설정하십시오. +Express 앱이 리버스 프록시 뒤에서 실행될 때, 일부 Express API는 예상과 다른 값을 반환할 수 있습니다. 이를 조정하기 위해 `trust proxy` 애플리케이션 설정을 사용하여, Express API에서 리버스 프록시가 제공한 정보를 노출하도록 할 수 있습니다. 가장 흔한 문제는 클라이언트의 IP 주소를 반환하는 Express API가 리버스 프록시의 내부 IP 주소를 대신 보여주는 경우입니다.
    -애플리케이션 변수 `trust proxy`가 설정되지 않아도 앱은 실행되지만, `trust proxy`가 구성되지 않으면 프록시의 IP 주소가 클라이언트 IP 주소로 잘못 등록됩니다. +`trust proxy` 설정을 구성할 때, 리버스 프록시의 정확한 구성 방식을 이해하는 것이 중요합니다. 이 설정은 요청에 포함된 값을 신뢰하게 만들기 때문에, Express의 설정이 리버스 프록시의 동작 방식과 일치해야 합니다.
    +프록시 뒤에서 Express 앱을 실행할 때는, ([app.set()](/{{ page.lang }}/4x/api.html#app.set)을 이용하여) 애플리케이션 변수 `trust proxy`를 다음 표에 나열된 값 중 하나로 설정하십시오. + @@ -22,51 +25,59 @@ lang: ko `true`인 경우, 클라이언트의 IP 주소는 `X-Forwarded-*` 내의 가장 왼쪽 입력 항목인 것으로 인식됩니다. `false`인 경우, 앱이 직접 인터넷에 연결되는 것으로 인식되며 클라이언트의 IP 주소는 `req.connection.remoteAddress`로부터 도출됩니다. 이 설정이 기본 설정입니다. + +
    `trust proxy`를 `true`로 설정할 경우, 마지막으로 신뢰할 수 있는 리버스 프록시가 다음의 HTTP 헤더들을 제거하거나 덮어쓰는지 반드시 확인해야 합니다: `X-Forwarded-For`, `X-Forwarded-Host`, `X-Forwarded-Proto`. 그렇지 않으면 클라이언트가 임의의 값을 제공하는 것이 가능해질 수 있습니다.
    - + - +
    유형
    IP 주소IP addresses -신뢰할 IP 주소나 서브넷, 또는 IP 주소 및 서브넷의 배열입니다. 아래의 목록에는 사전에 구성된 서브넷 이름이 표시되어 있습니다. +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` +- loopback - `127.0.0.1/8`, `::1/128` +- linklocal - `169.254.0.0/16`, `fe80::/10` +- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` 다음의 방법 중 하나로 IP 주소를 설정할 수 있습니다. -
    -app.set('trust proxy', 'loopback') // specify a single subnet
    +```js
    +app.set('trust proxy', 'loopback') // specify a single subnet
     app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
     app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
    -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
    -
    +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` + +IP 주소 또는 서브넷이 지정되는 경우, 해당 IP 주소 또는 서브넷은 주소 결정 프로세스에서 제외되며, 신뢰할 수 있는 것으로 지정되지 않은 IP 주소 중 애플리케이션 서버에서 가장 가까운 IP 주소가 클라이언트의 IP 주소로 결정됩니다. 이 설정은 `req.socket.remoteAddress`가 신뢰된 주소인지 확인하는 방식으로 작동합니다. 신뢰된 경우, `X-Forwarded-For` 헤더에 있는 각 IP 주소를 오른쪽에서 왼쪽으로 검사하며, 처음으로 신뢰되지 않은 주소를 만날 때까지 확인합니다. -IP 주소 또는 서브넷이 지정되는 경우, 해당 IP 주소 또는 서브넷은 주소 결정 프로세스에서 제외되며, 신뢰할 수 있는 것으로 지정되지 않은 IP 주소 중 애플리케이션 서버에서 가장 가까운 IP 주소가 클라이언트의 IP 주소로 결정됩니다.
    숫자 -가장 앞의 프록시 서버로부터 `n`번 째 홉을 클라이언트로서 신뢰합니다. +Express 애플리케이션으로부터 최대 `n` 홉(hop) 떨어진 위치에 있는 주소를 사용하게 됩니다. + `req.socket.remoteAddress`는 첫 번째 홉이며, 그 외의 주소들은 `X-Forwarded-For` 헤더에서 오른쪽에서 왼쪽 방향으로 조회됩니다. `0` 값을 설정하면, 첫 번째로 신뢰되지 않은 주소는 `req.socket.remoteAddress`가 되며, 이는 리버스 프록시가 없는 상태를 의미합니다. + +
    이 설정을 사용할 때는 Express 애플리케이션까지 도달하는 경로가 하나 이상 존재하지 않도록, 즉 서로 다른 홉 수의 경로가 존재하지 않도록 주의해야 합니다. 그렇지 않으면 클라이언트가 설정된 홉 수보다 가까운 위치에서 접근할 수 있게 되어, 임의의 값을 제공하는 것이 가능해질 수 있습니다.
    함수Function -사용자 정의 신뢰 구현입니다. 이 방법을 올바르게 숙지하고 있는 경우에만 이 방법을 사용하십시오. -
    -app.set('trust proxy', function (ip) {
    -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
    -  else return false;
    -});
    -
    +Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
    -`trust proxy` 값을 `false` 이외의 값으로 설정하면 다음과 같은 세 가지의 중요한 변화가 발생합니다. +`trust proxy`를 활성화하면 다음과 같은 영향을 미칩니다:
    • [req.hostname](/{{ page.lang }}/api.html#req.hostname)의 값은 `X-Forwarded-Host` 헤더에 설정된 값으로부터 도출되며, 이 값은 클라이언트 또는 프록시에 의해 설정될 수 있습니다. diff --git a/ko/guide/database-integration.md b/ko/guide/database-integration.md old mode 100755 new mode 100644 index 464edf2be2..f7f488fd1b --- a/ko/guide/database-integration.md +++ b/ko/guide/database-integration.md @@ -1,355 +1,490 @@ --- layout: page title: Express 데이터베이스 통합 +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: ko +redirect_from: " " --- # 데이터베이스 통합 데이터베이스를 Express 앱에 연결하는 기능을 추가하려면 앱에 포함된 데이터베이스를 위한 적절한 Node.js 드라이버를 로드해야 합니다. 이 문서에서는 Express 앱의 데이터베이스 시스템에 가장 널리 이용되고 있는 Node.js 모듈 중 다음과 같은 몇 개의 모듈을 추가 및 사용하는 방법을 설명합니다. -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongo) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgres) +- [Redis](#redis) +- +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
      -위의 데이터베이스 드라이버는 사용 가능한 여러 데이터베이스 드라이버 중 일부입니다. 다른 옵션을 확인하려면, +위의 데이터베이스 드라이버는 사용 가능한 여러 데이터베이스 드라이버 중 일부입니다. 다른 옵션을 확인하려면, [npm](https://www.npmjs.com/) 사이트에서 검색하십시오.
      - - ## Cassandra **모듈**: [cassandra-driver](https://github.com/datastax/nodejs-driver) **설치** -
      -
      +### 설치
      +
      +```bash
       $ npm install cassandra-driver
      -
      -
      +``` + +### Example + +```js +const cassandra = require('cassandra-driver') +const client = new cassandra.Client({ contactPoints: ['localhost'] }) + +client.execute('select key from system.local', (err, result) => { + if (err) throw err + console.log(result.rows[0]) +}) +``` -**예제** +## Couchbase -
      -
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      +**모듈**: [couchnode](https://github.com/couchbase/couchnode)
       
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      -
      +### 설치 + +```bash +$ npm install couchbase +``` + +### Example + +```js +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') + +// add a document to a bucket +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) - +// get all documents with shoe size 13 +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) +``` ## CouchDB **모듈**: [nano](https://github.com/dscape/nano) **설치** -
      -
      +### 설치
      +
      +```bash
       $ npm install nano
      -
      -
      +``` -**예제** +### Example -
      -
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      +```js
      +const nano = require('nano')('http://localhost:5984')
      +nano.db.create('books')
      +const books = nano.db.use('books')
       
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      +// Insert a book document in the books database
      +books.insert({ name: 'The Art of war' }, null, (err, body) => {
      +  if (err) {
      +    console.log(err)
      +  } else {
      +    console.log(body)
         }
      -});
      +})
       
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      -
      - - +// Get a list of all books +books.list((err, body) => { + if (err) { + console.log(err) + } else { + console.log(body.rows) + } +}) +``` ## LevelDB **모듈**: [levelup](https://github.com/rvagg/node-levelup) **설치** -
      -
      -$ npm install level levelup leveldown
      -
      -
      +### 설치 -**예제** +```bash +$ npm install level levelup leveldown +``` -
      -
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      +### Example
       
      -db.put('name', 'LevelUP', function (err) {
      +```js
      +const levelup = require('levelup')
      +const db = levelup('./mydb')
       
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      +db.put('name', 'LevelUP', (err) => {
      +  if (err) return console.log('Ooops!', err)
       
      -});
      -
      -
      + db.get('name', (err, value) => { + if (err) return console.log('Ooops!', err) - + console.log(`name=${value}`) + }) +}) +``` ## MySQL **모듈**: [mysql](https://github.com/felixge/node-mysql/) **설치** -
      -
      +### 설치
      +
      +```bash
       $ npm install mysql
      -
      -
      +``` -**예제** +### Example -
      -
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      +```js
      +const mysql = require('mysql')
      +const connection = mysql.createConnection({
      +  host: 'localhost',
      +  user: 'dbuser',
      +  password: 's3kreee7',
      +  database: 'my_db'
      +})
       
      -connection.connect();
      +connection.connect()
       
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
      +  if (err) throw err
       
      -connection.end();
      -
      -
      + console.log('The solution is: ', rows[0].solution) +}) - +connection.end() +``` ## MongoDB **모듈**: [mongodb](https://github.com/mongodb/node-mongodb-native) **설치** -
      -
      +### 설치
      +
      +```bash
       $ npm install mongodb
      -
      -
      +``` -**예제** +### Example (v2.\*) -
      -
      -var MongoClient = require('mongodb').MongoClient;
      +```js
      +const MongoClient = require('mongodb').MongoClient
       
      -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
      -  if (err) {
      -    throw err;
      -  }
      -  db.collection('mammals').find().toArray(function(err, result) {
      -    if (err) {
      -      throw err;
      -    }
      -    console.log(result);
      -  });
      -});
      -
      -
      +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { + if (err) throw err -MongoDB용 오브젝트 모델 드라이버가 필요한 경우에는 [Mongoose](https://github.com/LearnBoost/mongoose)를 확인하십시오. + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +### Example (v3.\*) + +```js +const MongoClient = require('mongodb').MongoClient - +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { + if (err) throw err + + const db = client.db('animals') + + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +MongoDB용 오브젝트 모델 드라이버가 필요한 경우에는 [Mongoose](https://github.com/LearnBoost/mongoose)를 확인하십시오. ## Neo4j -**모듈**: [apoc](https://github.com/hacksparrow/apoc) -**설치** +**모듈**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver) + +### 설치 -
      -
      -$ npm install apoc
      -
      -
      +```bash +$ npm install neo4j-driver +``` -**예제** +### Example -
      -
      -var apoc = require('apoc');
      +```js
      +const neo4j = require('neo4j-driver')
      +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein'))
       
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      +const session = driver.session()
      +
      +session.readTransaction((tx) => {
      +  return tx.run('MATCH (n) RETURN count(n) AS count')
      +    .then((res) => {
      +      console.log(res.records[0].get('count'))
      +    })
      +    .catch((error) => {
      +      console.log(error)
      +    })
      +})
      +```
      +
      +## Oracle
      +
      +**모듈**: [oracledb](https://github.com/oracle/node-oracledb)
      +
      +### 설치
      +
      +참고: [설치 전제 조건 참조](https://github.com/oracle/node-oracledb#-installation).
      +
      +```bash
      +$ npm install oracledb
      +```
      +
      +### Example
      +
      +```js
      +const oracledb = require('oracledb')
      +const config = {
      +  user: '',
      +  password: '',
      +  connectString: 'localhost:1521/orcl'
      +}
      +
      +async function getEmployee (empId) {
      +  let conn
      +
      +  try {
      +    conn = await oracledb.getConnection(config)
      +
      +    const result = await conn.execute(
      +      'select * from employees where employee_id = :id',
      +      [empId]
      +    )
      +
      +    console.log(result.rows[0])
      +  } catch (err) {
      +    console.log('Ouch!', err)
      +  } finally {
      +    if (conn) { // conn assignment worked, need to close
      +      await conn.close()
      +    }
         }
      -);
      -
      -
      +} - +getEmployee(101) +``` ## PostgreSQL **모듈**: [pg-promise](https://github.com/vitaly-t/pg-promise) **설치** -
      -
      +### 설치
      +
      +```bash
       $ npm install pg-promise
      -
      -
      +``` -**예제** +### Example -
      -
      -var pgp = require("pg-promise")(/*options*/);
      -var db = pgp("postgres://username:password@host:port/database");
      +```js
      +const pgp = require('pg-promise')(/* options */)
      +const db = pgp('postgres://username:password@host:port/database')
       
      -db.one("SELECT $1 AS value", 123)
      -    .then(function (data) {
      -        console.log("DATA:", data.value);
      -    })
      -    .catch(function (error) {
      -        console.log("ERROR:", error);
      -    });
      -
      -
      - - +db.one('SELECT $1 AS value', 123) + .then((data) => { + console.log('DATA:', data.value) + }) + .catch((error) => { + console.log('ERROR:', error) + }) +``` ## Redis **모듈**: [redis](https://github.com/mranney/node_redis) **설치** -
      -
      +### 설치
      +
      +```bash
       $ npm install redis
      -
      -
      +``` + +### Example + +```js +const redis = require('redis') +const client = redis.createClient() -**예제** +client.on('error', (err) => { + console.log(`Error ${err}`) +}) -
      -
      -var client = require('redis').createClient();
      +client.set('string key', 'string val', redis.print)
      +client.hset('hash key', 'hashtest 1', 'some value', redis.print)
      +client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
       
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      +client.hkeys('hash key', (err, replies) => {
      +  console.log(`${replies.length} replies:`)
       
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      +  replies.forEach((reply, i) => {
      +    console.log(`    ${i}: ${reply}`)
      +  })
       
      -client.hkeys('hash key', function (err, replies) {
      +  client.quit()
      +})
      +```
       
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      +## SQL 서버
       
      -  client.quit();
      +**모듈**: [tedious](https://github.com/tediousjs/tedious)
       
      -});
      -
      -
      +### 설치 - +```bash +$ npm install tedious +``` + +### Example + +```js +const Connection = require('tedious').Connection +const Request = require('tedious').Request + +const config = { + server: 'localhost', + authentication: { + type: 'default', + options: { + userName: 'your_username', // update me + password: 'your_password' // update me + } + } +} + +const connection = new Connection(config) + +connection.on('connect', (err) => { + if (err) { + console.log(err) + } else { + executeStatement() + } +}) + +function executeStatement () { + request = new Request("select 123, 'hello world'", (err, rowCount) => { + if (err) { + console.log(err) + } else { + console.log(`${rowCount} rows`) + } + connection.close() + }) + + request.on('row', (columns) => { + columns.forEach((column) => { + if (column.value === null) { + console.log('NULL') + } else { + console.log(column.value) + } + }) + }) + + connection.execSql(request) +} +``` ## SQLite **모듈**: [sqlite3](https://github.com/mapbox/node-sqlite3) **설치** -
      -
      -$ npm install sqlite3
      -
      -
      +### 설치 -**예제** +```bash +$ npm install sqlite3 +``` -
      -
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      +### Example
       
      -db.serialize(function() {
      +```js
      +const sqlite3 = require('sqlite3').verbose()
      +const db = new sqlite3.Database(':memory:')
       
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      +db.serialize(() => {
      +  db.run('CREATE TABLE lorem (info TEXT)')
      +  const stmt = db.prepare('INSERT INTO lorem VALUES (?)')
       
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      +  for (let i = 0; i < 10; i++) {
      +    stmt.run(`Ipsum ${i}`)
         }
       
      -  stmt.finalize();
      +  stmt.finalize()
       
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      +  db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
      +    console.log(`${row.id}: ${row.info}`)
      +  })
      +})
       
      -db.close();
      -
      -
      - - +db.close() +``` ## ElasticSearch **모듈**: [elasticsearch](https://github.com/elastic/elasticsearch-js) **설치** -
      -
      +### 설치
      +
      +```bash
       $ npm install elasticsearch
      -
      -
      +``` -**예제** +### Example -
      -
      -var elasticsearch = require('elasticsearch');
      -var client = elasticsearch.Client({
      +```js
      +const elasticsearch = require('elasticsearch')
      +const client = elasticsearch.Client({
         host: 'localhost:9200'
      -});
      +})
       
       client.search({
         index: 'books',
      @@ -362,10 +497,9 @@ client.search({
             }
           }
         }
      -}).then(function(response) {
      -  var hits = response.hits.hits;
      -}, function(error) {
      -  console.trace(error.message);
      -});
      -
      -
      +}).then((response) => { + const hits = response.hits.hits +}, (error) => { + console.trace(error.message) +}) +``` diff --git a/ko/guide/debugging.md b/ko/guide/debugging.md old mode 100755 new mode 100644 index f90543ea2b..81a5fee4d8 --- a/ko/guide/debugging.md +++ b/ko/guide/debugging.md @@ -1,42 +1,29 @@ --- layout: page title: Express 디버깅 +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: ko +redirect_from: " " --- # Express 디버깅 -Express는 내부적으로 [debug](https://www.npmjs.com/package/debug) 모듈을 -사용하여 라우트 일치, 사용 중인 미들웨어 함수, 애플리케이션 모드, 그리고 요청-응답 주기의 -플로우에 대한 정보를 로그합니다. - -
      -`debug`는 `console.log`의 보강된 버전과도 같지만, `console.log`와는 달리 -프로덕션 코드에서 `debug` 로그를 주석 처리할 필요가 없습니다. 로깅은 기본적으로 꺼져 있으며, `DEBUG` 환경 변수를 사용하여 조건부로 켤 수 있습니다. -
      - Express에서 사용되는 모든 내부 로그를 확인하려면, 앱을 실행할 때 `DEBUG` 환경 변수를 `express:*`로 설정하십시오. -
      -
      +```bash
       $ DEBUG=express:* node index.js
      -
      -
      +``` Windows에서는 다음과 같은 명령을 사용하십시오. -
      -
      -> set DEBUG=express:* & node index.js
      -
      -
      +```bash +> $env:DEBUG = "express:*"; node index.js +``` [Express 생성기](/{{ page.lang }}/starter/generator.html)가 생성한 기본 앱에 대해 이 명령을 실행하면 다음과 같이 인쇄됩니다. -
      -
      +```bash
       $ DEBUG=express:* node ./bin/www
         express:router:route new / +0ms
         express:router:layer new / +1ms
      @@ -72,19 +59,17 @@ $ DEBUG=express:* node ./bin/www
         express:router:layer new / +1ms
         express:router use /users router +0ms
         express:router:layer new /users +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -
      -
      +``` 이후 앱에 대한 요청이 이루어지면, Express 코드에 지정된 로그를 확인할 수 있습니다. -
      -
      +```bash
         express:router dispatching GET / +4h
         express:router query  : / +2ms
         express:router expressInit  : / +0ms
      @@ -100,8 +85,7 @@ $ DEBUG=express:* node ./bin/www
         express:view lookup "index.pug" +338ms
         express:view stat "/projects/example/views/index.pug" +0ms
         express:view render "/projects/example/views/index.pug" +1ms
      -
      -
      +``` 라우터 구현의 로그만 확인하려면 `DEBUG`의 값을 `express:router`로 설정하십시오. 마찬가지로, 애플리케이션 구현의 로그만 확인하려면 `DEBUG`의 값을 `express:application`으로 설정하십시오. 나머지도 이와 같습니다. @@ -111,18 +95,36 @@ $ DEBUG=express:* node ./bin/www 예를 들어 `$ express sample-app`을 통해 앱을 생성하는 경우에는 다음과 같은 명령을 통해 디버그 명령문을 사용할 수 있습니다. -
      -
      +```bash
       $ DEBUG=sample-app:* node ./bin/www
      -
      -
      +``` 다음과 같이 쉼표로 구분된 이름 목록을 지정하면 2개 이상의 디버그 네임스페이스를 지정할 수 있습니다. -
      -
      +```bash
       $ DEBUG=http,mail,express:* node index.js
      -
      -
      +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -`debug`에 대한 자세한 정보는 [debug](https://www.npmjs.com/package/debug)를 참조하십시오. +{% include admonitions/note.html content=debug-text %} diff --git a/ko/guide/error-handling.md b/ko/guide/error-handling.md old mode 100755 new mode 100644 index ebc3dce816..1af96b5f13 --- a/ko/guide/error-handling.md +++ b/ko/guide/error-handling.md @@ -1,124 +1,120 @@ --- layout: page title: Express 오류 처리 +description: Express.js가 동기 및 비동기 코드에서 오류를 처리하는 방식을 이해하고, 애플리케이션에 맞는 사용자 정의 오류 처리 미들웨어를 구현하는 방법을 알아보세요. menu: guide -lang: ko +redirect_from: " " --- # 오류 처리 -다른 미들웨어 함수와 동일한 방법으로 오류 처리 미들웨어 함수를 정의할 수 있지만, -오류 처리 함수는 3개가 아닌 4개의 인수, 즉 `(err, req, res, next)`를 -갖는다는 점이 다릅니다. 예를 들면 다음과 같습니다. +에러 처리란 Express가 동기 및 비동기적으로 발생하는 에러를 포착하고 처리하는 방식을 의미합니다. Express는 기본 에러 처리기를 제공하므로 시작하기 위해 직접 작성할 필요가 없습니다. -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      +## 에러 포착하기 -오류 처리 미들웨어는 다른 `app.use()` 및 라우트 호출을 정의한 후에 마지막으로 정의해야 하며, 예를 들면 다음과 같습니다. +Express가 라우트 핸들러와 미들웨어 실행 중 발생하는 모든 에러를 포착하는 것이 중요합니다. -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +라우트 핸들러 및 미들웨어 내부의 동기 코드에서 발생하는 에러는 추가 작업이 필요하지 않습니다. 동기 코드에서 에러가 발생하면 Express가 에러를 감지하여 처리합니다. 예를 들면 다음과 같습니다.
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      -  // logic
      -});
      -
      -
      +```js +app.get('/', (req, res) => { + throw new Error('BROKEN') // Express will catch this on its own. +}) +``` -미들웨어 함수 내부로부터의 응답은 HTML 오류 페이지, 단순한 메시지 또는 JSON 문자열 등 여러분이 선호하는 모든 형식일 수 있습니다. +여러 콜백 함수를 갖는 라우트 핸들러가 있는 경우에는 `route` 매개변수를 사용하여 그 다음의 라우트 핸들러로 건너뛸 수 있습니다. 예를 들면 다음과 같습니다. -조직적(및 상위 레벨 프레임워크) 목적을 위해, 여러 오류 처리 -미들웨어 함수를 정의할 수 있으며, 이는 일반적인 미들웨어 함수를 정의할 때와 -매우 비슷합니다. 예를 들어 `XHR`를 이용한 요청 및 -그렇지 않은 요청에 대한 오류 처리를 정의하려는 경우, 다음과 같은 명령을 사용할 수 있습니다. +```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) + } + }) +}) +``` -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +다른 미들웨어 함수와 동일한 방법으로 오류 처리 미들웨어 함수를 정의할 수 있지만,
      +오류 처리 함수는 3개가 아닌 4개의 인수, 즉 `(err, req, res, next)`를
      +갖는다는 점이 다릅니다.
      +예를 들면 다음과 같습니다.
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      -
      +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` -이 예에서 일반 `logErrors`는 요청 및 오류 정보를 `stderr`에 -기록할 수도 있으며, 예를 들면 다음과 같습니다. +`getUserById`에서 에러가 발생하거나 거부(reject)되면, `next`는 발생한 에러 또는 거부된 값을 사용하여 호출됩니다. 만약 거부된 값(rejected value)이 제공되지 않으면 `next`는 Express 라우터가 제공하는 기본 에러 객체와 함께 호출됩니다. -
      -
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      -
      +`next()` 함수로 어떠한 내용을 전달하는 경우(`'route'`라는 문자열 제외), Express는 현재의 요청에 오류가 있는 것으로 간주하며, 오류 처리와 관련되지 않은 나머지 라우팅 및 미들웨어 함수를 건너뜁니다. -또한 이 예에서 `clientErrorHandler`는 다음과 같이 정의되며, 이 경우 오류는 명시적으로 그 다음 항목으로 전달됩니다. +만약 연속적인 과정(sequence)에서 콜백이 데이터는 제공하지 않고 에러만 제공한다면 다음과 같이 코드를 간소화할 수 있습니다: -
      -
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      -  } else {
      -    next(err);
      +```js
      +app.get('/', [
      +  function (req, res, next) {
      +    fs.writeFile('/inaccessible-path', 'data', next)
      +  },
      +  function (req, res) {
      +    res.send('OK')
         }
      -}
      -
      -
      +]) +``` -"모든 오류를 처리하는(catch-all)" `errorHandler` 함수는 다음과 같이 구현될 수 있습니다. +위 예제에서, `next`는 `fs.writeFile`의 콜백으로 제공되며 이 콜백은 에러 발생 여부와 관계없이 호출됩니다. 에러가 없으면 두 번째 핸들러가 실행되고, 그렇지 않으면 Express에서 에러를 포착하여 처리합니다. -
      -
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      +라우트 핸들러나 미들웨어에서 호출하는 비동기 코드에서 발생하는 에러는 반드시 포착하여 Express에 전달하여 처리해야 합니다. 예를 들면 다음과 같습니다. -`next()` 함수로 어떠한 내용을 전달하는 경우(`'route'`라는 문자열 제외), Express는 현재의 요청에 오류가 있는 것으로 간주하며, 오류 처리와 관련되지 않은 나머지 라우팅 및 미들웨어 함수를 건너뜁니다. 이러한 오류를 어떻게든 처리하기 원하는 경우, 다음 섹션에 설명된 것과 같이 오류 처리 라우트를 작성해야 합니다. +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN') + } catch (err) { + next(err) + } + }, 100) +}) +``` -여러 콜백 함수를 갖는 라우트 핸들러가 있는 경우에는 `route` 매개변수를 사용하여 그 다음의 라우트 핸들러로 건너뛸 수 있습니다. 예를 들면 다음과 같습니다. +위 예제는 `try...catch` 블록을 사용하여 비동기 코드의 에러를 포착하여 Express에 전달합니다. 만약 `try...catch` 블록이 생략되면, Express는 해당 에러가 동기 핸들러 코드의 일부가 아니므로 에러를 포착하지 못할 것입니다. -
      -
      -app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      +프로미스를 사용하면 `try...catch` 블록의 오버헤드를 피하거나 프로미스를 반환하는 함수를 사용할 때 유용합니다. 예를 들면 다음과 같습니다.  예를 들면 다음과 같습니다.
       
      -      // continue handling this request
      -      next('route');
      -    }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      -
      +```js +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { + throw new Error('BROKEN') + }).catch(next) // Errors will be passed to Express. +}) +``` -이 예에서 `getPaidContent` 핸들러의 실행은 건너뛰지만, `/a_route_behind_paywall`에 대한 `app` 내의 나머지 핸들러는 계속하여 실행됩니다. +프로미스는 동기 에러와 거부된 프로미스를 모두 자동으로 포착하므로, `next`를 최종 catch 핸들러로 제공하기만 해도 Express가 에러를 포착합니다. 이는 catch 핸들러가 에러를 첫 번째 인자로 받기 때문입니다. -
      -`next()` 및 `next(err)`에 대한 호출은 현재의 핸들러가 완료되었다는 것과 해당 핸들러의 상태를 표시합니다. `next(err)`는 위에 설명된 것과 같이 오류를 처리하도록 설정된 핸들러를 제외한 체인 내의 나머지 모든 핸들러를 건너뜁니다. -
      +또한 비동기 코드를 최소화하여 동기 에러 감지에 의존하는 핸들러 체인을 사용할 수도 있습니다. 예를 들면 다음과 같습니다. + +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +위 예제에는 `readFile` 호출에서 몇 가지 간단한 내용을 포함합니다. 만약 `readFile`에서 에러가 발생한다면 Express로 해당 에러가 전달되고, 그렇지 않으면 체인의 다음 핸들러로 넘어가면서 동기적인 에러 처리 흐름으로 복귀하게 됩니다. 그런 다음 위 예제에서는 데이터 처리를 시도합니다. 만약 이 과정이 실패하면 동기 에러 핸들러가 에러를 포착합니다. 만약 이 처리를 `readFile` 콜백 내부에서 했다면 애플리케이션이 비정상 종료되어 Express 에러 핸들러가 실행되지 못할 수도 있습니다. + +어떤 방법을 사용하든, Express 에러 핸들러가 호출되고 애플리케이션이 정상적으로 작동하게 하려면 Express가 에러를 받도록 해야 합니다. ## 기본 오류 핸들러 @@ -132,6 +128,13 @@ Express는 내장된 오류 핸들러와 함께 제공되며, 내장 오류 핸 프로덕션 모드에서 앱을 실행하려면 환경 변수 `NODE_ENV`를 `production`으로 설정하십시오.
    +에러가 기록되면 다음 정보가 응답에 추가됩니다: + +- `res.statusCode`는 `err.status` 또는 `err.statusCode`값으로 설정됩니다. 이 값이 4xx 또는 5xx 범위를 벗어나면 500 으로 설정됩니다. +- `res.statusMessage`는 상태 코드에 따라 설정됩니다. +- body는 프로덕션 환경일 경우 상태 코드 메시지의 HTML이 되고, 그렇지 않은 경우 `err.stack`이 됩니다. +- `err.headers` 객체에 지정된 모든 헤더가 포함됩니다. + 응답의 기록을 시작한 후에 오류가 있는 `next()`를 호출하는 경우(예: 응답을 클라이언트로 스트리밍하는 중에 오류가 발생하는 경우), Express의 기본 오류 핸들러는 해당 연결을 닫고 @@ -140,16 +143,122 @@ Express는 내장된 오류 핸들러와 함께 제공되며, 내장 오류 핸 따라서 사용자 정의 오류 핸들러를 추가할 때, 헤더가 이미 클라이언트로 전송된 경우에는 다음과 같이 Express 내의 기본 오류 처리 메커니즘에 위임해야 합니다: -
    -
    -function errorHandler(err, req, res, next) {
    +```js
    +function errorHandler (err, req, res, next) {
       if (res.headersSent) {
    -    return next(err);
    +    return next(err)
       }
    -  res.status(500);
    -  res.render('error', { error: err });
    +  res.status(500)
    +  res.render('error', { error: err })
     }
    -
    -
    +``` 만약 `next()`를 여러분의 코드에서 여러 번 호출한다면, 사용자 정의 오류 핸들러가 있음에도 불구하고 기본 오류 핸들러가 발동될 수 있음에 주의하십시오. + +다른 에러 핸들링 미들웨어는 [Express middleware](/{{ page.lang }}/resources/middleware.html) 에서 확인할 수 있습니다. + +## 에러 핸들러 작성하기 + +에러 핸들링 미들웨어 함수는 다른 미들웨어 함수와 동일한 방식으로 정의합니다. 단, 에러 핸들링 함수는 세 개가 아닌 네 개의 인수(`err`, `req`, `res`, `next`)를 받는다는 점이 다릅니다. 예를 들면 다음과 같습니다. + +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` + +오류 처리 미들웨어는 다른 `app.use()` 및 라우트 호출을 정의한 후에 마지막으로 정의해야 하며, 예를 들면 다음과 같습니다. + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use((err, req, res, next) => { + // logic +}) +``` + +미들웨어 함수 내부로부터의 응답은 HTML 오류 페이지, 단순한 메시지 또는 JSON 문자열 등 여러분이 선호하는 모든 형식일 수 있습니다. + +조직적(및 상위 레벨 프레임워크) 목적을 위해, 여러 오류 처리 +미들웨어 함수를 정의할 수 있으며, 이는 일반적인 미들웨어 함수를 정의할 때와 +매우 비슷합니다. 예를 들어 `XHR`를 이용한 요청 및 +그렇지 않은 요청에 대한 오류 처리를 정의하려는 경우, 다음과 같은 명령을 사용할 수 있습니다. + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use(logErrors) +app.use(clientErrorHandler) +app.use(errorHandler) +``` + +이 예에서 일반 `logErrors`는 요청 및 오류 정보를 `stderr`에 +기록할 수도 있으며, 예를 들면 다음과 같습니다. + +```js +function logErrors (err, req, res, next) { + console.error(err.stack) + next(err) +} +``` + +또한 이 예에서 `clientErrorHandler`는 다음과 같이 정의되며, 이 경우 오류는 명시적으로 그 다음 항목으로 전달됩니다. + +에러 핸들링 함수에서 "next"를 호출하지 **않을** 경우, response를 작성하고 종료해야 합니다. 그렇지 않으면 해당 request는 "중단(hang)"되어 가비지 컬렉션 대상이 되지 않습니다. + +```js +function clientErrorHandler (err, req, res, next) { + if (req.xhr) { + res.status(500).send({ error: 'Something failed!' }) + } else { + next(err) + } +} +``` + +"모든 오류를 처리하는(catch-all)" `errorHandler` 함수는 다음과 같이 구현될 수 있습니다. + +```js +function errorHandler (err, req, res, next) { + res.status(500) + res.render('error', { error: err }) +} +``` + +만약 여러개의 콜백 함수가 있는 라우트 핸들러가 있다면 `route` 매개변수를 사용하여 다음 라우트 핸들러로 건너뛸 수 있습니다. 예를 들면 다음과 같습니다. + +```js +app.get('/a_route_behind_paywall', + (req, res, next) => { + if (!req.user.hasPaid) { + // continue handling this request + next('route') + } else { + next() + } + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` + +이 예에서 `getPaidContent` 핸들러의 실행은 건너뛰지만, `/a_route_behind_paywall`에 대한 `app` 내의 나머지 핸들러는 계속하여 실행됩니다. + +
    +`next()` 및 `next(err)`에 대한 호출은 현재의 핸들러가 완료되었다는 것과 해당 핸들러의 상태를 표시합니다. `next(err)`는 위에 설명된 것과 같이 오류를 처리하도록 설정된 핸들러를 제외한 체인 내의 나머지 모든 핸들러를 건너뜁니다. +
    diff --git a/ko/guide/migrating-4.md b/ko/guide/migrating-4.md old mode 100755 new mode 100644 index 146b7237c6..b95dd4a24b --- a/ko/guide/migrating-4.md +++ b/ko/guide/migrating-4.md @@ -1,8 +1,9 @@ --- layout: page title: Express 4로의 마이그레이션 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: ko +redirect_from: " " --- # Express 4로의 이전 @@ -24,7 +25,7 @@ Express 4는 Express 3로부터 근본적으로 변경되었습니다. 따라서 Express 4에서는 여러 중요한 부분이 변경되었습니다.
      -
    • Express 코어 및 미들웨어 시스템에 대한 변경. Connect 및 기본 제공 미들웨어에 대한 종속 항목이 제거되었으며, 따라서 사용자가 직접 미들웨어를 추가해야 합니다. +
    • Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
    • 라우팅 시스템에 대한 변경.
    • 기타 다양한 변경사항.
    • @@ -32,8 +33,8 @@ Express 4에서는 여러 중요한 부분이 변경되었습니다. 또한 다음을 참조하십시오. -* [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

      Express 코어 및 미들웨어 시스템에 대한 변경 @@ -54,7 +55,7 @@ Express 4는 더 이상 Connect에 종속되지 않으며, `express.static` 함 다음 표에는 Express 3의 미들웨어 및 그에 대응하는 Express 4의 미들웨어가 나열되어 있습니다. - + @@ -86,7 +87,7 @@ Express 4는 더 이상 Connect에 종속되지 않으며, `express.static` 함 -
      Express 3Express 4
      Express 3Express 4
      express.bodyParser body-parser + multer
      serve-index
      express.static serve-static
      + Express 4 미들웨어의 [전체 목록](https://github.com/senchalabs/connect#middleware)을 참조하십시오. @@ -99,14 +100,13 @@ Express 4 미들웨어의 [전체 목록](https://github.com/senchalabs/connect# 버전 4에서는 미들웨어 함수가 로드되는 경로를 정의하기 위하여 가변 매개변수를 사용할 수 있으며, 이후 라우트 핸들러로부터 매개변수의 값을 읽을 수 있습니다. 예를 들면 다음과 같습니다. -
      -
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -});
      -
      -
      +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` +

      라우팅 시스템

      @@ -119,8 +119,9 @@ app.use('/book/:id', function(req, res, next) { 라우팅 시스템에는 다음과 같은 2개의 새로운 기능이 추가되었습니다. {: .doclist } -* 라우트 경로에 대하여 체인 가능한 라우트 핸들러를 작성할 수 있는 새로운 메소드인 `app.route()`. -* 모듈식 마운팅 가능한 라우트 핸들러를 작성할 수 있는 새로운 클래스인 `express.Router`. + +- 라우트 경로에 대하여 체인 가능한 라우트 핸들러를 작성할 수 있는 새로운 메소드인 `app.route()`. +- 모듈식 마운팅 가능한 라우트 핸들러를 작성할 수 있는 새로운 클래스인 `express.Router`.

      app.route() 메소드

      @@ -130,20 +131,18 @@ app.use('/book/:id', function(req, res, next) { `app.route()` 함수를 사용하여 정의된 체인 라우트 핸들러의 예는 다음과 같습니다. -
      -
      +```js
       app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      +  .get((req, res) => {
      +    res.send('Get a random book')
      +  })
      +  .post((req, res) => {
      +    res.send('Add a book')
         })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      +  .put((req, res) => {
      +    res.send('Update the book')
         })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      +```

      express.Router 클래스

      @@ -158,38 +157,36 @@ app.route('/book') 예를 들면, 다음의 내용이 입력된 `birds.js`라는 이름의 라우터 파일을 앱 디렉토리에 작성할 수 있습니다. -
      -
      -var express = require('express');
      -var router = express.Router();
      +```js
      +var express = require('express')
      +var router = express.Router()
       
       // middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      +router.use((req, res, next) => {
      +  console.log('Time: ', Date.now())
      +  next()
      +})
       // define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      +router.get('/', (req, res) => {
      +  res.send('Birds home page')
      +})
       // define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      +router.get('/about', (req, res) => {
      +  res.send('About birds')
      +})
       
      -module.exports = router;
      -
      -
      +module.exports = router +``` 이후 앱 내에서 다음과 같이 라우터 모듈을 로드하십시오. -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      +```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` 앱은 이제 `/birds` 및 `/birds/about` 경로에 대한 요청을 처리할 수 있게 되었으며, 해당 라우트에 대한 특정한 미들웨어인 @@ -202,7 +199,7 @@ app.use('/birds', birds); 다음 표에는 Express 4의 작지만 중요한 다른 변경사항이 나열되어 있습니다. - + @@ -312,7 +309,7 @@ Express 4에서는 기본적으로 `json spaces` 애플리케이션 특성을 기능을 위해서는 `res.cookie()`를 사용하십시오. -
      오브젝트 설명
      +

      앱 마이그레이션의 예

      @@ -327,49 +324,46 @@ Express 4에서는 기본적으로 `json spaces` 애플리케이션 특성을 다음과 같은 `app.js` 파일을 갖는 Express 버전 3 애플리케이션을 가정합니다. -
      -
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      +```js
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var http = require('http')
      +var path = require('path')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(express.favicon())
      +app.use(express.logger('dev'))
      +app.use(express.methodOverride())
      +app.use(express.session({ secret: 'your secret here' }))
      +app.use(express.bodyParser())
      +app.use(app.router)
      +app.use(express.static(path.join(__dirname, 'public')))
       
       // development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(express.errorHandler())
       }
       
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

      package.json

      동반되는 버전 3의 `package.json` 파일의 내용은 - 다음과 같을 수 있습니다. +다음과 같을 수 있습니다. -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -382,8 +376,7 @@ http.createServer(app).listen(app.get('port'), function(){
           "pug": "*"
         }
       }
      -
      -
      +```

      프로세스 @@ -393,24 +386,22 @@ http.createServer(app).listen(app.get('port'), function(){ 각각 최신 버전으로 업데이트하여 마이그레이션 프로세스를 시작하십시오. -
      -
      +```bash
       $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      -
      +``` `app.js`를 다음과 같이 변경하십시오. 1. 기본 제공 Express 미들웨어 함수인 `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` 및 - `express.errorHandler`는 더 이상 `express` - 오브젝트에 사용할 수 없습니다. 이들 함수의 대체 함수를 수동으로 - 설치한 후 앱에서 로드해야 합니다. + `express.logger`, `express.methodOverride`, + `express.session`, `express.bodyParser` 및 + `express.errorHandler`는 더 이상 `express` + 오브젝트에 사용할 수 없습니다. 이들 함수의 대체 함수를 수동으로 + 설치한 후 앱에서 로드해야 합니다. 2. `app.router` 함수는 이제 로드할 필요가 없습니다. - 이 함수는 유효한 Express 4 앱 오브젝트가 아니므로 - `app.use(app.router);` 코드를 제거하십시오. + 이 함수는 유효한 Express 4 앱 오브젝트가 아니므로 + `app.use(app.router);` 코드를 제거하십시오. 3. 미들웨어 함수들이 올바른 순서로 로드되는지 확인하십시오(앱 라우트를 로드한 후 `errorHandler`를 로드). @@ -420,8 +411,7 @@ $ npm install serve-favicon morgan method-override express-session body-parser m 위의 `npm` 명령을 실행하면 `package.json`이 다음과 같이 업데이트됩니다. -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -434,119 +424,115 @@ $ npm install serve-favicon morgan method-override express-session body-parser m
           "errorhandler": "^1.1.1",
           "express": "^4.8.0",
           "express-session": "^1.7.2",
      -    "pug": "^2.0.0-beta6",
      +    "pug": "^2.0.0",
           "method-override": "^2.1.2",
           "morgan": "^1.2.2",
           "multer": "^0.1.3",
           "serve-favicon": "^2.0.1"
         }
       }
      -
      -
      +```

      app.js

      이후 올바르지 않은 코드를 제거하고, 필요한 미들웨어를 로드하고, 필요에 따라 다른 변경을 실행하십시오. `app.js` 파일의 내용은 다음과 같습니다. -
      -
      -var http = require('http');
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      +```js
      +var http = require('http')
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var path = require('path')
       
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      +var favicon = require('serve-favicon')
      +var logger = require('morgan')
      +var methodOverride = require('method-override')
      +var session = require('express-session')
      +var bodyParser = require('body-parser')
      +var multer = require('multer')
      +var errorHandler = require('errorhandler')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
      +app.use(logger('dev'))
      +app.use(methodOverride())
      +app.use(session({
      +  resave: true,
      +  saveUninitialized: true,
      +  secret: 'uwotm8'
      +}))
      +app.use(bodyParser.json())
      +app.use(bodyParser.urlencoded({ extended: true }))
      +app.use(multer())
      +app.use(express.static(path.join(__dirname, 'public')))
      +
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
       // error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(errorHandler())
       }
       
      -var server = http.createServer(app);
      -server.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```
      `http` 모듈을 이용해 직접 작업해야 하는 경우(socket.io/SPDY/HTTPS)를 제외하면 `http` 모듈을 로드할 필요가 없으며, 다음과 같은 방법으로 간단히 앱을 시작할 수 있습니다. -
      -app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +
      -

      앱 실행

      +

      Run the app

      마이그레이션 프로세스가 완료되었으며, 이제 앱은 Express 4 앱이 되었습니다. 확인을 위하여, 다음의 명령을 이용해 앱을 시작하십시오. -
      -
      +```bash
       $ node .
      -
      -
      +``` [http://localhost:3000](http://localhost:3000)을 - 로드한 후 홈 페이지가 Express 4에 의해 렌더링되는 것을 확인하십시오. +로드한 후 홈 페이지가 Express 4에 의해 렌더링되는 것을 확인하십시오.

      Express 4 앱 생성기로의 업그레이드

      Express 앱을 생성하기 위한 명령행 도구는 여전히 - `express`이지만, 새 버전으로 업그레이드하려면 - Express 3 앱 생성기의 설치를 제거한 후 새로운 - `express-generator`를 설치해야 합니다. +`express`이지만, 새 버전으로 업그레이드하려면 +Express 3 앱 생성기의 설치를 제거한 후 새로운 +`express-generator`를 설치해야 합니다.

      설치

      Express 3 앱 생성기가 이미 시스템에 설치되어 있는 경우, 다음과 같이 Express 3 앱 생성기의 설치를 제거해야 합니다. -
      -
      +```bash
       $ npm uninstall -g express
      -
      -
      +``` + 파일 및 디렉토리 권한이 구성된 방식에 따라서, 위의 명령은 `sudo`를 이용해 실행해야 할 수도 있습니다. 이제 다음과 같이 새 생성기를 설치하십시오. -
      -
      +```bash
       $ npm install -g express-generator
      -
      -
      +``` 파일 및 디렉토리 권한이 구성된 방식에 따라서, 위의 명령은 `sudo`를 이용해 실행해야 할 수도 있습니다. @@ -559,19 +545,18 @@ $ npm install -g express-generator 다음을 제외하면, 명령의 옵션 및 용도는 대체로 동일하게 유지되었습니다. {: .doclist } -* `--sessions` 옵션이 제거되었습니다. -* `--jshtml` 옵션이 제거되었습니다. -* [Hogan.js](http://twitter.github.io/hogan.js/)를 지원하기 위한 `--hogan` 옵션이 추가되었습니다. -

      +- `--sessions` 옵션이 제거되었습니다. +- `--jshtml` 옵션이 제거되었습니다. +- [Hogan.js](http://twitter.github.io/hogan.js/)를 지원하기 위한 `--hogan` 옵션이 추가되었습니다. + +

      Example

      Express 4 앱을 작성하기 위하여 다음의 명령을 실행하십시오. -
      -
      +```bash
       $ express app4
      -
      -
      +``` `app4/app.js` 파일의 내용을 살펴보면, 앱에 필요한 모든 미들웨어 함수(`express.static` 제외)가 독립적인 모듈로서 로드되며 @@ -582,11 +567,9 @@ $ express app4 종속 항목을 설치한 후, 다음의 명령을 이용해 앱을 시작하십시오. -
      -
      +```bash
       $ npm start
      -
      -
      +``` `package.json` 파일 내의 npm 시작 스크립트를 살펴보면, Express 3에서는 `node app.js`를 이용해 앱을 시작했지만, @@ -608,27 +591,23 @@ Node.js 파일을 통해 시작되어야 합니다. 이 경우에서 Node.js 파 `app.js` 파일의 끝에 있는 `module.exports = app;`가 포함된 행을 삭제한 후 그 자리에 다음의 코드를 붙여넣으십시오. -
      -
      -app.set('port', process.env.PORT || 3000);
      +```js
      +app.set('port', process.env.PORT || 3000)
       
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      -
      +var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` `debug` 모듈은 다음의 코드를 이용하여 `app.js` 파일의 맨 위에서 로드되어야 합니다. -
      -
      -var debug = require('debug')('app4');
      -
      -
      +```js +var debug = require('debug')('app4') +``` 다음으로, `package.json` 파일의 `"start": "node ./bin/www"`를 `"start": "node app.js"`로 변경하십시오. 이제 `./bin/www`의 기능이 다시 `app.js`로 -이전되었습니다. 이러한 변경은 권장되지 않지만, 이러한 연습을 통해 +이전되었습니다. 이러한 변경은 권장되지 않지만, 이러한 연습을 통해 `./bin/www` 파일의 작동 원리를 이해하고 `app.js` 파일이 더 이상 자체적으로 시작되지 않는 이유를 이해할 수 있습니다. diff --git a/ko/guide/migrating-5.md b/ko/guide/migrating-5.md old mode 100755 new mode 100644 index 84bf4702b3..199b1ce2a4 --- a/ko/guide/migrating-5.md +++ b/ko/guide/migrating-5.md @@ -1,32 +1,44 @@ --- layout: page title: Express 5로의 마이그레이션 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: ko +redirect_from: " " --- # Express 5로의 이전

      개요

      -Express 5.0은 아직 알파 릴리스 단계에 있지만, 이 문서에서는 릴리스에 포함될 변경사항과 Express 4 앱을 Express 5로 마이그레이션하는 방법을 미리 살펴봅니다. +Express 5는 Express 4와 크게 다르지 않으며, API에 대한 변경은 3.0에서 4.0으로의 변경만큼 크지 않습니다. 기본적인 API는 동일하게 유지되지만, 근본적인 변경사항이 존재합니다. 즉, Express 5를 사용하기 위해 기존 Express 4 프로그램을 업데이트하면 기존 Express 4 프로그램은 작동하지 않을 수 있습니다. -Express 5는 Express 4와 크게 다르지 않으며, API에 대한 변경은 3.0에서 4.0으로의 변경만큼 크지 않습니다. 기본적인 API는 동일하게 유지되지만, 근본적인 변경사항이 존재합니다. 즉, Express 5를 사용하기 위해 기존 Express 4 프로그램을 업데이트하면 기존 Express 4 프로그램은 작동하지 않을 수 있습니다. +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -Express 5의 최신 알파 버전을 설치하고 미리보려면, 애플리케이션 루트 디렉토리에서 다음의 명령을 입력하십시오. - -
      -
      -$ npm install express@5.0.0-alpha.2 --save
      -
      -
      +```sh +npm install "express@5" +``` 이후 자동화된 테스트를 실행하여 실패하는 항목을 확인하고, 아래에 나열된 업데이트에 따라 문제를 수정할 수 있습니다. 테스트 실패 항목을 처리한 후에는 앱을 실행하여 어떠한 오류가 발생하는지 확인하십시오. 지원되지 않는 메소드나 특성을 앱이 사용하는 경우에는 이를 곧바로 확인할 수 있습니다. -

      Express 5에서의 변경사항

      +## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: + +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). -아래에는 Express 사용자에게 영향을 미치는 변경사항(알파 2 릴리스 기준)의 목록이 표시되어 있습니다. -계획된 모든 기능의 목록을 확인하려면 [pull request](https://github.com/expressjs/express/pull/2237)를 참조하십시오. +

      Express 5에서의 변경사항

      **제거된 메소드 및 특성** @@ -38,96 +50,497 @@ $ npm install express@5.0.0-alpha.2 --save
    • req.param(name)
    • res.json(obj, status)
    • res.jsonp(obj, status)
    • +
    • res.redirect('back') and res.location('back')
    • +
    • res.redirect(url, status)
    • res.send(body, status)
    • res.send(status)
    • res.sendfile()
    • +
    • router.param(fn)
    • +
    • express.static.mime
    • +
    • express:router debug logs
    -**변경된 항목** +**개선된 항목** -**개선된 항목** +**변경된 항목** -

    제거된 메소드 및 특성

    +## 제거된 메소드 및 특성 앱에서 이러한 메소드 또는 특성 중 어느 하나라도 사용한다면 앱에서 충돌이 발생합니다. 따라서 버전 5로 업데이트한 후에는 앱을 변경해야 합니다. -

    app.del()

    +

    app.del()

    Express 5는 `app.del()` 함수를 더 이상 지원하지 않습니다. 이 함수를 사용하면 오류에 대한 예외 처리(throw)가 발생합니다. HTTP DELETE 라우트를 등록하려면 `app.delete()` 함수를 대신 사용하십시오. -`delete`는 JavaScript의 예약된 키워드이므로, 처음에는 `delete` 대신 `del`이 사용되었습니다. 그러나, ECMAScript 6을 기준으로, `delete` 및 다른 예약된 키워드를 정식 특성 이름으로 사용할 수 있게 되었습니다. `app.del` 함수 사용 중단의 요인이 된 토론을 여기서 읽을 수 있습니다. +`delete`는 JavaScript의 예약된 키워드이므로, 처음에는 `delete` 대신 `del`이 사용되었습니다. 그러나, ECMAScript 6을 기준으로, `delete` 및 다른 예약된 키워드를 정식 특성 이름으로 사용할 수 있게 되었습니다. + +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` + +{% endcapture %} -

    app.param(fn)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) + +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

    app.param(fn)

    `app.param(fn)` 시그니처는 `app.param(name, fn)` 함수의 작동을 수정하는 데 사용되었습니다. 이 시그니처는 v4.11.0 이후 더 이상 사용되지 않았으며 Express 5에서는 전혀 지원되지 않습니다. -

    복수형의 메소드 이름

    +

    복수형의 메소드 이름

    + +다음과 같은 메소드 이름은 이제 복수형이 되었습니다. Express 4에서는 구버전의 메소드를 사용하면 사용 중단 경고가 표시되었습니다. Express 5는 구버전의 메소드를 전혀 지원하지 않습니다. -다음과 같은 메소드 이름은 이제 복수형이 되었습니다. Express 4에서는 구버전의 메소드를 사용하면 사용 중단 경고가 표시되었습니다. Express 5는 구버전의 메소드를 전혀 지원하지 않습니다. +`req.acceptsLanguage()`는 `req.acceptsLanguages()`로 대체되었습니다. `req.acceptsCharset()`는 `req.acceptsCharsets()`로 대체되었습니다. `req.acceptsEncoding()`은 `req.acceptsEncodings()`로 대체되었습니다. -`req.acceptsLanguage()`는 `req.acceptsLanguages()`로 대체되었습니다. +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} -

    app.param(name, fn)에 대한 이름(name)의 첫머리 콜론(:)

    +{% include admonitions/note.html content=codemod-pluralized-methods %} + +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    app.param(name, fn)에 대한 이름(name)의 첫머리 콜론(:)

    `app.param(name, fn)` 함수의 이름(name)의 첫머리 콜론 문자(:)는 Express 3의 잔존물이며, 하위 호환성을 위해 Express 4에서는 첫머리 콜론을 지원하면서 사용 중단 알림을 표시했습니다. Express 5는 아무런 메시지 표시 없이 첫머리 콜론을 무시하며, 콜론을 이용한 접두부가 없는 이름 매개변수를 사용합니다. [app.param](/{{ page.lang }}/4x/api.html#app.param)에 대한 Express 4 문서에는 첫머리 콜론이 언급되어 있지 않으므로, 이 문서를 따라 앱을 작성한 경우에는 이 변경사항이 코드에 영향을 미치지 않을 것입니다. -

    req.param(name)

    +

    req.param(name)

    양식 데이터 검색을 위한 이 메소드는 혼란과 위험을 발생시킬 수 있으므로 제거되었습니다. 이제는 `req.params`, `req.body` 또는 `req.query` 오브젝트에서 제출된 매개변수 이름을 구체적으로 확인해야 합니다. -

    res.json(obj, status)

    +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    Express 5는 `res.json(obj, status)` 시그니처를 더 이상 지원하지 않습니다. 대신, 상태를 설정한 후 이를 `res.status(status).json(obj)`과 같은 `res.json()` 메소드에 체인해야 합니다. -

    res.jsonp(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    Express 5는 `res.jsonp(obj, status)` 시그니처를 더 이상 지원하지 않습니다. 대신, 상태를 설정한 후 이를 `res.status(status).jsonp(obj)`와 같은 `res.jsonp()` 메소드에 체인해야 합니다. -

    res.send(body, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    Express 5는 `res.send(obj, status)` 시그니처를 더 이상 지원하지 않습니다. 대신, 상태를 설정한 후 이를 `res.status(status).send(obj)`와 같은 `res.send()` 메소드에 체인해야 합니다. -

    res.send(status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    -Express 5는 *`status`*가 숫자인 res.send(status) 시그니처를 더 이상 지원하지 않습니다. 대신, HTTP 응답 헤더 상태 코드를 설정하고 해당 코드의 텍스트 버전("Not Found", "Internal Server Error" 등)을 전송하는 `res.sendStatus(statusCode)` 함수를 사용해야 합니다. +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    + +Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) + +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` + +

    res.send(status)

    + +Express 5는 \*`status`\*가 숫자인 res.send(status) 시그니처를 더 이상 지원하지 않습니다. 대신, HTTP 응답 헤더 상태 코드를 설정하고 해당 코드의 텍스트 버전("Not Found", "Internal Server Error" 등)을 전송하는 `res.sendStatus(statusCode)` 함수를 사용해야 합니다. `res.send()` 함수를 이용해 숫자를 전송해야 하는 경우, Express가 그 숫자를 지원되지 않는 구버전 시그니처 사용 시도로 해석하지 않도록 숫자의 앞뒤에 따옴표를 추가하여 숫자를 문자열로 변환하십시오. -

    res.sendfile()

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) + +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

    res.sendfile()

    Express 5에서 `res.sendfile()` 함수는 낙타 대문자(camel-cased) 버전인 `res.sendFile()`로 대체되었습니다. -

    변경된 항목

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. 이 시그니처는 v4.11.0 이후 더 이상 사용되지 않았으며 Express 5에서는 전혀 지원되지 않습니다. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## 변경된 항목 + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. 예를 들면 다음과 같습니다. -

    app.router

    +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +예를 들면 다음과 같습니다. + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    Express 4에서 제거되었던 `app.router` 오브젝트가 Express 5에 되돌아왔습니다. Express 3에서는 앱이 이 오브젝트를 명시적으로 로드해야 했던 것과 달리, 새 버전에서 이 오브젝트는 단순히 기본 Express 라우터에 대한 참조의 역할을 합니다. -

    req.host

    +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    Express 4에서, 포트 번호가 존재하는 경우 `req.host` 함수는 포트 번호를 올바르지 않게 제거했습니다. Express 5에서는 포트 번호가 유지됩니다. -

    req.query

    +

    req.query

    + +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -Express 4.7 및 Express 5 버전 이상에서는, 조회 문자열 구문 분석 로직을 위해 자체적인 함수를 사용하기 원할 때 조회 문자열 구문 분석을 사용하지 않도록 하는 `false`를 조회 구문 분석기 옵션으로 사용할 수 있습니다. +

    res.clearCookie

    -

    개선된 항목

    +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. -

    res.render()

    +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## 개선된 항목 + +

    res.render()

    이 메소드는 이제 모든 보기 엔진에 대해 비동기식 작동을 적용하며, 동기식 구현을 갖는 보기 엔진 및 권장되는 인터페이스를 위반하는 보기 엔진에 의한 버그의 발생을 방지합니다. + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/ko/guide/overriding-express-api.md b/ko/guide/overriding-express-api.md new file mode 100644 index 0000000000..bd55ab9b24 --- /dev/null +++ b/ko/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: 프로토타입을 사용해 request와 response 객체의 메서드와 속성을 오버라이드하여 Express.js API를 커스터마이즈하고 확장하는 방법을 알아보세요. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/ko/guide/routing.md b/ko/guide/routing.md old mode 100755 new mode 100644 index d88b62064a..5f69c5fe50 --- a/ko/guide/routing.md +++ b/ko/guide/routing.md @@ -1,28 +1,38 @@ --- layout: page title: Express 라우팅 +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: ko +redirect_from: " " --- # 라우팅 -*라우팅*은 애플리케이션 엔드 포인트(URI)의 정의, 그리고 URI가 클라이언트 요청에 응답하는 방식을 말합니다. +_라우팅_은 애플리케이션 엔드 포인트(URI)의 정의, 그리고 URI가 클라이언트 요청에 응답하는 방식을 말합니다. 라우팅에 대한 소개는 [기본 라우팅](/{{ page.lang }}/starter/basic-routing.html)을 참조하십시오. +You define routing using methods of the Express `app` object that correspond to HTTP methods; +for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). + +특수한 라우팅 메소드인 `app.all()`은 어떠한 HTTP 메소드로부터도 파생되지 않습니다. 이 메소드는 모든 요청 메소드에 대해 한 경로에서 미들웨어 함수를 로드하는 데 사용됩니다. + +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 +to the next callback. + 다음 코드는 매우 기본적인 라우트의 예입니다. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
     // respond with "hello world" when a GET request is made to the homepage
    -app.get('/', function(req, res) {
    -  res.send('hello world');
    -});
    -
    -
    +app.get('/', (req, res) => { + res.send('hello world') +}) +```

    라우트 메소드

    @@ -30,152 +40,207 @@ app.get('/', function(req, res) { 다음 코드는 앱의 루트에 대한 GET 및 POST 메소드에 대해 정의된 라우트의 예입니다. -
    -
    +```js
     // GET method route
    -app.get('/', function (req, res) {
    -  res.send('GET request to the homepage');
    -});
    +app.get('/', (req, res) => {
    +  res.send('GET request to the homepage')
    +})
     
     // POST method route
    -app.post('/', function (req, res) {
    -  res.send('POST request to the homepage');
    -});
    -
    -
    +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` Express는 HTTP 메소드에 해당하는 다음과 같은 라우팅 메소드를 지원합니다. -`get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search` 및 `connect`. - -
    -올바르지 않은 JavaScript 변수 이름으로 변환되는 메소드를 라우팅하려면 대괄호 표기법을 사용하십시오. 예를 들면 -`app['m-search']('/', function ...` 등과 같습니다. -
    - -특수한 라우팅 메소드인 `app.all()`은 어떠한 HTTP 메소드로부터도 파생되지 않습니다. 이 메소드는 모든 요청 메소드에 대해 한 경로에서 미들웨어 함수를 로드하는 데 사용됩니다. +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). -다음 예에서는, GET, POST, PUT 또는 DELETE 메소드를 사용하는 경우, 또는 [http 모듈](https://nodejs.org/api/http.html#http_http_methods)에서 지원되는 기타 모든 HTTP 요청 메소드를 사용하는 경우 등의 "/secret"에 대한 요청을 위하여 핸들러가 실행됩니다. +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`, `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('/secret', function (req, res, next) {
    -  console.log('Accessing the secret section ...');
    -  next(); // pass control to the next handler
    -});
    -
    -
    +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +```

    라우트 경로

    라우트 경로는, 요청 메소드와의 조합을 통해, 요청이 이루어질 수 있는 엔드포인트를 정의합니다. 라우트 경로는 문자열, 문자열 패턴 또는 정규식일 수 있습니다. -
    - Express는 라우트 경로의 일치를 위해 [path-to-regexp](https://www.npmjs.com/package/path-to-regexp)를 사용합니다. 라우트 경로를 정의할 수 있는 모든 가능성을 확인하려면 path-to-regexp 문서를 참조하십시오. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/)는 기본적인 Express 라우트의 테스트를 위한 편리한 도구이지만, 패턴 일치는 지원하지 않습니다. -
    +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
    -조회 문자열은 라우트 경로의 일부가 아닙니다. -
    +{% include admonitions/caution.html content=caution-character %} + +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} + +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} -문자열을 기반으로 하는 라우트 경로의 몇 가지 예는 다음과 같습니다. +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/)는 기본적인 Express 라우트의 테스트를 위한 편리한 도구이지만, 패턴 일치는 지원하지 않습니다. + +{% endcapture %} + +{% include admonitions/note.html content=note-path-to-regexp %} + +{% capture query-string-note %} + +Query strings are not part of the route path. + +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### 문자열을 기반으로 하는 라우트 경로의 몇 가지 예는 다음과 같습니다. 다음의 라우트 경로는 요청을 루트 라우트 `/`에 일치시킵니다. -
    -
    -app.get('/', function (req, res) {
    -  res.send('root');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` 다음의 라우트 경로는 요청을 `/about`에 일치시킵니다. -
    -
    -app.get('/about', function (req, res) {
    -  res.send('about');
    -});
    -
    -
    +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` 다음의 라우트 경로는 요청을 `/random.text`에 일치시킵니다. -
    -
    -app.get('/random.text', function (req, res) {
    -  res.send('random.text');
    -});
    -
    -
    +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` -문자열 패턴을 기반으로 하는 라우트 경로의 몇 가지 예는 다음과 같습니다. +### 문자열 패턴을 기반으로 하는 라우트 경로의 몇 가지 예는 다음과 같습니다. + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} + +{% include admonitions/caution.html content=caution-string-patterns %} 다음의 라우트 경로는 `acd` 및 `abcd`와 일치합니다. -
    -
    -app.get('/ab?cd', function(req, res) {
    -  res.send('ab?cd');
    -});
    -
    -
    +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` 다음의 라우트 경로는 `abcd`, `abbcd` 및 `abbbcd` 등과 일치합니다. -
    -
    -app.get('/ab+cd', function(req, res) {
    -  res.send('ab+cd');
    -});
    -
    -
    +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` 다음의 라우트 경로는 `abcd`, `abxcd`, `abRABDOMcd` 및 `ab123cd` 등과 일치합니다. -
    -
    -app.get('/ab*cd', function(req, res) {
    -  res.send('ab*cd');
    -});
    -
    -
    +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` 다음의 라우트 경로는 `/abe` 및 `/abcde`와 일치합니다. -
    -
    -app.get('/ab(cd)?e', function(req, res) {
    - res.send('ab(cd)?e');
    -});
    -
    -
    - -
    -?, +, * 및 () 문자는 정규식 문자의 서브세트입니다. 하이픈(-) 및 점(.)은 문자열 기반 경로에 의해 문자 그대로 해석됩니다. -
    +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` -정규식을 기반으로 하는 라우트 경로의 예: +### 정규식을 기반으로 하는 라우트 경로의 예: 다음의 라우트 경로는 라우트 이름에 "a"가 포함된 모든 항목과 일치합니다. -
    -
    -app.get(/a/, function(req, res) {
    -  res.send('/a/');
    -});
    -
    -
    +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` 다음의 라우트 경로는 `butterfly` 및 `dragonfly`와 일치하지만, `butterflyman` 및 `dragonfly man` 등과 일치하지 않습니다. -
    -
    -app.get(/.*fly$/, function(req, res) {
    -  res.send('/.*fly$/');
    -});
    -
    -
    +```js +app.get(/.*fly$/, (req, res) => { + res.send('/.*fly$/') +}) +``` + +

    +조회 문자열은 라우트 경로의 일부가 아닙니다. +

    + +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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
    +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +
    + +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. + +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` + +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` + +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): + +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` + +{% capture escape-advisory %} + +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %}

    라우트 핸들러

    @@ -183,89 +248,81 @@ app.get(/.*fly$/, function(req, res) { 다음 예에 나타난 것과 같이, 라우트 핸들러는 함수나 함수 배열의 형태 또는 둘을 조합한 형태일 수 있습니다. -하나의 콜백 함수는 하나의 라우트를 처리할 수 있습니다. 예를 들면 다음과 같습니다. +하나의 콜백 함수는 하나의 라우트를 처리할 수 있습니다. 예를 들면 다음과 같습니다. -
    -
    -app.get('/example/a', function (req, res) {
    -  res.send('Hello from A!');
    -});
    -
    -
    +```js +app.get('/example/a', (req, res) => { + res.send('Hello from A!') +}) +``` 2개 이상의 콜백 함수는 하나의 라우트를 처리할 수 있습니다(`next` 오브젝트를 반드시 지정해야 함). 예를 들면 다음과 같습니다. -
    -
    -app.get('/example/b', function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from B!');
    -});
    -
    -
    - -하나의 콜백 함수 배열은 하나의 라우트를 처리할 수 있습니다. 예를 들면 다음과 같습니다. - -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +app.get('/example/b', (req, res, next) => {
    +  console.log('the response will be sent by the next function ...')
    +  next()
    +}, (req, res) => {
    +  res.send('Hello from B!')
    +})
    +```
    +
    +하나의 콜백 함수 배열은 하나의 라우트를 처리할 수 있습니다. 예를 들면 다음과 같습니다.
    +
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -var cb2 = function (req, res) {
    -  res.send('Hello from C!');
    +const cb2 = function (req, res) {
    +  res.send('Hello from C!')
     }
     
    -app.get('/example/c', [cb0, cb1, cb2]);
    -
    -
    +app.get('/example/c', [cb0, cb1, cb2]) +``` -독립적인 함수와 함수 배열의 조합은 하나의 라우트를 처리할 수 있습니다. 예를 들면 다음과 같습니다. +독립적인 함수와 함수 배열의 조합은 하나의 라우트를 처리할 수 있습니다. 예를 들면 다음과 같습니다. -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/d', [cb0, cb1], function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from D!');
    -});
    -
    -
    +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +```

    응답 메소드

    다음 표에 표시된 응답 오브젝트에 대한 메소드(`res`)는 응답을 클라이언트로 전송하고 요청-응답 주기를 종료할 수 있습니다. 라우트 핸들러로부터 다음 메소드 중 어느 하나도 호출되지 않는 경우, 클라이언트 요청은 정지된 채로 방치됩니다. -| 메소드 | 설명 -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | 파일이 다운로드되도록 프롬프트합니다. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | 응답 프로세스를 종료합니다. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | JSON 응답을 전송합니다. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | JSONP 지원을 통해 JSON 응답을 전송합니다. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | 요청의 경로를 재지정합니다. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | 보기 템플리트를 렌더링합니다. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | 다양한 유형의 응답을 전송합니다. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | 파일을 옥텟 스트림의 형태로 전송합니다. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | 응답 상태 코드를 설정한 후 해당 코드를 문자열로 표현한 내용을 응답 본문으로서 전송합니다. +| 메소드 | 설명 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | 파일이 다운로드되도록 프롬프트합니다. | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | 응답 프로세스를 종료합니다. | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | JSON 응답을 전송합니다. | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | JSONP 지원을 통해 JSON 응답을 전송합니다. | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | 요청의 경로를 재지정합니다. | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | 보기 템플리트를 렌더링합니다. | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | 다양한 유형의 응답을 전송합니다. | +| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | 파일을 옥텟 스트림의 형태로 전송합니다. | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | 응답 상태 코드를 설정한 후 해당 코드를 문자열로 표현한 내용을 응답 본문으로서 전송합니다. |

    app.route()

    @@ -274,20 +331,18 @@ app.get('/example/d', [cb0, cb1], function (req, res, next) { `app.route()`를 사용하여 정의된 체인 라우트 핸들러의 예는 다음과 같습니다. -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
    +  })
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .put((req, res) => {
    +    res.send('Update the book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    +```

    express.Router

    @@ -297,37 +352,43 @@ app.route('/book') 다음의 내용이 입력된 `birds.js`라는 이름의 라우터 파일을 앱 디렉토리에 작성하십시오. -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const router = express.Router()
     
     // middleware that is specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +const timeLog = (req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +}
    +router.use(timeLog)
    +
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` 이후 앱 내에서 다음과 같이 라우터 모듈을 로드하십시오. -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +const birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` 앱은 이제 `/birds` 및 `/birds/about`에 대한 요청을 처리할 수 있게 되었으며, 해당 라우트에 대한 특정한 미들웨어 함수인 `timeLog`를 호출할 것입니다. + +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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/ko/guide/using-middleware.md b/ko/guide/using-middleware.md old mode 100755 new mode 100644 index 3308a91cb2..6f65293a64 --- a/ko/guide/using-middleware.md +++ b/ko/guide/using-middleware.md @@ -1,265 +1,260 @@ --- layout: page title: Express 미들웨어 사용 +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: ko +redirect_from: " " --- # 미들웨어 사용 Express는 자체적인 최소한의 기능을 갖춘 라우팅 및 미들웨어 웹 프레임워크이며, Express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출입니다. -*미들웨어* 함수는 [요청 오브젝트](/{{ page.lang }}/4x/api.html#req)(`req`), [응답 오브젝트](/{{ page.lang }}/4x/api.html#res) (`res`), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 `next`라는 이름의 변수로 표시됩니다. +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the next middleware function in the application's request-response cycle. 그 다음의 미들웨어 함수는 일반적으로 `next`라는 이름의 변수로 표시됩니다. 미들웨어 함수는 다음과 같은 태스크를 수행할 수 있습니다. -* 모든 코드를 실행. -* 요청 및 응답 오브젝트에 대한 변경을 실행. -* 요청-응답 주기를 종료. -* 스택 내의 그 다음 미들웨어 함수를 호출. +- 모든 코드를 실행. +- 요청 및 응답 오브젝트에 대한 변경을 실행. +- 요청-응답 주기를 종료. +- 스택 내의 그 다음 미들웨어 함수를 호출. 현재의 미들웨어 함수가 요청-응답 주기를 종료하지 않는 경우에는 `next()`를 호출하여 그 다음 미들웨어 함수에 제어를 전달해야 합니다. 그렇지 않으면 해당 요청은 정지된 채로 방치됩니다. Express 애플리케이션은 다음과 같은 유형의 미들웨어를 사용할 수 있습니다. - - [애플리케이션 레벨 미들웨어](#middleware.application) - - [라우터 레벨 미들웨어](#middleware.router) - - [오류 처리 미들웨어](#middleware.error-handling) - - [기본 제공 미들웨어](#middleware.built-in) - - [써드파티 미들웨어](#middleware.third-party) +- [애플리케이션 레벨 미들웨어](#middleware.application) +- [라우터 레벨 미들웨어](#middleware.router) +- [오류 처리 미들웨어](#middleware.error-handling) +- [기본 제공 미들웨어](#middleware.built-in) +- [써드파티 미들웨어](#middleware.third-party) 애플리케이션 레벨 및 라우터 레벨 미들웨어는 선택적인 마운트 경로를 통해 로드할 수 있습니다. 일련의 미들웨어 함수를 함께 로드할 수도 있으며, 이를 통해 하나의 마운트 위치에 미들웨어 시스템의 하위 스택을 작성할 수 있습니다.

    애플리케이션 레벨 미들웨어

    -`app.use()` 및 `app.METHOD()` 함수를 이용해 애플리케이션 미들웨어를 [앱 오브젝트](/{{ page.lang }}/4x/api.html#app)의 인스턴스에 바인드하십시오. 이때 `METHOD`는 미들웨어 함수가 처리하는 요청(GET, PUT 또는 POST 등)의 소문자로 된 HTTP 메소드입니다. +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. 다음 예에는 마운트 경로가 없는 미들웨어 함수가 표시되어 있습니다. 이 함수는 앱이 요청을 수신할 때마다 실행됩니다. -
    -
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    -
    -
    +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` 다음 예에는 `/user/:id` 경로에 마운트되는 미들웨어 함수가 표시되어 있습니다. 이 함수는 `/user/:id` 경로에 대한 모든 유형의 HTTP 요청에 대해 실행됩니다. -
    -
    -app.use('/user/:id', function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` 다음 예에는 라우트 및 해당 라우트의 핸들러 함수(미들웨어 시스템)이 표시되어 있습니다. 이 함수는 `/user/:id` 경로에 대한 GET 요청을 처리합니다. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  res.send('USER');
    -});
    -
    -
    +```js +app.get('/user/:id', (req, res, next) => { + res.send('USER') +}) +``` 아래에는 하나의 마운트 경로를 통해 일련의 미들웨어 함수를 하나의 마운트 위치에 로드하는 예가 표시되어 있습니다. 이 예는 `/user/:id` 경로에 대한 모든 유형의 HTTP 요청에 대한 요청 정보를 인쇄하는 미들웨어 하위 스택을 나타냅니다. -
    -
    -app.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` 라우트 핸들러를 이용하면 하나의 경로에 대해 여러 라우트를 정의할 수 있습니다. 아래의 예에서는 `/user/:id` 경로에 대한 GET 요청에 대해 2개의 라우트를 정의합니다. 두 번째 라우트는 어떠한 문제도 발생키지 않지만, 첫 번째 라우트가 요청-응답 주기를 종료시키므로 두 번째 라우트는 절대로 호출되지 않습니다. 다음 예에는 `/user/:id` 경로에 대한 GET 요청을 처리하는 미들웨어 하위 스택이 표시되어 있습니다. -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -}, function (req, res, next) {
    -  res.send('User Info');
    -});
    +```js
    +app.get('/user/:id', (req, res, next) => {
    +  console.log('ID:', req.params.id)
    +  next()
    +}, (req, res, next) => {
    +  res.send('User Info')
    +})
     
     // handler for the /user/:id path, which prints the user ID
    -app.get('/user/:id', function (req, res, next) {
    -  res.end(req.params.id);
    -});
    -
    -
    +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) +}) +``` 라우터 미들웨어 스택의 나머지 미들웨어 함수들을 건너뛰려면 `next('route')`를 호출하여 제어를 그 다음 라우트로 전달하십시오. -**참고**: `next('route')`는 `app.METHOD()` 또는 `router.METHOD()` 함수를 이용해 로드된 미들웨어 함수에서만 작동합니다. + +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} 다음 예에는 `/user/:id` 경로에 대한 GET 요청을 처리하는 미들웨어 하위 스택이 표시되어 있습니다. -
    -
    -app.get('/user/:id', function (req, res, next) {
    +```js
    +app.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next route
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass the control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    -  // render a regular page
    -  res.render('regular');
    -});
    +  else next()
    +}, (req, res, next) => {
    +  // send a regular response
    +  res.send('regular')
    +})
     
    -// handler for the /user/:id path, which renders a special page
    -app.get('/user/:id', function (req, res, next) {
    -  res.render('special');
    -});
    -
    -
    +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +아래에는 상세한 옵션 오브젝트와 함께 `express.static` 미들웨어 함수를 사용하는 예가 표시되어 있습니다. + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

    라우터 레벨 미들웨어

    라우터 레벨 미들웨어는 `express.Router()` 인스턴스에 바인드된다는 점을 제외하면 애플리케이션 레벨 미들웨어와 동일한 방식으로 작동합니다. -
    -
    -var router = express.Router();
    -
    -
    +```js +const router = express.Router() +``` + `router.use()` 및 `router.METHOD()` 함수를 사용하여 라우터 레벨 미들웨어를 로드하십시오. 다음 예의 코드는 위에서 애플리케이션 레벨 미들웨어에 대해 표시된 미들웨어 시스템을 라우터 레벨 미들웨어를 사용하여 복제합니다. -
    -
    -var app = express();
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const app = express()
    +const router = express.Router()
     
     // a middleware function with no mount path. This code is executed for every request to the router
    -router.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time:', Date.now())
    +  next()
    +})
     
     // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    -router.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    +router.use('/user/:id', (req, res, next) => {
    +  console.log('Request URL:', req.originalUrl)
    +  next()
    +}, (req, res, next) => {
    +  console.log('Request Type:', req.method)
    +  next()
    +})
     
     // a middleware sub-stack that handles GET requests to the /user/:id path
    -router.get('/user/:id', function (req, res, next) {
    +router.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next router
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    +  else next()
    +}, (req, res, next) => {
       // render a regular page
    -  res.render('regular');
    -});
    +  res.render('regular')
    +})
     
     // handler for the /user/:id path, which renders a special page
    -router.get('/user/:id', function (req, res, next) {
    -  console.log(req.params.id);
    -  res.render('special');
    -});
    +router.get('/user/:id', (req, res, next) => {
    +  console.log(req.params.id)
    +  res.render('special')
    +})
     
     // mount the router on the app
    -app.use('/', router);
    -
    -
    +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. + +다음 예에는 `/user/:id` 경로에 대한 GET 요청을 처리하는 미들웨어 하위 스택이 표시되어 있습니다. + +```js +const express = require('express') +const app = express() +const router = express.Router() + +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) + +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) + +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +```

    오류 처리 미들웨어

    -오류 처리 미들웨어에는 항상 *4개*의 인수가 필요합니다. 어떠한 함수를 오류 처리 미들웨어 함수로 식별하려면 4개의 인수를 제공해야 합니다. `next` 오브젝트를 사용할 필요는 없지만, 시그니처를 유지하기 위해 해당 오브젝트를 지정해야 합니다. 그렇지 않으면 `next` 오브젝트는 일반적인 미들웨어로 해석되어 오류 처리에 실패하게 됩니다. +오류 처리 미들웨어에는 항상 *4개*의 인수가 필요합니다. 어떠한 함수를 오류 처리 미들웨어 함수로 식별하려면 4개의 인수를 제공해야 합니다. `next` 오브젝트를 사용할 필요는 없지만, 시그니처를 유지하기 위해 해당 오브젝트를 지정해야 합니다. 그렇지 않으면 `next` 오브젝트는 일반적인 미들웨어로 해석되어 오류 처리에 실패하게 됩니다.
    다른 미들웨어 함수와 동일반 방법으로 다음과 같이 오류 처리 미들웨어 함수를 정의할 수 있지만, 오류 처리 함수는 3개가 아닌 4개의 인수, 구체적으로 말하면 `(err, req, res, next)` 시그니처를 갖는다는 점이 다릅니다. -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` 오류 처리 미들웨어에 대한 상세 정보는 [오류 처리](/{{ page.lang }}/guide/error-handling.html)를 참조하십시오. -

    기본 제공 미들웨어

    +

    Built-in middleware

    4.x 버전 이후의 Express는 더 이상 [Connect](https://github.com/senchalabs/connect)에 종속되지 않습니다. `express.static`의 실행을 제외하면, 이전에 Express와 함께 포함되었던 모든 미들웨어 함수는 이제 별도의 모듈에 포함되어 있습니다. [미들웨어 함수 목록](https://github.com/senchalabs/connect#middleware)을 확인하십시오. -

    express.static(root, [options])

    - -Express의 유일한 기본 제공 미들웨어 함수는 `express.static`입니다. 이 함수는 [serve-static](https://github.com/expressjs/serve-static)을 기반으로 하며, Express 애플리케이션의 정적 자산을 제공하는 역할을 합니다. - -`root` 인수는 정적 자산의 제공을 시작하는 위치가 되는 루트 디렉토리를 지정합니다. - -선택사항인 `options` 오브젝트는 다음과 같은 특성을 가질 수 있습니다. - -| 특성 | 설명 | 유형 | 기본값 | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | dotfile을 제공하기 위한 옵션입니다. 사용 가능한 값은 "allow", "deny" 및 "ignore"입니다. | 문자열 | "ignore" | -| `etag` | etag의 생성을 사용 또는 사용 안함으로 설정합니다. | 부울 | `true` | -| `extensions` | 파일 확장자 폴백을 설정합니다. | 배열 | `[]` | -| `index` | 디렉토리 인덱스 파일을 전송합니다. 디렉토리 인덱스 작성을 사용하지 않으려면 `false`를 설정하십시오. | 혼합 | "index.html" | - `lastModified` | OS에서 해당 파일이 마지막으로 수정된 날짜를 `Last-Modified` 헤더에 설정합니다. 사용 가능한 값은 `true` 또는 `false`입니다. | 부울 | `true` | -| `maxAge` | 밀리초 또는 [ms 형식](https://www.npmjs.org/package/ms)의 문자열로 Cache-Control 헤더의 max-age 특성을 설정합니다. | 숫자 | 0 | -| `redirect` | 경로 이름이 디렉토리인 경우 후미부의 "/"로 경로를 재지정합니다. | 부울 | `true` | -| `setHeaders` | 파일을 제공하도록 HTTP 헤더를 설정하기 위한 함수입니다. | 함수 | | - -아래에는 상세한 옵션 오브젝트와 함께 `express.static` 미들웨어 함수를 사용하는 예가 표시되어 있습니다. - -
    -
    -var options = {
    -  dotfiles: 'ignore',
    -  etag: false,
    -  extensions: ['htm', 'html'],
    -  index: false,
    -  maxAge: '1d',
    -  redirect: false,
    -  setHeaders: function (res, path, stat) {
    -    res.set('x-timestamp', Date.now());
    -  }
    -}
    -
    -app.use(express.static('public', options));
    -
    -
    - -다음과 같이, 하나의 앱은 2개 이상의 정적 디렉토리를 가질 수 있습니다. - -
    -
    -app.use(express.static('public'));
    -app.use(express.static('uploads'));
    -app.use(express.static('files'));
    -
    -
    +Express has the following built-in middleware functions: -`serve-static` 함수 및 그 옵션에 대한 자세한 정보는 [serve-static](https://github.com/expressjs/serve-static) 문서를 참조하십시오. +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** -

    써드파티 미들웨어

    +

    Third-party middleware

    Express 앱에 기능을 추가하려면 써드파티 미들웨어를 사용하십시오. @@ -267,21 +262,17 @@ Express 앱에 기능을 추가하려면 써드파티 미들웨어를 사용하 다음 예는 쿠키 구문 분석 미들웨어 함수인 `cookie-parser`의 설치 및 로드를 나타냅니다. -
    -
    +```bash
     $ npm install cookie-parser
    -
    -
    +``` -
    -
    -var express = require('express');
    -var app = express();
    -var cookieParser = require('cookie-parser');
    +```js
    +const express = require('express')
    +const app = express()
    +const cookieParser = require('cookie-parser')
     
     // load the cookie-parsing middleware
    -app.use(cookieParser());
    -
    -
    +app.use(cookieParser()) +``` Express와 함께 일반적으로 사용되고 있는 써드파티 미들웨어 함수의 일부 목록을 확인하려면 [써드파티 미들웨어](../resources/middleware.html)를 참조하십시오. diff --git a/ko/guide/using-template-engines.md b/ko/guide/using-template-engines.md old mode 100755 new mode 100644 index 052432da4b..b881be8fda --- a/ko/guide/using-template-engines.md +++ b/ko/guide/using-template-engines.md @@ -1,61 +1,62 @@ --- layout: page title: Express와 함께 템플리트 엔진 사용 +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: ko +redirect_from: " " --- -# Express와 함께 템플리트 엔진을 사용 +# Express와 함께 템플리트 엔진 사용 -Express가 템플리트를 렌더링하려면 다음과 같은 애플리케이션 설정이 필요합니다. +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +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. -* `views`, 템플리트가 있는 디렉토리. 예: `app.set('views', './views')` -* `view engine`, 사용할 템플리트 엔진. 예: `app.set('view engine', 'pug')` +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. + +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: + +- `views`, 템플리트가 있는 디렉토리. 예: `app.set('views', './views')` + This defaults to the `views` directory in the application root directory. +- `view engine`, 사용할 템플리트 엔진. 예: `app.set('view engine', 'pug')` 이후 그에 맞는 템플리트 엔진 npm 패키지를 다음과 같이 설치하십시오. -
    -
    +```bash
     $ npm install pug --save
    -
    -
    +```
    Express와 호환되는 템플리트 엔진(예: Pug)은 `__express(filePath, options, callback)`라는 이름의 함수를 내보내며, 이 함수는 `res.render()` 함수에 의해 호출되어 템플리트 코드를 렌더링합니다. 일부 템플리트 엔진은 이러한 방식을 따르지 않습니다. [Consolidate.js](https://www.npmjs.org/package/consolidate) 라이브러리는 널리 이용되고 있는 모든 Node.js 템플리트 엔진을 맵핑함으로써 이러한 방식을 따르므로 Express 내에서 완벽하게 작동합니다. +
    보기 엔진을 설정한 후에는 앱에서 엔진을 지정하거나 템플리트 엔진 모듈을 로드할 필요가 없으며, Express는 아래에 표시된 것과 같이 내부적으로 모듈을 로드합니다(위의 예에 대한 코드). -
    -
    -app.set('view engine', 'pug');
    -
    -
    +```js +app.set('view engine', 'pug') +``` 다음의 내용이 입력된 `index.pug`라는 이름의 Pug 템플리트를 `views` 디렉토리에 작성하십시오. -
    -
    +```pug
     html
       head
         title= title
       body
         h1= message
    -
    -
    +``` 이후 `index.pug` 파일을 렌더링할 라우트를 작성하십시오. `view engine` 특성이 설정되어 있지 않은 경우에는 `view` 파일의 확장자를 지정해야 합니다. 해당 특성이 설정되어 있는 경우에는 확장자를 생략할 수 있습니다. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` 홈 페이지에 대한 요청을 실행할 때, `index.pug` 파일은 HTML 형식으로 렌더링됩니다. -Express에서 템플리트 엔진이 작동하는 방식에 대한 자세한 내용을 확인하려면 ["Express용 템플리트 엔진 개발"](/{{ page.lang }}/advanced/developing-template-engines.html)을 참조하십시오. +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/ko/guide/writing-middleware.md b/ko/guide/writing-middleware.md old mode 100755 new mode 100644 index 9e296f916b..b6ab5ed606 --- a/ko/guide/writing-middleware.md +++ b/ko/guide/writing-middleware.md @@ -1,33 +1,35 @@ --- layout: page title: Express 앱에서 사용하기 위한 미들웨어 작성 +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: ko +redirect_from: " " --- # Express 앱에서 사용하기 위한 미들웨어 작성

    개요

    -*미들웨어* 함수는 [요청 오브젝트](/{{ page.lang }}/4x/api.html#req)(`req`), [응답 오브젝트](/{{ page.lang }}/4x/api.html#res) (`res`), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 `next`라는 이름의 변수로 표시됩니다. +_미들웨어_ 함수는 [요청 오브젝트](/{{ page.lang }}/4x/api.html#req)(`req`), [응답 오브젝트](/{{ page.lang }}/4x/api.html#res) (`res`), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 `next`라는 이름의 변수로 표시됩니다. 미들웨어 함수는 다음과 같은 태스크를 수행할 수 있습니다. -* 모든 코드를 실행. -* 요청 및 응답 오브젝트에 대한 변경을 실행. -* 요청-응답 주기를 종료. -* 스택 내의 그 다음 미들웨어를 호출. +- 모든 코드를 실행. +- 요청 및 응답 오브젝트에 대한 변경을 실행. +- 요청-응답 주기를 종료. +- 스택 내의 그 다음 미들웨어를 호출. 현재의 미들웨어 함수가 요청-응답 주기를 종료하지 않는 경우에는 `next()`를 호출하여 그 다음 미들웨어 함수에 제어를 전달해야 합니다. 그렇지 않으면 해당 요청은 정지된 채로 방치됩니다. 다음 예시에 미들웨어 함수 호출의 요소가 표시되어 있습니다. +
    -
    미들웨어 함수가 적용되는 경로(라우트).
    @@ -40,62 +42,64 @@ lang: ko
    미들웨어 함수에 대한 HTTP 요청 인수(일반적으로 "req"라 불림).
    - +
    +Elements of a middleware function call -
    미들웨어 함수가 적용되는 HTTP 메소드.
    +
    미들웨어 함수가 적용되는 HTTP 메소드.
    +
    -아래에는 간단한 "Hello World" Express 애플리케이션에 대한 예가 표시되어 있으며, 이 애플리케이션을 위해 두 개의 미들웨어 함수를 정의하게 됩니다. +Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error. -
    -
    -var express = require('express');
    -var app = express();
    +

    Example

    + +아래에는 간단한 "Hello World" Express 애플리케이션에 대한 예가 표시되어 있으며, 이 애플리케이션을 위해 두 개의 미들웨어 함수를 정의하게 됩니다. +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. -app.get('/', function (req, res) { - res.send('Hello World!'); -}); +```js +const express = require('express') +const app = express() -app.listen(3000); -
    -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -

    개발

    +app.listen(3000) +``` +

    Middleware function myLogger

    아래에는 "myLogger"라는 이름의 미들웨어 함수에 대한 간단한 예가 표시되어 있습니다. 이 함수는 앱에 대한 요청이 해당 함수를 거쳐 전달될 때 단순히 "LOGGED"를 인쇄합니다. 이 미들웨어 함수는 `myLogger`라는 이름의 변수에 지정되어 있습니다. -
    -
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    -
    -
    +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
    -위의 예에서 `next()`에 대한 호출에 주목하십시오. 이 함수를 호출하면 앱 내의 그 다음 미들웨어 함수가 호출됩니다. -`next()` 함수는 Node.js 또는 Express API의 일부가 아니지만, 미들웨어 함수에 전달되는 세 번째 인수입니다. `next()` 함수에는 어떠한 이름을 지정해도 좋지만, 일반적으로 항상 "next"라는 이름을 갖습니다. 혼란을 방지하려면 항상 이러한 방식을 사용하십시오. +위의 예에서 `next()`에 대한 호출에 주목하십시오. 이 함수를 호출하면 앱 내의 그 다음 미들웨어 함수가 호출됩니다. +`next()` 함수는 Node.js 또는 Express API의 일부가 아니지만, 미들웨어 함수에 전달되는 세 번째 인수입니다. `next()` 함수에는 어떠한 이름을 지정해도 좋지만, 일반적으로 항상 "next"라는 이름을 갖습니다. +혼란을 방지하려면 항상 이러한 방식을 사용하십시오.
    미들웨어 함수를 로드하려면 미들웨어 함수를 지정하여 `app.use()`를 호출하십시오. 예를 들면, 다음의 코드는 루트 경로(/)로 라우팅하기 전에 `myLogger` 미들웨어 함수를 로드합니다. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    +const myLogger = function (req, res, next) {
    +  console.log('LOGGED')
    +  next()
    +}
     
    -app.use(myLogger);
    +app.use(myLogger)
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    +app.listen(3000) +``` 앱이 요청을 수신할 때마다, 앱은 "LOGGED"라는 메시지를 터미널에 인쇄합니다. @@ -105,43 +109,112 @@ app.listen(3000); 미들웨어 함수 `myLogger`는 단순히 메시지를 인쇄한 후 `next()` 함수를 호출하여 스택 내의 그 다음 미들웨어 함수에 요청을 전달합니다. +

    Middleware function requestTime

    + 다음 예에서는 `requestTime`라는 특성을 요청 오브젝트에 추가합니다. 이 미들웨어 함수는 "requestTime"이라고 명명하겠습니다. -
    -
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    -
    -
    +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` 이제 앱은 `requestTime` 미들웨어 함수를 사용합니다. 또한 루트 경로 라우트의 콜백 함수는 미들웨어 함수가 `req`(요청 오브젝트)에 추가하는 특성을 사용합니다. -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    +const requestTime = function (req, res, next) {
    +  req.requestTime = Date.now()
    +  next()
    +}
     
    -app.use(requestTime);
    +app.use(requestTime)
     
    -app.get('/', function (req, res) {
    -  var responseText = 'Hello World!
    '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) -app.listen(3000); -
    -
    +app.listen(3000) +``` 앱의 루트에 대한 요청을 실행할 때, 앱은 이제 요청의 타임스탬프를 브라우저에 표시합니다. +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    + 사용자는 요청 오브젝트, 응답 오브젝트, 스택 내의 그 다음 미들웨어 함수, 그리고 모든 Node.js API에 대한 액세스 권한을 가지고 있으므로, 미들웨어 함수에 대한 가능성은 끝이 없습니다. Express 미들웨어에 대한 자세한 정보는 [Express 미들웨어 사용](/{{ page.lang }}/guide/using-middleware.html)을 참조하십시오. + +

    Configurable middleware

    + +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. + +File: `my-middleware.js` + +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` + +The middleware can now be used as shown below. + +```js +const mw = require('./my-middleware.js') + +app.use(mw({ option1: '1', option2: '2' })) +``` + +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/ko/index.md b/ko/index.md index bbd36d7ff5..a63f85c861 100644 --- a/ko/index.md +++ b/ko/index.md @@ -1,44 +1,61 @@ --- layout: home -title: Express - Node.js 웹 애플리케이션 프레임워크 +title: Express - Node.js web application framework +description: "Express는 빠르고, 특정 방식에 얽매이지 않으며, 최소한의 구조를 지닌 Node.js용 웹 프레임워크로, 웹 및 모바일 애플리케이션을 위한 강력한 기능들을 제공합니다." menu: home -lang: ko +redirect_from: " " --- +
    - {% include header/header-{{ page.lang }}.html %} -
    - - Node.js를 위한 빠르고 개방적인 간결한 웹 프레임워크 + +

    Fast, unopinionated, minimalist web framework for Node.js

    -
    $ npm install express --save
    +
    $ npm install express --save
    +
    + +
    + +```javascript +const express = require('express') +const app = express() +const port = 3000 + +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` +
    - +{% endif %}
    -
    -

    웹 애플리케이션

    Express는 웹 및 모바일 애플리케이션을 위한 일련의 강력한 기능을 제공하는 간결하고 유연한 Node.js 웹 애플리케이션 프레임워크입니다. +

    Web Applications

    Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
    -
    -

    API

    자유롭게 활용할 수 있는 수많은 HTTP 유틸리티 메소드 및 미들웨어를 통해 쉽고 빠르게 강력한 API를 작성할 수 있습니다. +

    APIs

    With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy.
    -
    -

    성능

    Express는 기본적인 웹 애플리케이션 기능으로 구성된 얇은 계층을 제공하여, 여러분이 알고 있고 선호하는 Node.js 기능을 모호하게 만들지 않습니다. +

    Performance

    Express provides a thin layer of fundamental web application features, without obscuring Node.js features that you know and love.
    - -
    -

    Frameworks

    많은 유명한 프레임워크들이 Express를 기반으로 하고 있습니다. +
    +

    미들웨어

    + Express is a lightweight and flexible routing framework with minimal core features + meant to be augmented through the use of Express middleware modules.
    -
    diff --git a/ko/resources/community.md b/ko/resources/community.md old mode 100755 new mode 100644 index 5c847f423f..a7e7033409 --- a/ko/resources/community.md +++ b/ko/resources/community.md @@ -1,27 +1,59 @@ --- layout: page title: Express 커뮤니티 +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: ko +redirect_from: " " --- # 커뮤니티 -## 메일링 리스트 +## Technical committee -[Google Group](https://groups.google.com/group/express-js)에서 -2,000명 이상의 Express 사용자와 만나거나 5,000건 이상의 토론을 둘러보십시오. +The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, +and other issues relevant to the Express project. Each meeting is typically announced in an +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is +open to all observers. -## Gitter +The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -[expressjs/express chatroom](https://gitter.im/expressjs/express)은 Express와 관련된 -일상적인 토론에 관심이 있는 개발자들에게 매우 적합한 곳입니다. +Members of the Express technical committee are: -## IRC 채널 +**Active:** -매일 수백 명의 개발자들이 Freenode의 #express에서 시간을 보내고 있습니다. -프레임워크에 대한 질문이 있는 경우에는 채팅에 참여하여 -신속하게 피드백을 얻으십시오. +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida + +**Inactive:** + +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express is made of many modules + +활기찬 커뮤니티에서는 매우 다양한 확장기능, [미들웨어 모듈](/{{ page.lang }}/resources/middleware.html) +및 상위 레벨 프레임워크가 개발되어 왔습니다. + +Additionally, the Express community maintains modules in these two GitHub orgs: + +- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. + +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). + +## 문제 + +버그라고 생각되는 현상을 겪었거나, 기능에 대한 요청을 하기 원하는 경우에는 +[issue queue](https://github.com/expressjs/express/issues)에서 티켓을 작성하십시오. ## 예제 @@ -29,14 +61,32 @@ API 설계에서부터 인증 및 템플리트 엔진 통합에 이르는 모든 수십 개의 Express 애플리케이션 [예제](https://github.com/expressjs/express/tree/master/examples)를 확인하십시오. -## 문제 +## Github Discussions -버그라고 생각되는 현상을 겪었거나, 기능에 대한 요청을 하기 원하는 경우에는 -[issue queue](https://github.com/expressjs/express/issues)에서 티켓을 작성하십시오. +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. -## 써드파티 +# Branding of Express.js -활기찬 커뮤니티에서는 매우 다양한 확장기능, [미들웨어 모듈](/{{ page.lang }}/resources/middleware.html) -및 상위 레벨 프레임워크가 개발되어 왔습니다. [wiki](https://github.com/expressjs/express/wiki)에서 -이 모두를 확인해 보십시오. +## Express.js Logo + +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/ko/resources/contributing.md b/ko/resources/contributing.md new file mode 100644 index 0000000000..e37cee3122 --- /dev/null +++ b/ko/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/ko/resources/glossary.md b/ko/resources/glossary.md old mode 100755 new mode 100644 index fdbed40482..0c81a97d1b --- a/ko/resources/glossary.md +++ b/ko/resources/glossary.md @@ -1,56 +1,65 @@ --- layout: page title: Express 용어집 +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: ko +redirect_from: " " --- # 용어집 -### 라우터(router) +### 애플리케이션(application) -API 참조의 [라우터](/{{ page.lang }}/4x/api.html#router)를 참조하십시오. +일반적으로, 특정한 목적의 연산을 수행하도록 설계된 하나 이상의 프로그램입니다. Express의 컨텍스트에서는, Node.js 플랫폼에서 실행되며 Express API를 사용하는 프로그램을 말합니다. 또한 [앱 오브젝트](/{{ page.lang }}/api.html#express)를 지칭할 수도 있습니다. -### 라우트(route) +### API -자원을 식별하는 URL의 일부입니다. 예를 들면, `http://foo.com/products/id`에서 "/products/id"가 라우트입니다. +애플리케이션 프로그래밍 인터페이스(Application Programming Interface)입니다. 이 용어를 최초로 사용할 때는 약어를 풀어서 기재하십시오. -### 미들웨어(middleware) +### Express -최종 요청 핸들러 이전의 Express 라우팅 계층에 의해 호출되는 함수이며, 따라서 원시 요청과 의도된 최종 라우트 사이의 미들웨어에 위치합니다. 미들웨어와 관련된 용어의 몇 가지 요점은 다음과 같습니다. +Node.js 애플리케이션을 위한 빠르고 개방적인 간결한 웹 프레임워크입니다. 일반적으로 "Express.js"보다 "Express"가 선호되지만, "Express.js"도 허용됩니다. - * `var foo = require('middleware')`는 Node.js 모듈을 *요구* 또는 *사용*하는 것으로 일컬어집니다. 이후 `var mw = foo()` 명령문은 일반적으로 미들웨어를 리턴합니다. - * `app.use(mw)`는 *미들웨어를 전역 처리 스택에 추가*하는 것으로 일컬어집니다. - * `app.get('/foo', mw, function (req, res) { ... })`는 *미들웨어를 "GET /foo" 처리 스택에 추가*하는 것으로 일컬어집니다. +### libuv -### 애플리케이션(application) +비동기식 I/O에 초점을 둔 멀티플랫폼 지원 라이브러리이며, 주로 Node.js에 의해 사용되도록 개발됩니다. -일반적으로, 특정한 목적의 연산을 수행하도록 설계된 하나 이상의 프로그램입니다. Express의 컨텍스트에서는, Node.js 플랫폼에서 실행되며 Express API를 사용하는 프로그램을 말합니다. 또한 [앱 오브젝트](/{{ page.lang }}/api.html#express)를 지칭할 수도 있습니다. +### middleware + +최종 요청 핸들러 이전의 Express 라우팅 계층에 의해 호출되는 함수이며, 따라서 원시 요청과 의도된 최종 라우트 사이의 미들웨어에 위치합니다. 미들웨어와 관련된 용어의 몇 가지 요점은 다음과 같습니다. + +- `var foo = require('middleware')`는 Node.js 모듈을 _요구_ 또는 _사용_하는 것으로 일컬어집니다. 이후 `var mw = foo()` 명령문은 일반적으로 미들웨어를 리턴합니다. +- `app.use(mw)`는 _미들웨어를 전역 처리 스택에 추가_하는 것으로 일컬어집니다. +- `app.get('/foo', mw, function (req, res) { ... })`는 _미들웨어를 "GET /foo" 처리 스택에 추가_하는 것으로 일컬어집니다. + +### Node.js + +확장 가능한 네트워크 애플리케이션을 개발하는 데 사용되는 소프트웨어 플랫폼입니다. Node.js는 JavaScript를 스크립팅 언어로 사용하며, 방해하지 않는 I/O 및 단일 스레드 이벤트 루프를 통해 높은 처리량을 달성합니다. [nodejs.org](http://nodejs.org/)를 참조하십시오. **활용 참고**: 최초에는 "Node.js"였으며 이후 "Node"가 되었습니다. ### 오픈 소스(open-source, open source) -영문에서 형용사로 사용될 때는 하이픈이 사용됩니다. (예: "이 소프트웨어는 오픈 소스 소프트웨어입니다" [Wikipedia의 Open-source software](http://en.wikipedia.org/wiki/Open-source_software)를 참조하십시오.) 참고로 영문에서 이 용어에 하이픈이 사용되지 않는 경우가 흔하지만, 여기서는 합성 형용사에 하이픈을 추가하는 표준 영문 규칙을 사용합니다. +When used as an adjective, hyphenate; for example: "This is open-source software." (예: "이 소프트웨어는 오픈 소스 소프트웨어입니다" [Wikipedia의 Open-source software](http://en.wikipedia.org/wiki/Open-source_software)를 참조하십시오.) -### 요청(request) +{% capture english-rules %} -HTTP 요청입니다. 클라이언트는 HTTP 요청 메시지를 서버에 제출하며, 서버는 응답을 리턴합니다. 요청은 여러 [요청 메소드](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) 중 하나를 사용해야 합니다(예: GET, POST 등). +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. -### 응답(response) +{% endcapture %} -HTTP 응답입니다. 서버는 HTTP 응답 메시지를 클라이언트에 리턴합니다. 응답에는 요청에 대한 완료 상태 정보가 포함되어 있으며 응답 메시지 본문에는 요청된 컨텐츠가 포함되어 있을 수도 있습니다. +{% include admonitions/note.html content=english-rules %} -### API +### 요청(request) -애플리케이션 프로그래밍 인터페이스(Application Programming Interface)입니다. 이 용어를 최초로 사용할 때는 약어를 풀어서 기재하십시오. +HTTP 요청입니다. 클라이언트는 HTTP 요청 메시지를 서버에 제출하며, 서버는 응답을 리턴합니다. 요청은 여러 [요청 메소드](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) 중 하나를 사용해야 합니다(예: GET, POST 등). -### Express +### 응답(response) -Node.js 애플리케이션을 위한 빠르고 개방적인 간결한 웹 프레임워크입니다. 일반적으로 "Express.js"보다 "Express"가 선호되지만, "Express.js"도 허용됩니다. +HTTP 응답입니다. 서버는 HTTP 응답 메시지를 클라이언트에 리턴합니다. 응답에는 요청에 대한 완료 상태 정보가 포함되어 있으며 응답 메시지 본문에는 요청된 컨텐츠가 포함되어 있을 수도 있습니다. -### libuv +### 라우트(route) -비동기식 I/O에 초점을 둔 멀티플랫폼 지원 라이브러리이며, 주로 Node.js에 의해 사용되도록 개발됩니다. +자원을 식별하는 URL의 일부입니다. 예를 들면, `http://foo.com/products/id`에서 "/products/id"가 라우트입니다. -### Node.js +### 라우터(router) -확장 가능한 네트워크 애플리케이션을 개발하는 데 사용되는 소프트웨어 플랫폼입니다. Node.js는 JavaScript를 스크립팅 언어로 사용하며, 방해하지 않는 I/O 및 단일 스레드 이벤트 루프를 통해 높은 처리량을 달성합니다. [nodejs.org](http://nodejs.org/)를 참조하십시오. **활용 참고**: 최초에는 "Node.js"였으며 이후 "Node"가 되었습니다. +API 참조의 [라우터](/{{ page.lang }}/4x/api.html#router)를 참조하십시오. diff --git a/ko/resources/learning.md b/ko/resources/learning.md deleted file mode 100755 index bf6e24c57f..0000000000 --- a/ko/resources/learning.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: 추가 학습 -menu: resources -lang: ko ---- - -# 추가 학습 - -
    Disclaimer: Unendorsed community content.
    - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/ko/resources/middleware.md b/ko/resources/middleware.md old mode 100755 new mode 100644 index f56ab5266a..b079e6264a --- a/ko/resources/middleware.md +++ b/ko/resources/middleware.md @@ -1,9 +1,9 @@ --- -layout: page +layout: middleware title: Express 미들웨어 +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: ko -redirect_from: "/resources/middleware.html" +redirect_from: " " module: mw-home --- @@ -11,47 +11,33 @@ module: mw-home 목록에 적힌 Express 미들웨어 모듈들은 [Expressjs 팀](https://github.com/orgs/expressjs/people)이 유지보수합니다. -| 미들웨어 모듈 | 설명 | 내장 함수 (Express 3)| -|---------------------------|---------------------|----------------------| -| [body-parser](/resources/middleware/body-parser.html) | HTTP 요청 body를 파싱합니다. [body](https://github.com/raynos/body), [co-body](https://github.com/visionmedia/co-body), 그리고 [raw-body](https://github.com/stream-utils/raw-body)도 참고하세요. | express.bodyParser | -| [compression](/resources/middleware/compression.html) | HTTP 요청들을 압축합니다. | express.compress | -| [connect-rid](/resources/middleware/connect-rid.html) | 고유한 요청 ID를 생성합니다. | 없음 | -| [cookie-parser](/resources/middleware/cookie-parser.html) | 쿠키 헤더를 파싱하고 `req.cookies`에 할당합니다. [cookies](https://github.com/jed/cookies)와 [keygrip](https://github.com/jed/keygrip)도 참고하세요. | express.cookieParser | -| [cookie-session](/resources/middleware/cookie-session.html) | 쿠키 기반의 세션을 만듭니다. | express.cookieSession | -| [cors](/resources/middleware/cors.html) | 다양한 옵션들을 이용하여 Cross-origin resource sharing (CORS)를 활성화합니다. | 없음 | -| [csurf](/resources/middleware/csurf.html) | CSRF 취약점을 방어합니다. | express.csrf | -| [errorhandler](/resources/middleware/errorhandler.html) | 개발 중에 발생하는 에러를 핸들링하고 디버깅합니다. | express.errorHandler | -| [method-override](/resources/middleware/method-override.html) | 헤더를 이용해 HTTP method를 덮어씁니다. | express.methodOverride | -| [morgan](/resources/middleware/morgan.html) | HTTP 요청 로그를 남깁니다. | express.logger | -| [multer](/resources/middleware/multer.html) | multi-part 폼 데이터를 처리합니다. | express.bodyParser | -| [response-time](/resources/middleware/response-time.html) | 응답 시간을 기록합니다. | express.responseTime | -| [serve-favicon](/resources/middleware/serve-favicon.html) | 파비콘을 제공합니다. | express.favicon | -| [serve-index](/resources/middleware/serve-index.html) | 주어진 경로의 디렉토리 리스트를 제공합니다. | express.directory | -| [serve-static](/resources/middleware/serve-static.html) | 정적 파일을 제공합니다. | express.static | -| [session](/resources/middleware/session.html) | 서버 기반의 세션을 만듭니다 (개발 전용). | express.session | -| [timeout](/resources/middleware/timeout.html) | HTTP 요청 처리를 위해 timeout을 만듭니다. | express.timeout | -| [vhost](/resources/middleware/vhost.html) | 가상 도메인을 만듭니다. | express.vhost | +| 미들웨어 모듈 | 설명 | +| --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | HTTP 요청 body를 파싱합니다. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | HTTP 요청들을 압축합니다. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | 고유한 요청 ID를 생성합니다. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | 쿠키 헤더를 파싱하고 `req.cookies`에 할당합니다. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | 쿠키 기반의 세션을 만듭니다. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | 다양한 옵션들을 이용하여 Cross-origin resource sharing (CORS)를 활성화합니다. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | 개발 중에 발생하는 에러를 핸들링하고 디버깅합니다. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | 헤더를 이용해 HTTP method를 덮어씁니다. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP 요청 로그를 남깁니다. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | multi-part 폼 데이터를 처리합니다. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | 응답 시간을 기록합니다. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | 주어진 경로의 디렉토리 리스트를 제공합니다. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | 정적 파일을 제공합니다. | +| [session](/{{page.lang}}/resources/middleware/session.html) | 서버 기반의 세션을 만듭니다 (개발 전용). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | 가상 도메인을 만듭니다. | ## 추가 미들웨어 모듈 -몇몇 유명한 외부 미들웨어 모듈들입니다. +These are some additional popular middleware modules. {% include community-caveat.html %} -|미들웨어 모듈 | 설명 | -|---------------------------|---------------------| -| [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus) | 이미지 제공을 최적화힙니다. 할 수 있다면 이미지를 `.webp`나 `.jxr`로 바꿉니다. | -| [express-debug](https://github.com/devoidfury/express-debug) | 템플릿 변수 (지역), 현재 세션, 기타 등등에 대한 정보를 제공하는 개발 도구입니다. | -| [express-partial-response](https://github.com/nemtsov/express-partial-response) | JSON 응답을 URL의 `fields`를 받아서 필터링합니다. Google API의 Partial Response를 활용합니다. | -| [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn) | 정적 요소들을 위해 CDN을 사용하도록 도와줍니다. 다양한 호스트를 지원합니다. | -| [express-slash](https://github.com/ericf/express-slash) | 구현된 루터에 맟춰서 슬래쉬 유무를 맞춰줍니다. | -| [express-stormpath](https://github.com/stormpath/stormpath-express) | 사용자 저장소, 인증 확인, 인증, SSO, 그리고 데이터 보안에 관련된 모듈입니다. (Okta로 합쳐졌습니다) | -| [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize) | 대문자를 포함하는 HTTP 요청들을 표준 소문자 폼으로 리다이렉트시킵니다. containing uppercase to a canonical lowercase form. | -| [helmet](https://github.com/helmetjs/helmet) |다양한 HTTP 헤더를 설정해 앱이 안전하게 도와줍니다. | -| [join-io](https://github.com/coderaiser/join-io) | 요청 횟수를 줄이기 위해 파일들을 묶어줍니다. | -| [passport](https://github.com/jaredhanson/passport) | OAuth, OpenID 같은 방법들을 사용하는 인증 체계입니다. 자세한 정보는 [http://passportjs.org/](http://passportjs.org/)에서 확인하세요. | -| [static-expiry](https://github.com/paulwalker/connect-static-expiry) | 정적 에셋을 위해 헤더를 캐싱하거나 URL을 고유화합니다. | -| [view-helpers](https://github.com/madhums/node-view-helpers) | 뷰 엔진들을 위한 일반적인 도움을 제공합니다. | -| [sriracha-admin](https://github.com/hdngr/siracha) | 동적으로 Mongoose의 관리 사이트를 만듭니다. | - -[http-framework](https://github.com/Raynos/http-framework#modules)에서 더 많은 모듈들을 찾을 수 있습니다. +| 미들웨어 모듈 | 설명 | +| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet) | 다양한 HTTP 헤더를 설정해 앱이 안전하게 도와줍니다. | +| [passport](https://github.com/jaredhanson/passport) | OAuth, OpenID 같은 방법들을 사용하는 인증 체계입니다. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/ko/resources/middleware/body-parser.md b/ko/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/ko/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/ko/resources/middleware/compression.md b/ko/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/ko/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/ko/resources/middleware/connect-rid.md b/ko/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/ko/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/ko/resources/middleware/cookie-parser.md b/ko/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/ko/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/ko/resources/middleware/cookie-session.md b/ko/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/ko/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/ko/resources/middleware/cors.md b/ko/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/ko/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/ko/resources/middleware/errorhandler.md b/ko/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/ko/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/ko/resources/middleware/method-override.md b/ko/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/ko/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/ko/resources/middleware/morgan.md b/ko/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/ko/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/ko/resources/middleware/multer.md b/ko/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/ko/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/ko/resources/middleware/response-time.md b/ko/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/ko/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/ko/resources/middleware/serve-favicon.md b/ko/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/ko/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/ko/resources/middleware/serve-index.md b/ko/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/ko/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/ko/resources/middleware/serve-static.md b/ko/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/ko/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/ko/resources/middleware/session.md b/ko/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/ko/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/ko/resources/middleware/timeout.md b/ko/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/ko/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/ko/resources/middleware/vhost.md b/ko/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/ko/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/ko/resources/utils.md b/ko/resources/utils.md new file mode 100644 index 0000000000..424448498b --- /dev/null +++ b/ko/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/ko/starter/basic-routing.md b/ko/starter/basic-routing.md old mode 100755 new mode 100644 index 86b54b40d5..abeb759f89 --- a/ko/starter/basic-routing.md +++ b/ko/starter/basic-routing.md @@ -1,22 +1,22 @@ --- layout: page title: Express 기본 라우팅 +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: ko +redirect_from: " " --- # 기본 라우팅 -*라우팅*은 URI(또는 경로) 및 특정한 HTTP 요청 메소드(GET, POST 등)인 특정 엔드포인트에 대한 클라이언트 요청에 애플리케이션이 응답하는 방법을 결정하는 것을 말합니다. +_라우팅_은 URI(또는 경로) 및 특정한 HTTP 요청 메소드(GET, POST 등)인 특정 엔드포인트에 대한 클라이언트 요청에 애플리케이션이 응답하는 방법을 결정하는 것을 말합니다. 각 라우트는 하나 이상의 핸들러 함수를 가질 수 있으며, 이러한 함수는 라우트가 일치할 때 실행됩니다. 라우트 정의에는 다음과 같은 구조가 필요합니다. -
    -
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` 여기서, @@ -33,42 +33,36 @@ app.METHOD(PATH, HANDLER) 홈 페이지에서 `Hello World!`로 응답: -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -애플리케이션의 홈 페이지인 루트 라우트(`/`)에서 POST 요청에 응답: +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` `/user` 라우트에 대한 PUT 요청에 응답: -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` `/user` 라우트에 대한 DELETE 요청에 응답: -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` 라우팅에 대한 자세한 내용을 확인하려면 [라우팅 안내서](/{{ page.lang }}/guide/routing.html)를 참조하십시오. + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/ko/starter/examples.md b/ko/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/ko/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/ko/starter/faq.md b/ko/starter/faq.md old mode 100755 new mode 100644 index 6e8c9dfc92..b7c54f7172 --- a/ko/starter/faq.md +++ b/ko/starter/faq.md @@ -1,8 +1,9 @@ --- layout: page title: Express 자주 묻는 질문(FAQ) +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: ko +redirect_from: " " --- # 자주 묻는 질문(FAQ) @@ -17,13 +18,13 @@ lang: ko 선호하는 모든 디렉토리 구조에 존재할 수 있습니다. 도움을 받으려면 다음의 예를 확인하십시오. -* [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc) +- [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc) 또한, 이러한 패턴을 간략화할 수 있는 다음과 같은 Express용 써드파티 확장기능이 존재합니다. -* [Resourceful routing](https://github.com/expressjs/express-resource) +- [Resourceful routing](https://github.com/expressjs/express-resource) ## 모델을 어떻게 정의해야 합니까? @@ -36,10 +37,9 @@ Express에는 데이터베이스의 개념이 없습니다. 이러한 개념은 ## 어떻게 사용자를 인증할 수 있습니까? 인증은 또 다른 주관적인 영역이며, Express는 -이에 관여하지 않습니다. 개발자는 자신이 원하는 어떠한 인증 체계라도 사용할 수 있습니다. +이에 관여하지 않습니다. 개발자는 자신이 원하는 어떠한 인증 체계라도 사용할 수 있습니다. 사용자 이름 / 비밀번호 체계에 대해서는 [이 예제](https://github.com/expressjs/express/tree/master/examples/auth)를 참조하십시오. - ## Express는 어느 템플리트 엔진을 지원합니까? Express는 `(path, locals, callback)` 시그니처를 준수하는 모든 템플리트 엔진을 지원합니다. @@ -47,6 +47,8 @@ Express는 `(path, locals, callback)` 시그니처를 준수하는 모든 템플 [consolidate.js](https://github.com/visionmedia/consolidate.js) 프로젝트를 참조하여 지원을 받으십시오. 목록에 포함되지 않은 템플리트 엔진이 Express 시그니처를 지원할 수도 있습니다. +For more information, see [Using template engines with Express](/{{page.lang}}/guide/using-template-engines.html). + ## 404 응답을 어떻게 처리해야 합니까? Express에서 404 응답은 오류로 인해 발생하는 결과가 아니며, 따라서 @@ -57,27 +59,26 @@ Express에서 404 응답은 오류로 인해 발생하는 결과가 아니며, 다음과 같이 404 응답을 처리하기 위한 미들웨어 함수를 스택의 가장 아래(다른 모든 함수의 아래)에 추가하기만 하면 됩니다. -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` + +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## 오류 핸들러를 어떻게 설정해야 합니까? 오류 처리 미들웨어는 다른 미들웨어와 동일한 방식으로 정의할 수 있지만, 다음과 같이 오류 처리 함수는 3개가 아닌 4개의 인수, 구체적으로 말하면 `(err, req, res, next)` 시그니처를 갖는다는 점이 다릅니다. -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` 자세한 정보는 [오류 처리](/{{ page.lang }}/guide/error-handling.html)를 참조하십시오. @@ -87,3 +88,10 @@ app.use(function(err, req, res, next) { 특정한 파일을 렌더링해야 하는 경우에는 `res.sendFile()` 함수를 사용하십시오. 하나의 디렉토리에서 여러 자산을 제공하는 경우에는 `express.static()` 미들웨어 함수를 사용하십시오. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/ko/starter/generator.md b/ko/starter/generator.md old mode 100755 new mode 100644 index e8d4cee7ab..1961b4da57 --- a/ko/starter/generator.md +++ b/ko/starter/generator.md @@ -1,29 +1,34 @@ --- layout: page title: Express 애플리케이션 생성기 +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: ko +redirect_from: " " --- # Express 애플리케이션 생성기 애플리케이션의 골격을 신속하게 작성하려면 애플리케이션 생성기 도구인 `express`를 사용하십시오. -다음의 명령을 이용해 `express`를 설치하십시오. +You can run the application generator with the `npx` command (available in Node.js 8.2.0). + +```bash +$ npx express-generator +``` -
    -
    -$ npm install express-generator -g
    -
    -
    +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` 다음과 같이 `-h` 옵션을 이용해 명령의 옵션을 표시하십시오. -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -34,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` -예를 들면, 다음의 예에서는 _myapp_라는 이름의 Express 앱을 현재 작업 디렉토리에 작성합니다. +예를 들면, 다음의 예에서는 _myapp_라는 이름의 Express 앱을 현재 작업 디렉토리에 작성합니다. The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -64,40 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` 이후 다음과 같이 종속 항목을 설치하십시오. -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` MacOS 또는 Linux에서는 다음 명령을 사용하여 앱을 실행하십시오. -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` Windows에서는 다음 명령을 사용하십시오. -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` + +다음의 명령을 이용해 `express`를 설치하십시오. + +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` 이후 브라우저에서 `http://localhost:3000/`을 로드하여 앱에 액세스하십시오. 생성된 앱은 다음과 같은 디렉토리 구조를 갖습니다. -
    -
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -117,9 +118,10 @@ Windows에서는 다음 명령을 사용하십시오.
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    생성기에 의해 작성된 앱 구조는 Express 앱을 구조화하는 여러 방법 중 하나에 불과합니다. 이러한 구조를 사용하거나 사용자의 요구사항에 가장 적합하도록 구조를 수정하십시오.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/ko/starter/hello-world.md b/ko/starter/hello-world.md old mode 100755 new mode 100644 index be0b28db46..c66293ba50 --- a/ko/starter/hello-world.md +++ b/ko/starter/hello-world.md @@ -1,8 +1,9 @@ --- layout: page title: Express "Hello World" 예제 +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: ko +redirect_from: " " --- # Hello world 예제 @@ -11,12 +12,7 @@ lang: ko 기본적으로 이 앱은 여러분이 작성할 수 있는 가장 간단한 Express 앱일 것입니다. 이 앱은 하나의 파일로 된 앱이며 [Express 생성기](/{{ page.lang }}/starter/generator.html)를 통해 얻게 되는 앱과는 같지 *않습니다*. (이 예제와 달리 Express 생성기를 통해 얻게 되는 앱은 다양한 목적을 위한 여러 JavaScript 파일, Jade 템플리트 및 하위 디렉토리를 포함하는 전체 앱에 대한 스캐폴딩을 작성합니다.)
    -먼저, `myapp`이라는 이름의 디렉토리를 작성한 후 이 디렉토리로 이동하여 `npm init`를 실행하십시오. 이후 [설치 안내서](/{{ page.lang }}/starter/installing.html)에 따라 `express`를 종속 항목으로서 설치하십시오. - -`myapp` 디렉토리에 `app.js`라는 이름의 파일을 작성한 후 다음과 같은 코드를 추가하십시오. - -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -26,13 +22,19 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    +``` -앱은 서버를 시작하며 3000번 포트에서 연결을 청취합니다. 앱은 루트 URL(`/`) 또는 *라우트*에 +앱은 서버를 시작하며 3000번 포트에서 연결을 청취합니다. 앱은 루트 URL(`/`) 또는 _라우트_에 대한 요청에 "Hello World!"로 응답합니다. 다른 모든 경로에 대해서는 **404 Not Found**로 응답합니다. +### Running Locally + +먼저, `myapp`이라는 이름의 디렉토리를 작성한 후 이 디렉토리로 이동하여 `npm init`를 실행하십시오. 이후 [설치 안내서](/{{ page.lang }}/starter/installing.html)에 따라 `express`를 종속 항목으로서 설치하십시오. + +`myapp` 디렉토리에 `app.js`라는 이름의 파일을 작성한 후 다음과 같은 코드를 추가하십시오. +
    `req`(요청) 및 `res`(응답)는 Node가 제공하는 동일한 오브젝트이며, 따라서 `req.pipe()`, `req.on('data', callback)` 그리고 Express의 관여가 필요 없는 다른 모든 항목을 호출할 수 있습니다. @@ -40,11 +42,10 @@ app.listen(port, () => { 다음의 명령을 이용하여 앱을 실행하십시오. -
    -
    +```bash
     $ node app.js
    -
    -
    +``` 이후 브라우저에서 [http://localhost:3000/](http://localhost:3000/)을 로드하여 결과물을 확인하십시오. +### [Previous: Installing ](/{{ page.lang }}/starter/installing.html)    [Next: Express Generator ](/{{ page.lang }}/starter/generator.html) diff --git a/ko/starter/installing.md b/ko/starter/installing.md old mode 100755 new mode 100644 index d44435b5d5..792b530ddd --- a/ko/starter/installing.md +++ b/ko/starter/installing.md @@ -1,58 +1,53 @@ --- layout: page title: Express 설치 +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: ko +redirect_from: " " --- # 설치 [Node.js](https://nodejs.org/)가 이미 설치되었다고 가정한 상태에서, 애플리케이션을 보관할 디렉토리를 작성하고 그 디렉토리를 작업 디렉토리로 설정하십시오. -
    -
    +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher.
    +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher.
    +
    +```bash
     $ mkdir myapp
     $ cd myapp
    -
    -
    +``` `npm init` 명령을 이용하여 애플리케이션에 대한 `package.json` 파일을 작성하십시오. `package.json`의 작동 원리에 대한 자세한 정보는 [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json)을 참조하십시오. -
    -
    +```bash
     $ npm init
    -
    -
    +``` 이 명령을 실행하면 애플리케이션의 이름 및 버전과 같은 몇 가지 정보에 대해 프롬프트합니다. 지금은 다음의 항목을 제외한 대부분의 항목에서 ENTER 키를 눌러 기본값을 수락할 수 있습니다. -
    -
    +```
     entry point: (index.js)
    -
    -
    +``` 기본 파일의 이름을 `app.js`로 입력하거나 자유롭게 입력하십시오. 기본 파일의 이름을 `index.js`로 입력하기 원하는 경우에는 ENTER 키를 눌러 제안된 기본 파일 이름을 수락하십시오. 이제 `myapp` 디렉토리에 Express를 설치한 후 종속 항목 목록에 저장하십시오. 예를 들면 다음과 같습니다. -
    -
    -$ npm install express --save
    -
    -
    +```bash +$ npm install express +``` Express를 임시로 설치하고 종속 항목 목록에 추가하지 않으려면, 다음과 같이 `--save` 옵션을 생략하십시오. -
    -
    -$ npm install express
    -
    -
    +```bash +$ npm install express --no-save +```
    -`--save` 옵션을 통해 설치된 Node 모듈은 `package.json` 파일 내의 `dependencies` 목록에 추가됩니다. -이후 `app` 디렉토리에서 `npm install`을 실행하면 종속 항목 목록 내의 모듈이 자동으로 설치됩니다. +`--save` 옵션을 통해 설치된 Node 모듈은 `package.json` 파일 내의 `dependencies` 목록에 추가됩니다. 이후 `app` 디렉토리에서 `npm install`을 실행하면 종속 항목 목록 내의 모듈이 자동으로 설치됩니다.
    + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/ko/starter/static-files.md b/ko/starter/static-files.md old mode 100755 new mode 100644 index b5c7437261..dc872597e8 --- a/ko/starter/static-files.md +++ b/ko/starter/static-files.md @@ -1,33 +1,39 @@ --- layout: page title: Express에서 정적 파일 제공 +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: ko +redirect_from: " " --- # Express에서 정적 파일 제공 이미지, CSS 파일 및 JavaScript 파일과 같은 정적 파일을 제공하려면 Express의 기본 제공 미들웨어 함수인 `express.static`을 사용하십시오. -정적 자산이 포함된 디렉토리의 이름을 `express.static` 미들웨어 함수에 전달하면 파일의 직접적인 제공을 시작할 수 있습니다. 예를 들면, 다음과 같은 코드를 이용하여 `public`이라는 이름의 디렉토리에 포함된 이미지, CSS 파일 및 JavaScript 파일을 제공하십시오. +The function signature is: -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +예를 들면, 다음과 같은 코드를 이용하여 `public`이라는 이름의 디렉토리에 포함된 이미지, CSS 파일 및 JavaScript 파일을 제공하십시오. + +```js +app.use(express.static('public')) +``` 이제 다음과 같이 `public` 디렉토리에 포함된 파일을 로드할 수 있습니다. -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +```
    Express는 정적 디렉토리에 대해 상대적으로 파일을 검색하며, 따라서 정적 디렉토리의 이름은 URL의 일부가 아닙니다. @@ -35,39 +41,41 @@ Express는 정적 디렉토리에 대해 상대적으로 파일을 검색하며, 여러 개의 정적 자산 디렉토리를 이용하려면 다음과 같이 `express.static` 미들웨어 함수를 여러 번 호출하십시오. -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` Express는 `express.static` 미들웨어 함수를 이용해 정적 디렉토리를 설정한 순서대로 파일을 검색합니다. -`express.static` 함수를 통해 제공되는 파일에 대한 가상 경로 접두부(파일 시스템 내에 해당 경로가 실제로 존재하지 않는 경우)를 작성하려면, 아래에 표시된 것과 같이 정적 디렉토리에 대한 [마운트 경로를 지정](/{{ page.lang }}/4x/api.html#app.use)하십시오. +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` 이제 `/static` 경로 접두부를 통해 `public` 디렉토리에 포함된 파일을 로드할 수 있습니다. -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` 그러나 `express.static` 함수에 제공되는 경로는 `node` 프로세스가 실행되는 디렉토리에 대해 상대적입니다. Express 앱을 다른 디렉토리에서 실행하는 경우에는 다음과 같이 제공하기 원하는 디렉토리의 절대 경로를 사용하는 것이 더 안전합니다. -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +```js +const path = require('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.html). + +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/ko/support/index.md b/ko/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/ko/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..60dc84d15e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3529 @@ +{ + "name": "expressjs.com", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "expressjs.com", + "version": "0.0.0", + "devDependencies": { + "eslint": "^8.54.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-markdown": "^2.2.1", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.6.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/builtins": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-standard": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", + "eslint-plugin-promise": "^6.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-markdown": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-2.2.1.tgz", + "integrity": "sha512-FgWp4iyYvTFxPwfbxofTvXxgzPsDuSKHQy2S+a8Ve6savbujey+lgrFFbXQA0HPygISpRYWYBjooPzhYSF81iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^0.8.5" + }, + "engines": { + "node": "^8.10.0 || ^10.12.0 || >= 12.0.0" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-n": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz", + "integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtins": "^5.0.1", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.11.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", + "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 5b75c0e4cf..eebc645804 100644 --- a/package.json +++ b/package.json @@ -6,13 +6,12 @@ "test": "eslint --ignore-path .gitignore --ignore-pattern _includes/readmes/ \"**/*.md\"" }, "devDependencies": { - "eslint": "^7.32.0", - "eslint-config-standard": "^14.1.1", - "eslint-plugin-import": "^2.25.2", + "eslint": "^8.54.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-markdown": "^2.2.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.1.0", - "eslint-plugin-standard": "^4.1.0" + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.6.0" }, "eslintConfig": { "extends": [ @@ -30,7 +29,25 @@ { "files": "**/*.md/*.js", "rules": { - "handle-callback-err": "off" + "array-callback-return": "off", + "no-var": "error", + "n/handle-callback-err": "off", + "object-shorthand": "error", + "prefer-arrow-callback": "error", + "prefer-template": "error" + } + }, + { + "files": [ + "**/3x/*.md/*.js", + "**/4x/*.md/*.js", + "**/guide/migrating-4.md/*.js" + ], + "rules": { + "no-var": "off", + "object-shorthand": "off", + "prefer-arrow-callback": "off", + "prefer-template": "off" } } ] diff --git a/pt-br/3x/api.md b/pt-br/3x/api.md index ee71dabfa0..e7d0273c41 100644 --- a/pt-br/3x/api.md +++ b/pt-br/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - API Reference +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: pt-br +redirect_from: " " --- +
    **Express 3.x support is ending soon** - This series will continue to receive only security updates and bug fixes until July 2015. It is highly recommended to upgrade to Express 4.x. -
    - -

    3.x API

    +This series will continue to receive only security updates and bug fixes until July 2015. It is highly recommended to upgrade to Express 4.x. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
    - - {% include api/en/3x/res.md %} +

    3.x API

    - - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %}
    diff --git a/pt-br/4x/api.md b/pt-br/4x/api.md index 4a15dda1ad..7adeb1cdf1 100644 --- a/pt-br/4x/api.md +++ b/pt-br/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api -title: Express 4.x - Referência da API +layout: api +version: 4x +title: Express 4.x - Referência de API +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: pt-br +redirect_from: " " --- +
    -

    4.x API

    +

    API 4.x

    - - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
    diff --git a/pt-br/5x/api.md b/pt-br/5x/api.md new file mode 100644 index 0000000000..bcb1fdb6b0 --- /dev/null +++ b/pt-br/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - Referência da API +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
    + +

    5.x API

    + +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
    diff --git a/pt-br/advanced/best-practice-performance.md b/pt-br/advanced/best-practice-performance.md old mode 100755 new mode 100644 index a369a893ac..e4aae98528 --- a/pt-br/advanced/best-practice-performance.md +++ b/pt-br/advanced/best-practice-performance.md @@ -1,49 +1,58 @@ --- layout: page title: Melhores Práticas de Desempenho Usando o Express em Produção +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: pt-br +redirect_from: " " --- # Melhores Práticas de Produção: desempenho e confiabilidade -## Visão Geral - Este artigo discute as melhores práticas de desempenho e de confiabilidade para aplicativos Express implementados para produção. Este tópico se enquadra claramente no mundo de "devops", abordando o desenvolvimento tradicional e as operações. Assim, as informações são divididas em duas partes: -* [Itens a fazer no seu código](#code) (a parte do dev). -* [Itens a fazer no seu ambiente / configuração](#env) (a parte de ops). - - +- [Itens a fazer no seu código](#code) (a parte do dev). + - Use a compactação gzip + - Não use funções síncronas + - Faça o registro de logs corretamente + - [Handle exceptions properly](#handle-exceptions-properly) +- [Itens a fazer no seu ambiente / configuração](#env) (a parte de ops). + - Configure o NODE_ENV para "produção" + - Executar o seu aplicativo (e Node) diretamente com o sistema + de inicialização. Isto é de certa forma mais simples, mas você não + obtém as vantagens adicionais do uso de um gerenciador de processos. + - Execute seu aplicativo em um cluster + - + - Use um balanceador de carga + - Use um proxy reverso ## Itens a fazer no seu código A seguir serão apresentados alguns itens que podem ser feitos no seu código para melhorar o desempenho dos aplicativos: -* Use a compactação gzip -* Não use funções síncronas -* Use o middleware para entregar arquivos estáticos -* Faça o registro de logs corretamente -* Lide com exceções adequadamente +- Use a compactação gzip +- Não use funções síncronas +- Faça o registro de logs corretamente +- [Handle exceptions properly](#handle-exceptions-properly) ### Use a compactação gzip A compactação Gzip pode diminuir bastante o tamanho do corpo de resposta e assim aumentar a velocidade de um aplicativo da web. Use o middleware [compression](https://www.npmjs.com/package/compression) para fazer a compactação gzip no seu aplicativo do Express. Por exemplo: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` Para um website com tráfego intenso na produção, a melhor maneira de colocar a compactação em prática, é implementá-la em um -nível de proxy reverso (consulte [Use um proxy reverso](#proxy)). Neste caso, não é necessário usar o middleware de compactação. Para obter detalhes sobre a ativação da compactação gzip no Nginx, consulte o [Módulo -ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html) na documentação do Nginx. +nível de proxy reverso (consulte [Use um proxy reverso](#proxy)). Neste caso, não é necessário usar o middleware de compactação. Para obter detalhes sobre a ativação da compactação gzip no Nginx, consulte o Módulo +ngx_http_gzip_module na documentação do Nginx. ### Não use funções síncronas @@ -54,32 +63,16 @@ aplicativo. Evite o uso delas na produção. Apesar de o Node e muitos módulos fornecerem versões síncronas e assíncronas de suas funções, sempre use as versões assíncronas na produção. O único momento em que o uso de uma função síncrona pode ser justificado é na primeira inicialização. -Se estiver usando o Node.js 4.0+ ou o io.js 2.1.0+, é possível usar a sinalização `--trace-sync-io` da linha de comandos para imprimir um aviso e um rastreio de pilha sempre que o seu aplicativo usar uma API síncrona. Obviamente, não seria desejado usar isto na produção, mas sim antes, para garantir que seu código está pronto para produção. Consulte a [Atualização -semanal para o io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0) para obter mais informações. - -### Use o middleware para entregar arquivos estáticos - -No desenvolvimento, é possível usar a [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) para entregar arquivos estáticos. Mas -não use isto na produção, pois esta função precisa ser lida a partir -do sistema de arquivos para cada solicitação de arquivo, e portanto -encontraria latência e afetaria o desempenho geral do aplicativo. Observe que a `res.sendFile()` *não* é implementada com a chamada de sistema [sendfile](http://linux.die.net/man/2/sendfile) o que a tornaria muito mais eficiente. - -Ao invés disso, use o middleware [serve-static](https://www.npmjs.com/package/serve-static) -(ou algo equivalente), que é otimizado para a entrega de arquivos para os aplicativos do Express. - -Uma opção ainda melhor é usar um proxy reverso para entregar -arquivos estáticos; consulte [Use um proxy -reverso](#proxy) para obter mais informações. +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. Obviamente, não seria desejado usar isto na produção, mas sim antes, para garantir que seu código está pronto para produção. Consulte a Atualização +semanal para o io.js 2.1.0 para obter mais informações. -### Faça o registro de logs corretamente +### Lide com exceções adequadamente Em geral, existem duas razões para registrar logs em seu aplicativo: Para depuração e para registro de logs de atividade do aplicativo (essencialmente, todo o resto). Usar o `console.log()` ou o `console.err()` para imprimir mensagens de log no -terminal é uma prática comum em desenvolvimento. Mas [essas -funções são síncronas](https://nodejs.org/api/console.html#console_console_1) quando o destino é um terminal ou um arquivo, portanto elas não são adequadas para produção, a não ser que -a saída seja canalizada para outro programa. +terminal é uma prática comum em desenvolvimento. 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. -#### Para depuração +#### For debugging Se estiver registrando logs com o propósito de depuração, então ao invés de usar o `console.log()`, use um módulo especial para depuração como o [debug](https://www.npmjs.com/package/debug). Este @@ -89,14 +82,7 @@ módulo permite que seja usada a variável de ambiente DEBUG para controlar quai #### Para atividade do aplicativo -Se estiver registrando logs de atividade do aplicativo (por -exemplo, rastreamento de tráfico ou chamadas de API), ao invés de -usar o `console.log()`, use uma biblioteca de -registro de logs como [Winston](https://www.npmjs.com/package/winston) ou [Bunyan](https://www.npmjs.com/package/bunyan). Para -obter uma comparação detalhada dessas duas bibliotecas, consulte a postagem do blog do StrongLoop -[Comparando o registro de logs no Node.js usando Winston e Bunyan](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - - +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. ### Lide com exceções adequadamente @@ -110,8 +96,8 @@ necessário tratar exceções adequadamente. Para garantir que está tratando todas as exceções, use as seguintes técnicas: -* [Use try-catch](#try-catch) -* [Use promessas](#promises) +- [Use try-catch](#try-catch) +- [Use promessas](#promises) Antes de se aprofundar nestes tópicos, você deveria ter um entendimento básico de manipulação de erros do Node/Express: usando @@ -122,38 +108,12 @@ convenção de retorno de chamada erros-first para tratar o erro de forma signif Para obter mais informações sobre os fundamentos de manipulação de erros, consulte: -* [Manipulação de Erros no Node.js](https://www.joyent.com/developers/node/design/errors) -* [Construindo -Aplicativos Node Robustos: Manipulação de Erros](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (blog do StrongLoop) - -#### O que não fazer - -Uma coisa que *não* deveria fazer é escutar a eventos `uncaughtException`, emitidos quando uma exceção -emerge regressando ao loop de eventos. Incluir um listener de eventos para `uncaughtException` irá mudar o comportamento -padrão do processo que está encontrando uma exceção; o processo irá continuar a execução apesar da exceção. Essa pode parecer como uma boa maneira de prevenir que o seu -aplicativo caia, mas continuar a execução do aplicativo após uma -exceção não capturada é uma prática perigosa e não é recomendada, porque o estado do processo se torna não confiável e imprevisível. - -Adicionalmente, usar o `uncaughtException` é oficialmente reconhecido como [grosseiro](https://nodejs.org/api/process.html#process_event_uncaughtexception) -e existe uma [proposta](https://github.com/nodejs/node-v0.x-archive/issues/2582) -de removê-lo do núcleo. Portando escutar por um `uncaughtException` é simplesmente uma má ideia. É -por isso que recomendamos coisas como múltiplos processos e -supervisores: o processo de queda e reinicialização é frequentemente a -forma mais confiável de se recuperar de um erro. - -Também não recomendamos o uso de [domínios](https://nodejs.org/api/domain.html). Ele -geralmente não resolve o problema e é um módulo descontinuado. - - +- [Manipulação de Erros no Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### Use try-catch Try-catch é uma construção da linguagem JavaScript que pode ser usada para capturar exceções em um código síncrono. Use try-catch, por exemplo, para tratar erros de análise sintática de JSON como mostrado abaixo. -Use uma ferramenta como o [JSHint](http://jshint.com/) ou o -[JSLint](http://www.jslint.com/) para ajudá-lo a localizar exceções implícitas como -[erros de referência em variáveis indefinidas](http://www.jshint.com/docs/options/#undef). - Aqui está um exemplo de uso de try-catch para tratar uma potencial exceção causadora de queda de processo. Esta função middleware aceita um parâmetro de campo de consulta chamado "params" que é um objeto JSON. @@ -162,9 +122,9 @@ Esta função middleware aceita um parâmetro de campo de consulta chamado "para app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -177,120 +137,93 @@ Entretanto, o try-catch funciona apenas para códigos síncronos. Como a plataforma Node é a princípio assíncrona (particularmente em um ambiente de produção), o try-catch deixará de capturar muitas exceções. - - #### Use promessas -Promessas irão tratar quaisquer exceções (ambas explícitas e implícitas) em blocos de códigos assíncronos que usem -`then()`. Apenas inclua `.catch(next)` no final da cadeia de promessas. Por exemplo: +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -Agora todos os erros assíncronos e síncronos são propagados para o middleware de erros. - -Entretanto, existem dois alertas: - -1. Todo seu código assíncrono deve retornar promessas (exceto -emissores). Se uma biblioteca em particular não retornar promessas, -converta o objeto base através do uso de uma função auxiliar como -[Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Emissores de eventos (como fluxos) podem ainda causar -exceções não capturadas. Portanto certifique-se de que está tratando -o evento de erro apropriadamente; por exemplo: +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -Para obter mais informações sobre o manipulação de erros usando -promessas, consulte: +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. + +#### O que não fazer + +Uma coisa que _não_ deveria fazer é escutar a eventos `uncaughtException`, emitidos quando uma exceção +emerge regressando ao loop de eventos. Incluir um listener de eventos para `uncaughtException` irá mudar o comportamento +padrão do processo que está encontrando uma exceção; o processo irá continuar a execução apesar da exceção. Essa pode parecer como uma boa maneira de prevenir que o seu +aplicativo caia, mas continuar a execução do aplicativo após uma +exceção não capturada é uma prática perigosa e não é recomendada, porque o estado do processo se torna não confiável e imprevisível. -* [Manipulando Erros -Assíncronos no Express com Promessas, Geradores e ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promessas no Node.js com o Q – Uma Alternativa a Retornos de Chamada](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +Adicionalmente, usar o `uncaughtException` é oficialmente reconhecido como [grosseiro](https://nodejs.org/api/process.html#process_event_uncaughtexception) +e existe uma [proposta](https://github.com/nodejs/node-v0.x-archive/issues/2582) +de removê-lo do núcleo. Portando escutar por um `uncaughtException` é simplesmente uma má ideia. É +por isso que recomendamos coisas como múltiplos processos e +supervisores: o processo de queda e reinicialização é frequentemente a +forma mais confiável de se recuperar de um erro. - +Também não recomendamos o uso de [domínios](https://nodejs.org/api/domain.html). Ele +geralmente não resolve o problema e é um módulo descontinuado. ## Coisa a se fazer no seu ambiente / configuração A seguir serão apresentados alguns itens que podem ser feitos no seu ambiente de sistema para melhorar o desempenho dos seus aplicativos: -* Configure o NODE_ENV para "produção" -* Assegure que o seu aplicativo reinicie automaticamente -* Execute seu aplicativo em um cluster -* Armazene em cache os resultados das solicitações -* Use um balanceador de carga -* Use um proxy reverso +- Configure o NODE_ENV para "produção" +- Executar o seu aplicativo (e Node) diretamente com o sistema + de inicialização. Isto é de certa forma mais simples, mas você não + obtém as vantagens adicionais do uso de um gerenciador de processos. +- Execute seu aplicativo em um cluster +- +- Use um balanceador de carga +- Use um proxy reverso ### Configure o NODE_ENV para "produção" A variável de ambiente NODE_ENV especifica o ambiente no qual um aplicativo está executando (geralmente, desenvolvimento ou -produção). Uma das coisas mais simples que podem ser feitas para -melhorar o desempenho é configurar NODE_ENV para "produção". +produção). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. Configurando NODE_ENV para "produção" faz com que o Express: -* Armazene em Cache os modelos de visualização. -* Armazene em Cache arquivos CSS gerados a partir de extensões CSS. -* Gere menos mensagens de erro detalhadas +- Armazene em Cache os modelos de visualização. +- Armazene em Cache arquivos CSS gerados a partir de extensões CSS. +- Gere menos mensagens de erro detalhadas -[Testes -indicam](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) que apenas fazendo isso pode melhorar o desempenho por um fator de três! +[Tests indicate](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! Se precisar escrever código específico por ambiente, é possível verificar o valor de NODE_ENV com `process.env.NODE_ENV`. Esteja ciente de que verificar o valor de qualquer variável de ambiente incorre em perda de desempenho, e por isso deve ser feito raramente. Em desenvolvimento, você tipicamente configura variáveis de ambiente no seu shell interativo, por exemplo, usando o -`export` ou o seu arquivo `.bash_profile`. Mas -em geral você não deveria fazer isto em um servidor de produção; ao invés disso, use o sistema de inicialização do seu sistema -operacional (systemd ou Upstart). A próxima seção fornece mais detalhes sobre a utilização do seu sistema de inicialização em geral, +`export` ou o seu arquivo `.bash_profile`. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). A próxima seção fornece mais detalhes sobre a utilização do seu sistema de inicialização em geral, mas configurando NODE_ENV é tão importante para o desempenho (e fácil de fazer), que está destacado aqui. -Com o Upstart, use a palavra-chave `env` no -seu arquivo de tarefa. Por exemplo: - -
    -
    -# /etc/init/env.conf
    - env NODE_ENV=production
    -
    -
    - -Para obter mais informações, consulte o [Introdução, Cookbook e Melhores Práticas para o Upstart](http://upstart.ubuntu.com/cookbook/#environment-variables). - Com o systemd, use a diretiva `Environment` no seu arquivo de unidade. Por exemplo: -
    -
    +```sh
     # /etc/systemd/system/myservice.service
     Environment=NODE_ENV=production
    -
    -
    - -Para obter mais informações, consulte [Usando -Variáveis de Ambiente em Unidades systemd](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). +``` -Se estiver usando o StrongLoop Process Manager, é possível também -[configurar -a variável de ambiente ao instalar o StrongLoop PM como um serviço](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### Assegure que o seu aplicativo reinicie automaticamente @@ -300,9 +233,9 @@ reinicie tanto se o aplicativo cair quanto se o próprio servidor cair. Apesar de se esperar que nenhum desses eventos ocorram, realisticamente você deve considerar ambas as eventualidades: -* Usando um gerenciador de processos para reiniciar o aplicativo (e o Node) quando ele cair. -* Usando o sistema de inicialização fornecido pelo seu sistema operacional para reiniciar o gerenciador de processos quando o -sistema operacional cair. Também é possível usar o sistema de inicialização sem um gerenciador de processos. +- Usando um gerenciador de processos para reiniciar o aplicativo (e o Node) quando ele cair. +- Usando o sistema de inicialização fornecido pelo seu sistema operacional para reiniciar o gerenciador de processos quando o + sistema operacional cair. Também é possível usar o sistema de inicialização sem um gerenciador de processos. Aplicativos do Node caem se encontrarem uma exceção não capturada. A principal coisa que precisa ser feita é assegurar que o @@ -323,39 +256,11 @@ gerenciamento do aplicativo em tempo real. Em adição à reinicialização do seu aplicativo quando cai, um gerenciador de processos pode permitir que você: -* Ganhe insights sobre o desempenho em tempo de execução e o consumo de recursos. -* Modifique configurações dinamicamente para melhorar o desempenho. -* Controle a clusterização (StrongLoop PM e pm2). +- Ganhe insights sobre o desempenho em tempo de execução e o consumo de recursos. +- Modifique configurações dinamicamente para melhorar o desempenho. +- Control clustering (pm2). -Os gerenciador de processos mais populares para o Node são os -seguintes: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -Para uma comparação recurso por recurso dos três gerenciadores -de processos, consulte [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Para -obter uma introdução mais detalhada para todos os três, consulte [Gerenciadores de Processos para aplicativos do -Express](/{{ page.lang }}/advanced/pm.html). - -Usando qualquer um desses gerenciadores de processos será o -suficiente para manter seu aplicativo funcionando, mesmo se ele cair -de tempos em tempos. - -Entretanto, o StrongLoop PM possui vários recursos que são especificamente destinados para a implementação na produção. É possível usá-lo e as ferramentas relacionadas do StrongLoop para: - -* Construir e empacotar seu aplicativo localmente, em seguida -implemente-o seguramente para o seu sistema de produção. -* Automaticamente reiniciar seu aplicativo se ele cair por qualquer razão. -* Gerenciar seus clusters remotamente. -* Visualizar perfis de CPU e captura instantânea de heap para -otimizar o desempenho e diagnosticar fugas de memória. -* Visualizar métricas de desempenho para o seu aplicativo. -* Facilmente escalar para múltiplos hosts com controle integrado para o balanceador de carga Nginx. - -Como explicado abaixo, ao instalar o StrongLoop PM como um serviço do sistema operacional usando o seu sistema de -inicialização, ele irá automaticamente reiniciar quando o sistema reiniciar. Assim, ele irá manter seus processos do aplicativo e clusters ativos para sempre. +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 um sistema de inicialização @@ -363,18 +268,14 @@ A próxima camada de confiabilidade é para assegurar que o seu aplicativo reinicie quando o servidor reiniciar. Os sistemas podem ainda assim cair por uma variedade de razões. Para assegurar que o seu aplicativo reinicie se o servidor cair, use o sistema de -inicialização integrado no seu sistema operacional. Os dois -principais sistemas de inicialização usados atualmente são o -[systemd](https://wiki.debian.org/systemd) e o [Upstart](http://upstart.ubuntu.com/). +inicialização integrado no seu sistema operacional. The main init system in use today is [systemd](https://wiki.debian.org/systemd). Existem duas formas de usar sistemas de inicialização com o seu aplicativo Express: -* Executar o seu aplicativo em um gerenciador de processos, e instalar o gerenciador de processos com o sistema de inicialização. O gerenciador de processos irá reiniciar seu aplicativo quando o -aplicativo cair, e o sistema de inicialização irá reiniciar o -gerenciador de processos quando o sistema operacional reiniciar. Esta é a abordagem recomendada. -* Executar o seu aplicativo (e Node) diretamente com o sistema -de inicialização. Isto é de certa forma mais simples, mas você não -obtém as vantagens adicionais do uso de um gerenciador de processos. +- Executar o seu aplicativo em um gerenciador de processos, e instalar o gerenciador de processos com o sistema de inicialização. O gerenciador de processos irá reiniciar seu aplicativo quando o + aplicativo cair, e o sistema de inicialização irá reiniciar o + gerenciador de processos quando o sistema operacional reiniciar. Esta é a abordagem recomendada. +- 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 @@ -383,20 +284,19 @@ maioria das distribuições principais do Linux adotaram o systemd como sistema de inicialização padrão. Um arquivo de configuração de serviço do systemd é chamado -de *arquivo de unidade*, com um nome de arquivo +de _arquivo de unidade_, com um nome de arquivo terminando em .service. Aqui está um exemplo de arquivo de unidade para gerenciar um aplicativo Node diretamente (substitua o texto em -negrito com valores para o seu sistema e aplicativo): +negrito com valores para o seu sistema e aplicativo): Replace the values enclosed in `` for your system and app: -
    -
    +```sh
     [Unit]
    -Description=Awesome Express App
    +Description=
     
     [Service]
     Type=simple
    -ExecStart=/usr/local/bin/node /projects/myapp/index.js
    -WorkingDirectory=/projects/myapp
    +ExecStart=/usr/local/bin/node 
    +WorkingDirectory=
     
     User=nobody
     Group=nogroup
    @@ -417,133 +317,11 @@ Restart=always
     
     [Install]
     WantedBy=multi-user.target
    -
    -
    -Para obter mais informações sobre o systemd, consulte a -[referência -do systemd (página do manual)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM como um serviço do systemd - -É possível facilmente instalar o StrongLoop Process Manager -como um serviço do systemd. Após fazer isso, quando o servidor -reiniciar, ele irá automaticamente reiniciar o StrongLoop PM, que irá -então reiniciar todos os aplicativos que está gerenciando. - -Para instalar o StrongLoop PM como um serviço do systemd: - -
    -
    -$ sudo sl-pm-install --systemd
    -
    -
    - -Em seguida inicie o serviço com: - -
    -
    -$ sudo /usr/bin/systemctl start strong-pm
    -
    -
    - -Para obter mais informações, consulte -[Configurando -um host de produção (documentação do StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -O Upstart é uma ferramenta de sistema disponível em muitas distribuições Linux para inicialização de tarefas e serviços durante -a inicialização do sistema, parando-os durante o encerramento, e -supervisionando-os. É possível configurar seu aplicativo Express ou -gerenciador de processos como um serviço e em seguida o Upstart irá -automaticamente reiniciá-lo quando ele cair. - -Um serviço do Upstart é definido em um arquivo de configuração de tarefa -(também chamado de uma "tarefa") com o nome do arquivo terminando com -`.conf`. O seguinte exemplo mostra como criar uma -tarefa chamada "myapp" para um aplicativo chamado "myapp" com o -arquivo principal localizado em `/projects/myapp/index.js`. - -Crie um arquivo chamado `myapp.conf` em -`/etc/init/` com o seguinte conteúdo (substitua o -texto em negrito com os valores para o seu sistema e aplicativo): - -
    -
    -# When to start the process
    -start on runlevel [2345]
    -
    -# When to stop the process
    -stop on runlevel [016]
    -
    -# Increase file descriptor limit to be able to handle more requests
    -limit nofile 50000 50000
    -
    -# Use production mode
    -env NODE_ENV=production
    -
    -# Run as www-data
    -setuid www-data
    -setgid www-data
    -
    -# Run from inside the app dir
    -chdir /projects/myapp
    -
    -# The process to start
    -exec /usr/local/bin/node /projects/myapp/index.js
    -
    -# Restart the process if it is down
    -respawn
    -
    -# Limit restart attempt to 10 times within 10 seconds
    -respawn limit 10 10
    -
    -
    - -NOTA: Este script requer o Upstart 1.4 ou mais novo, suportado no Ubuntu 12.04-14.10. - -Como a tarefa está configurada para executar quando o sistema -inicia, seu aplicativo será iniciado juntamente com o sistema -operacional, e automaticamente reiniciado se o aplicativo ou o -sistema cair. - -À parte da reinicialização automática do aplicativo, o Upstart -permite que você use estes comandos: - -* `start myapp` – Inicia o aplicativo -* `restart myapp` – Reinicia o aplicativo -* `stop myapp` – Para o aplicativo - -Para obter mais informações sobre o Upstart, consulte a -[Introdução, Cookbook, -e Melhores Práticas para o Upstart](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM como um serviço do Upstart - -É possível facilmente instalar o StrongLoop Process Manager -como um serviço do Upstart. Após fazer isso, quando o servidor -reiniciar, ele irá automaticamente reiniciar o StrongLoop PM, que irá -então reiniciar todos os aplicativos que está gerenciando. - -Para instalar o StrongLoop PM como um serviço do Upstart 1.4: - -
    -
    -$ sudo sl-pm-install
    -
    -
    - -Em seguida execute o serviço com: - -
    -
    -$ sudo /sbin/initctl start strong-pm
    -
    -
    +``` -NOTA: Em sistemas que não suportam o Upstart 1.4, os comandos -são ligeiramente diferentes. Consulte [Configurando -um host de produção (documentação do StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) para obter mais informações. +Para obter mais informações sobre o systemd, consulte a +referência +do systemd (página do manual). ### Execute seu aplicativo em um cluster @@ -553,7 +331,7 @@ de processos. Um cluster executa múltiplas instâncias do aplicativo, idealmente uma instância em cada núcleo da CPU, assim distribuindo a carga e as tarefas entre as instâncias. - +![Balancing between application instances using the cluster API](/images/clustering.png) IMPORTANTE: Como as instâncias do aplicativo são executadas em processos separados, elas não compartilham o mesmo espaço de memória. Isto é, os objetos são locais para cada instância do aplicativo. Portanto, não é possível manter o estado no código do aplicativo. Entretanto, é possível usar um armazenamento de dados em memória como o [Redis](http://redis.io/) para armazenar dados relativos à sessão e ao estado. Este alerta aplica-se a essencialmente todas as formas de escalonamento horizontal, seja a @@ -563,41 +341,37 @@ Em aplicativos clusterizados, processos de trabalho podem cair individualmente s #### Usando o módulo de cluster do Node -A clusterização é pode ser feita com o [módulo de -cluster](https://nodejs.org/docs/latest/api/cluster.html) do Node. Isto permite que um processo principal faça o +Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). Isto permite que um processo principal faça o spawn de processos de trabalho e distribua conexões recebidas entre -os trabalhadores. Entretanto, em vez de usar este módulo diretamente, -é muito melhor usar uma das muitas ferramentas que fazem isso -automaticamente por você; por exemplo o [node-pm](https://www.npmjs.com/package/node-pm) ou -o [cluster-service](https://www.npmjs.com/package/cluster-service). - -#### Usando o StrongLoop PM - -Se você implementar seu aplicativo no StrongLoop Process Manager -(PM), então é possível tirar vantagem da clusterização -*sem* modificar o código do seu aplicativo. - -Quando o StrongLoop Process Manager (PM) executa um aplicativo, -ele automaticamente executa-o em um cluster com um número de -trabalhadores igual ao número de núcleos de CPU do sistema. É -possível manualmente alterar o número de processos de trabalho no -cluster usando a ferramenta de linha de comandos slc sem parar o -aplicativo. - -Por exemplo, assumindo que tenha implementado o seu aplicativo -para prod.foo.com e o StrongLoop PM está escutando na porta 8701 (a -padrão), em seguida configurar o tamanho do cluster para oito usando -o slc: - -
    -
    -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
    -
    -
    - -Para obter mais informações sobre clusterização com o StrongLoop -PM, consulte por [Clusterização](https://docs.strongloop.com/display/SLC/Clustering) -na documentação do StrongLoop. +os trabalhadores. + +#### 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 +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ 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 +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ 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. ### Armazene em cache os resultados das solicitações @@ -606,12 +380,7 @@ armazenar em cache o resultado de solicitações, para que o seu aplicativo não repita a operação para entregar a mesma solicitação repetidamente. -Use um servidor de armazenamento em cache como o -[Varnish](https://www.varnish-cache.org/) ou o -[Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) -(consulte também [Armazenamento -em Cache no Nginx](https://serversforhackers.com/nginx-caching/)) para melhorar imensamente a velocidade e o -desempenho do seu aplicativo. +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### Use um balanceador de carga @@ -625,29 +394,16 @@ que é possível com uma instância única. Um balanceador de carga é geralmente um proxy reverso que orquestra o tráfego para e de múltiplas instâncias de aplicativo e -servidores. É possível facilmente configurar um balanceador de carga -para o seu aplicativo usando o [Nginx](http://nginx.org/en/docs/http/load_balancing.html) -ou o [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). +servidores. 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). Com o balanceamento de carga, você pode ter que garantir que solicitações que estão associadas com um ID de sessão em particular conectam ao processo que as originou. Isto é conhecido como -*afinidade de sessão*, ou *sessões -pegajosas*, e podem ser endereçadas pela sugestão acima para +_afinidade de sessão_, ou _sessões +pegajosas_, e podem ser endereçadas pela sugestão acima para usar um armazenamento de dados como o Redis para os dados da sessão (dependendo do seu aplicativo). Para uma discussão, consulte por -[Usando -múltiplos nós](http://socket.io/docs/using-multiple-nodes/). - -#### Usando o StrongLoop PM com um balanceador de carga Nginx - -O [StrongLoop Process -Manager](http://strong-pm.io/) é integrado com um Controlador Nginx, tornando mais -fácil a configurar configurações de ambientes de produção com -múltiplos hosts. Para obter mais informações, consulte por -[Escalando -para servidores múltiplos](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (documentação do StrongLoop). - +[Usando múltiplos nós](https://socket.io/docs/v4/using-multiple-nodes/). ### Use um proxy reverso @@ -659,7 +415,4 @@ balanceamento de carga entre outras coisas. Entregar tarefas que não requerem conhecimento do estado do aplicativo para um proxy reverso libera o Express para executar -tarefas especializadas de aplicativos. Por esta razão, é recomendado -executar o Express atrás de um proxy reverso como o -[Nginx](https://www.nginx.com/) ou o -[HAProxy](http://www.haproxy.org/) na produção. +tarefas especializadas de aplicativos. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/pt-br/advanced/best-practice-security.md b/pt-br/advanced/best-practice-security.md old mode 100755 new mode 100644 index 525b850916..4868367700 --- a/pt-br/advanced/best-practice-security.md +++ b/pt-br/advanced/best-practice-security.md @@ -1,17 +1,18 @@ --- layout: page title: Melhores Práticas de Segurança para o Express em Produção +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: pt-br +redirect_from: " " --- # Melhores Práticas em Produção: Segurança ## Visão Geral -O termo *"produção"* refere-se ao estágio no ciclo de vida do software onde um aplicativo ou API está geralmente -disponível para os seus usuários finais ou consumidores. Em contrapartida, no estágio de *"desenvolvimento"*, -você ainda está ativamente escrevendo e testando o código, e o aplicativo não está aberto para acesso externo. Os ambiente de sistema correspondentes são conhecidos como ambientes de *produção* e *desenvolvimento*, +O termo _"produção"_ refere-se ao estágio no ciclo de vida do software onde um aplicativo ou API está geralmente +disponível para os seus usuários finais ou consumidores. Em contrapartida, no estágio de _"desenvolvimento"_, +você ainda está ativamente escrevendo e testando o código, e o aplicativo não está aberto para acesso externo. Os ambiente de sistema correspondentes são conhecidos como ambientes de _produção_ e _desenvolvimento_, respectivamente. Os ambientes de desenvolvimento e produção são geralmente @@ -23,13 +24,45 @@ ambiente de produção. E em desenvolvimento, você não precisa se preocupar com a escalabilidade, confiabilidade, e desempenho, enquanto estas preocupações se tornam críticas na produção. +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} + Este artigo discute algumas melhores práticas de segurança para aplicativos do Express implementadas na produção. +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [Use TLS](#use-tls) + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - [Use Helmet](#use-helmet) + - [Reduce fingerprinting](#reduce-fingerprinting) + - A [hsts](https://github.com/helmetjs/hsts) configura o cabeçalho `Strict-Transport-Security` + que impinge conexões seguras (HTTP sobre SSL/TLS) com o servidor. + - A principal diferença entre esses dois módulos é como eles salvam os dados de cookies de sessão. O middleware [express-session](https://www.npmjs.com/package/express-session) + armazena os dados da sessão no servidor; ele salva apenas o ID da + sessão no cookie, não os dados da sessão. Por padrão, ele usa + armazenamento em memória e não é projetado para um ambiente de + produção. Em produção, será necessário configurar um armazenamento de + sessão escalável; consulte a lista de armazenamentos + de sessão compatíveis. + - A [ieNoOpen](https://github.com/helmetjs/ienoopen) configura o `X-Download-Options` para o IE8+. + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) + - A [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) remove o cabeçalho `X-Powered-By`. + - [Additional considerations](#additional-considerations) + ## Não use versões descontinuadas ou vulneráveis do Express Os Express 2.x e 3.x não são mais mantidos. Problemas de -segurança e desempenho nestas versões não serão corrigidos. Não use-as! Se +segurança e desempenho nestas versões não serão corrigidos. Não use-as! Se não tiver migrado para a versão 4, siga o [guia de migração](/{{ page.lang }}/guide/migrating-4.html). Assegure-se também de que não esteja usando nenhuma das versões @@ -40,8 +73,8 @@ liberações estáveis, preferivelmente a mais recente. ## Use TLS Se o seu aplicativo negocia com ou transmite dados sensíveis, -use a [Segurança -da Camada de Transporte](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) para proteger a conexão e os +use a Segurança +da Camada de Transporte (TLS) para proteger a conexão e os dados. Esta tecnologia criptografa os dados antes deles serem enviados do cliente para o servidor, assim evitando alguns ataques comuns (e fáceis). Apesar de solicitações Ajax e POST não parecerem @@ -49,19 +82,46 @@ visivelmente óbvias e parecerem "ocultas" em navegadores, o seu tráfego de rede é vulnerável a [sniffing de pacotes](https://en.wikipedia.org/wiki/Packet_analyzer) e [ataques man-in-the-middle ](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -Você pode estar familiarizado com a criptografia Secure Sockets Layer(SSL). [O -TLS é simplesmente a próxima progressão do](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). Em outras palavras, se você estava usando o SSL antes, considere fazer o -upgrade para o TLS. Em geral, recomendamos o Nginx para lidar com o TLS. Para +Você pode estar familiarizado com a criptografia Secure Sockets Layer(SSL). O +TLS é simplesmente a próxima progressão do. Em outras palavras, se você estava usando o SSL antes, considere fazer o +upgrade para o TLS. Em geral, recomendamos o Nginx para lidar com o TLS. Para obter uma boa referência para configurar o TLS no Nginx (e outros servidores), consulte -[Configurações -Recomendadas de Servidores (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). +Configurações +Recomendadas de Servidores (Mozilla Wiki). Além disso, uma ferramenta útil para obter um certificado TLS -gratuito é a [Let's -Encrypt](https://letsencrypt.org/about/), uma autoridade de certificação (CA) gratuita, +gratuito é a Let's +Encrypt, uma autoridade de certificação (CA) gratuita, automatizada, e aberta fornecida pelo -[Grupo de Pesquisas de -Segurança da Internet (ISRG)](https://letsencrypt.org/isrg/). +Grupo de Pesquisas de +Segurança da Internet (ISRG). + +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` ## Use Helmet @@ -69,63 +129,87 @@ O [Helmet](https://www.npmjs.com/package/helmet) pode ajudar a proteger o seu aplicativo de algumas vulnerabilidades da web bastante conhecidas configurando os cabeçalhos HTTP adequadamente. -O Helmet é na realidade apenas uma coleção de nove funções de -middlewares menores que configuram cabeçalhos HTTP relacionados à -segurança: +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* A [csp](https://github.com/helmetjs/csp) configura o cabeçalho `Content-Security-Policy` para ajudar a evitar ataques de cross-site scripting e outras injeções cross-site. -* A [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) remove o cabeçalho `X-Powered-By`. -* A [hsts](https://github.com/helmetjs/hsts) configura o cabeçalho `Strict-Transport-Security` -que impinge conexões seguras (HTTP sobre SSL/TLS) com o servidor. -* A [ieNoOpen](https://github.com/helmetjs/ienoopen) configura o `X-Download-Options` para o IE8+. -* A [noCache](https://github.com/helmetjs/nocache) configura os cabeçalhos `Cache-Control` e Pragma -para desativar o armazenamento em cache no lado do cliente. -* A [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) -configura o `X-Content-Type-Options` para evitar que os navegadores procurem por MIME uma resposta a partir do -content-type declarado. -* A [frameguard](https://github.com/helmetjs/frameguard) -configura o cabeçalho `X-Frame-Options` para fornecer proteção [clickjacking](https://www.owasp.org/index.php/Clickjacking). -* A [xssFilter](https://github.com/helmetjs/x-xss-protection) -configura o `X-XSS-Protection` para ativar o filtro -de Cross-site scripting (XSS) nos navegadores da web mais recentes. +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. Instale o Helmet como qualquer outro módulo: -
    -
    -$ npm install --save helmet
    -
    -
    +```bash +$ npm install helmet +``` Em seguida use-o no seu código: -
    -
    -...
    -var helmet = require('helmet');
    -app.use(helmet());
    -...
    -
    -
    +```js +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... +``` + +## Reduce fingerprinting + +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. + +By default, Express sends the `X-Powered-By` response header that you can +disable using the `app.disable()` method: + +```js +app.disable('x-powered-by') +``` + +{% capture powered-advisory %} + +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. -### No mínimo, desative o cabeçalho X-Powered-By +{% endcapture %} -Se não desejar usar o Helmet, então pelo menos desative o -cabeçalho `X-Powered-By`. Invasores podem utilizar -este cabeçalho (que fica ativado por padrão) para detectar -aplicativos executando o Express e então iniciar ataques -especificamente direcionados a eles. +{% include admonitions/note.html content=powered-advisory %} -Portanto, a melhor prática é desligar o cabeçalho com o método -`app.disable()`: +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): -
    -
    -app.disable('x-powered-by');
    -
    -
    +```js +// last app.use calls right before app.listen(): -Se usar o `helmet.js`, ele cuida disso por você. +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## Use cookies de maneira segura @@ -136,29 +220,23 @@ opções de segurança de cookies adequadamente. Existem dois módulos de middleware principais para sessão de cookies: -* [express-session](https://www.npmjs.com/package/express-session) -que substitui o middleware `express.session` -integrado no Express 3.x. -* [cookie-session](https://www.npmjs.com/package/cookie-session) -que substitui o middleware `express.cookieSession` integrado no Express 3.x. +- [express-session](https://www.npmjs.com/package/express-session) + que substitui o middleware `express.session` + integrado no Express 3.x. +- [cookie-session](https://www.npmjs.com/package/cookie-session) + que substitui o middleware `express.cookieSession` integrado no Express 3.x. -A principal diferença entre esses dois módulos é como eles salvam os dados de cookies de sessão. O middleware [express-session](https://www.npmjs.com/package/express-session) -armazena os dados da sessão no servidor; ele salva apenas o ID da -sessão no cookie, não os dados da sessão. Por padrão, ele usa -armazenamento em memória e não é projetado para um ambiente de -produção. Em produção, será necessário configurar um armazenamento de -sessão escalável; consulte a lista de [armazenamentos -de sessão compatíveis](https://github.com/expressjs/session#compatible-session-stores). +The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. 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). Em contrapartida, o middleware [cookie-session](https://www.npmjs.com/package/cookie-session) -implementa um armazenamento apoiado em cookies: ele serializa a sessão inteira para o cookie, ao invés de apenas a chave da sessão. Use apenas quando os dados da sessão são relativamente pequenos e facilmente codificados como números primitivos(ao invés de objetos). Apesar de navegadores supostamente suportarem pelo menos 4096 bytes por cookie, para assegurar que você não exceda o limite, não exceda -um tamanho de 4093 bytes por domínio. Além disso, esteja ciente de que os dados do cookie serão visíveis para o cliente, portanto se +implementa um armazenamento apoiado em cookies: ele serializa a sessão inteira para o cookie, ao invés de apenas a chave da sessão. Use apenas quando os dados da sessão são relativamente pequenos e facilmente codificados como números primitivos(ao invés de objetos). Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Apesar de navegadores supostamente suportarem pelo menos 4096 bytes por cookie, para assegurar que você não exceda o limite, não exceda +um tamanho de 4093 bytes por domínio. Além disso, esteja ciente de que os dados do cookie serão visíveis para o cliente, portanto se houver razão para mantê-los seguros ou obscuros, então o express-session pode ser uma escolha melhor. ### Não use o nome do cookie da sessão padrão Usando o nome do cookie da sessão padrão pode deixar o seu -aplicativo aberto a ataques. O problema de segurança levantado é +aplicativo aberto a ataques. O problema de segurança levantado é parecido ao do `X-Powered-By`: um invasor em potencial poderia usá-lo para identificar o servidor e direcionar ataques de acordo com ele. @@ -166,82 +244,109 @@ ataques de acordo com ele. Para evitar este problema, use nomes de cookie genéricos; por exemplo usando o middleware [express-session](https://www.npmjs.com/package/express-session): -
    -
    -var session = require('express-session');
    +```js
    +const session = require('express-session')
     app.set('trust proxy', 1) // trust first proxy
    -app.use( session({
    -   secret : 's3Cur3',
    -   name : 'sessionId',
    -  })
    -);
    -
    -
    +app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) +``` ### Configure as opções de segurança de cookie Configure as seguintes opções de cookie para aprimorar a segurança: -* `secure` - Assegura que o navegador só envie o cookie por HTTPS. -* `httpOnly` - Assegura que o cookie seja enviado apenas por HTTP(S), não por cliente JavaScript, ajudando -assim a se proteger contra ataques de cross-site scripting. -* `domain` - indica o domínio do cookie; use-o para comparação contra o domínio do servidor em que a URL está -sendo solicitada. Se elas corresponderem, verifique o atributo de caminho em seguida. -* `path` - indica o caminho do cookie; use-o para comparação contra o caminho da solicitação. Se este e o domínio corresponderem, então envie o cookie na solicitação. -* `expires` - use para configurar uma data de -expiração para cookies persistentes. +- `secure` - Assegura que o navegador só envie o cookie por HTTPS. +- `httpOnly` - Assegura que o cookie seja enviado apenas por HTTP(S), não por cliente JavaScript, ajudando + assim a se proteger contra ataques de cross-site scripting. +- `domain` - indica o domínio do cookie; use-o para comparação contra o domínio do servidor em que a URL está + sendo solicitada. Se elas corresponderem, verifique o atributo de caminho em seguida. +- `path` - indica o caminho do cookie; use-o para comparação contra o caminho da solicitação. Se este e o domínio corresponderem, então envie o cookie na solicitação. +- `expires` - use para configurar uma data de + expiração para cookies persistentes. Aqui está um exemplo usando o middleware [cookie-session](https://www.npmjs.com/package/cookie-session): -
    -
    -var session = require('cookie-session');
    -var express = require('express');
    -var app = express();
    +```js
    +const session = require('cookie-session')
    +const express = require('express')
    +const app = express()
     
    -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
    +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
     app.use(session({
       name: 'session',
       keys: ['key1', 'key2'],
    -  cookie: { secure: true,
    -            httpOnly: true,
    -            domain: 'example.com',
    -            path: 'foo/bar',
    -            expires: expiryDate
    -          }
    -  })
    -);
    -
    -
    + cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) +``` -## Considerações adicionais +## Prevent brute-force attacks against authorization + +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +1. The number of consecutive failed attempts by the same user name and IP address. +2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) + +## Ensure your dependencies are secure + +Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. + +Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. + +```bash +$ npm audit +``` -Aqui estão algumas recomendações adicionais da excelente [Lista -de Verificação de Segurança do Node.js](https://blog.risingstack.com/node-js-security-checklist/). Refira-se a esta postagem do blog para obter todos os detalhes destas recomendações: - -* Implemente limitações de tráfego para evitar ataques de força -bruta contra a autenticação. Uma forma de fazer isso é usar o [Gateway -da API do StrongLoop](https://strongloop.com/node-js/api-gateway/) para impingir políticas de limitação de tráfego. Alternativamente, -é possível usar um middleware como o [express-limiter](https://www.npmjs.com/package/express-limiter), -mas fazer isso irá requerer que você modifique seu código de alguma forma. -* Use o middleware [csurf](https://www.npmjs.com/package/csurf) para se proteger contra falsificações de solicitação cross-site (CSRF). -* Sempre filtrar e limpar a entrada do usuário para se proteger de ataques de cross-site scripting (XSS) e injeção de comando. -* Proteja-se contra ataques de injeção de SQLs usando consultas parametrizadas ou instruções preparadas. -* Use a ferramenta de software livre [sqlmap](http://sqlmap.org/) para detectar -vulnerabilidades de injeção de SQL no seu aplicativo. -* Use as ferramentas [nmap](https://nmap.org/) e [sslyze](https://github.com/nabla-c0d3/sslyze) para -testar a configuração das suas cifras SSL, chaves, e renegociação, bem como a validade do seu certificado. -* Use o [safe-regex](https://www.npmjs.com/package/safe-regex) para assegurar que suas expressões regulares não estejam suscetíveis -a ataques [negação de serviço de expressões regulares](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). - -## Evitar outras vulnerabilidades conhecidas +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: + +```bash +$ npm install -g snyk +$ cd your-app +``` + +Use this command to test your application for vulnerabilities: + +```bash +$ snyk test +``` + +### Evitar outras vulnerabilidades conhecidas Fique atento às recomendações do -[Node Security -Project](https://npmjs.com/advisories) que podem afetar o Express ou outros módulos usados -pelo seu aplicativo. Em geral, o Node Security Project é um excelente +Node Security +Project que podem afetar o Express ou outros módulos usados +pelo seu aplicativo. Em geral, o Node Security Project é um excelente recurso para conhecimento e ferramentas sobre segurança do Node. Finalmente, os aplicativos do Express - como outros aplicativos web - podem estar vulneráveis a uma variedade de ataques baseados na -web. Familiarize-se com [vulnerabilidades web](https://www.owasp.org/index.php/Top_10_2013-Top_10) conhecidas e tome precauções para evitá-las. +web. Familiarize-se com [vulnerabilidades web](https://www.owasp.org/www-project-top-ten/) conhecidas e tome precauções para evitá-las. + +## Considerações adicionais + +Aqui estão algumas recomendações adicionais da excelente Lista +de Verificação de Segurança do Node.js. Refira-se a esta postagem do blog para obter todos os detalhes destas recomendações: + +- Sempre filtrar e limpar a entrada do usuário para se proteger de ataques de cross-site scripting (XSS) e injeção de comando. +- Proteja-se contra ataques de injeção de SQLs usando consultas parametrizadas ou instruções preparadas. +- Use a ferramenta de software livre [sqlmap](http://sqlmap.org/) para detectar + vulnerabilidades de injeção de SQL no seu aplicativo. +- Use as ferramentas [nmap](https://nmap.org/) e [sslyze](https://github.com/nabla-c0d3/sslyze) para + testar a configuração das suas cifras SSL, chaves, e renegociação, bem como a validade do seu certificado. +- Use o [safe-regex](https://www.npmjs.com/package/safe-regex) para assegurar que suas expressões regulares não estejam suscetíveis + a ataques [negação de serviço de expressões regulares](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). + +[helmet]: https://helmetjs.github.io/ \ No newline at end of file diff --git a/pt-br/advanced/developing-template-engines.md b/pt-br/advanced/developing-template-engines.md old mode 100755 new mode 100644 index e7dbf250e1..a146c7d9ff --- a/pt-br/advanced/developing-template-engines.md +++ b/pt-br/advanced/developing-template-engines.md @@ -1,8 +1,9 @@ --- layout: page title: Desenvolvendo mecanismos de modelo para o Express +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: pt-br +redirect_from: " " --- # Desenvolvendo mecanismos de modelo para o Express @@ -17,40 +18,37 @@ de retorno de chamada. O código a seguir é um exemplo de implementação de um mecanismo de modelo muito simples para renderização de arquivos `.ntl`. -
    -
    -var fs = require('fs'); // this engine requires the fs module
    -app.engine('ntl', function (filePath, options, callback) { // define the template engine
    -  fs.readFile(filePath, function (err, content) {
    -    if (err) return callback(new Error(err));
    +```js
    +const fs = require('fs') // this engine requires the fs module
    +app.engine('ntl', (filePath, options, callback) => { // define the template engine
    +  fs.readFile(filePath, (err, content) => {
    +    if (err) return callback(err)
         // this is an extremely simple template engine
    -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
    -    .replace('#message#', '

    '+ options.message +'

    '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
    -
    + const rendered = content.toString() + .replace('#title#', `${options.title}`) + .replace('#message#', `

    ${options.message}

    `) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine +``` Seu aplicativo estará agora habilitado a renderizar arquivos `.ntl`. Crie um arquivo chamado `index.ntl` no diretório `views` com o seguinte conteúdo. -
    -
    +```pug
     #title#
     #message#
    -
    -
    +``` + Em seguida, crie a seguinte rota no seu aplicativo. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    -Ao fazer uma solicitação à página inicial, o `index.ntl` será renderizado como HTML. +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` + +Ao fazer uma solicitação à página inicial, o `index.ntl` será renderizado como HTML. \ No newline at end of file diff --git a/pt-br/advanced/healthcheck-graceful-shutdown.md b/pt-br/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..be0604829a --- /dev/null +++ b/pt-br/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/pt-br/advanced/pm.md b/pt-br/advanced/pm.md deleted file mode 100755 index 503be29ee5..0000000000 --- a/pt-br/advanced/pm.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -layout: page -title: Gerenciadores de processos para aplicativos do Express -menu: advanced -lang: pt-br ---- - -# Gerenciadores de processos para aplicativos do Express - -Ao executar aplicativos do Express para produção, é útil usar um *gerenciador de processos* para completar as -seguintes tarefas: - - -- Reiniciar o aplicativo automaticamente se cair. -- Ganhe insights sobre o desempenho em tempo de execução e o consumo de recursos. - -- Modifique configurações dinamicamente para melhorar o desempenho. -- Controle a clusterização. - -Um gerenciador de processos é de certa forma parecido com um -servidor de aplicativos: ele é um "contêiner" para aplicativos que -facilita a implementação, fornece alta disponibilidade, e permite o -gerenciamento do aplicativo em tempo real. - -Os gerenciadores de processos mais populares para o Express e outros aplicativos Node.js são os seguintes: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -Usar qualquer uma dessas três ferramentas pode ser muito útil, -entretanto o StrongLoop Process Manager é a única ferramenta que -fornece uma solução abrangente de tempo de execução e implementação -que é atende ao ciclo de vida completo de aplicativos do Node.js, com -ferramentas para todas as etapas antes e depois da produção, em uma -interface unificada. - - -Aqui está uma breve visão de cada uma dessas ferramentas. -Para obter uma comparação detalhada, consulte [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -O StrongLoop Process Manager (StrongLoop PM) é um gerenciador -de processos para aplicativos do Node.js. O StrongLoop PM possui -balanceamento de carga, monitoramento, e implementação em múltiplos -hosts integrada, e um console gráfico. -É possível usar o StrongLoop PM para as seguintes tarefas: - -- Construir, empacotar, e implementar aplicativos do Node.js para um sistema local ou remoto. -- Visualizar perfis de CPU e captura instantânea de heap para -otimizar o desempenho e diagnosticar fugas de memória. -- Manter processos e clusters ativos para sempre. -- Visualizar métricas de desempenho no seu aplicativo. -- Facilmente gerenciar implementações em múltiplos hosts com a integração com o Nginx. -- Unificar vários StrongLoop PMs para um tempo de execução de microsserviços distribuído que é gerenciado a partir de um Arc. - - -É possível trabalhar com o StrongLoop PM usando uma poderosa -ferramenta de interface da linha de comandos chamada -`slc`, ou uma ferramenta gráfica chamada Arc. A Arc -é um software livre, com suporte profissional fornecido pelo StrongLoop. - -Para obter mais informações, consulte [http://strong-pm.io/](http://strong-pm.io/). - -Documentação completa: - -- [Aplicativos operacionais do Node (documentação do StrongLoop)](http://docs.strongloop.com/display/SLC) -- [Usando o StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Instalação -
    -
    -$ [sudo] npm install -g strongloop
    -
    -
    - -### Uso Básico -
    -
    -$ cd my-app
    -$ slc start
    -
    -
    - -Visualizar o status do Gerenciador de Processos e todos os aplicativos implementados: - -
    -
    -$ slc ctl
    -Service ID: 1
    -Service Name: my-app
    -Environment variables:
    -  No environment variables defined
    -Instances:
    -    Version  Agent version  Cluster size
    -     4.1.13      1.5.14           4
    -Processes:
    -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
    -    1.1.57692  57692   0
    -    1.1.57693  57693   1     0.0.0.0:3001
    -    1.1.57694  57694   2     0.0.0.0:3001
    -    1.1.57695  57695   3     0.0.0.0:3001
    -    1.1.57696  57696   4     0.0.0.0:3001
    -
    -
    - -Listar todos os aplicativos (serviços) sendo gerenciados: - -
    -
    -$ slc ctl ls
    -Id          Name         Scale
    - 1          my-app       1
    -
    -
    - -Parar um aplicativo: - -
    -
    -$ slc ctl stop my-app
    -
    -
    - -Reiniciar um aplicativo: - -
    -
    -$ slc ctl restart my-app
    -
    -
    - -É possível também fazer uma "reinicialização leve," que dá aos -processos de trabalho um período de tolerância para fechar conexões -existentes, e em seguida reiniciar o aplicativo atual: - - -
    -
    -$ slc ctl soft-restart my-app
    -
    -
    - -Para remover um aplicativo do gerenciamento: - -
    -
    -$ slc ctl remove my-app
    -
    -
    - -## PM2 - -O PM2 é um gerenciador de processos de produção para aplicativos do Node.js, -que possui um balanceador de carga integrado. O PM2 permite manter os -aplicativos ativos para sempre e recarregá-los sem tempo de -inatividade, e facilitará tarefas comuns de administração de -sistemas. O PM2 também permite que você gerencie o registro de logs, -o monitoramento, e a clusterização do aplicativo. - - -Para obter mais informações, consulte: [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Instalação - -
    -
    -$ [sudo] npm install pm2 -g
    -
    -
    - -### Uso Básico - -Ao iniciar um aplicativo usando o comando -`pm2`, você deve especificar o caminho do aplicativo. No -entanto, ao parar, reiniciar, ou excluir um aplicativo, é possível -especificar apenas o nome ou o id do aplicativo. - - -
    -
    -$ pm2 start npm --name my-app -- start
    -[PM2] restartProcessId process id 0
    -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
    -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
    -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
    -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
    -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
    - Use the `pm2 show ` command to get more details about an app.
    -
    -
    - -Ao iniciar um aplicativo usando o comando `pm2`, o aplicativo será imediatamente enviado para -o segundo plano. É possível controlar os aplicativos em segundo plano a partir da linha de comandos usando vários comandos `pm2`. - -Após um aplicativo ser iniciado usando o comando `pm2`, ele é registrado na lista de -processos do PM2 com um ID. É possível portanto gerenciar aplicativos com o mesmo nome a partir de diretórios diferentes no sistema, usando -os seus IDs. - -Observe que se mais de um aplicativo com o mesmo nome estiver executando, os comandos do `pm2` afetam todos eles. -Portanto use os IDs ao invés dos nomes para gerenciar aplicativos individualmente. - -Listar todos os processos em execução: - -
    -
    -$ pm2 list
    -
    -
    - -Parar um aplicativo: - -
    -
    -$ pm2 stop 0
    -
    -
    - -Reiniciar um aplicativo: - -
    -
    -$ pm2 restart 0
    -
    -
    - -Para visualizar informações detalhadas sobre um aplicativo: - -
    -
    -$ pm2 show 0
    -
    -
    - -Para remover um aplicativo do registro do PM2: - -
    -
    -$ pm2 delete 0
    -
    -
    - - -## Forever - -Forever é uma ferramenta simples de interface da linha de -comandos para assegurar que um dado script executa continuamente -(para sempre). A interface simples do Forever torna-o ideal para a -execução de implementações menores dos aplicativos e scripts do -Node.js. - - -Para obter mais informações, consulte: [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Instalação - -
    -
    -$ [sudo] npm install forever -g
    -
    -
    - -### Uso Básico - -Para iniciar um script, use o comando `forever start` e especifique o caminho do script: - -
    -
    -$ forever start script.js
    -
    -
    - -Este comando irá executar o script em modo daemon (no segundo plano). - -Para executar o script de forma que ele seja anexado ao terminal, omita `start`: - -
    -
    -$ forever script.js
    -
    -
    - -É uma boa ideia registrar os logs da saída da ferramenta Forever e do script usando as opções de log `-l`, -`-o`, e `-e`, como mostradas nesse exemplo: - - -
    -
    -$ forever start -l forever.log -o out.log -e err.log script.js
    -
    -
    - -Para visualizar a lista de scripts que foram iniciados pelo Forever: - -
    -
    -$ forever list
    -
    -
    - -Para parar um script que foi iniciado pelo Forever use o -comando `forever stop` e especifique o índice do -processo (conforme listado pelo comando `forever -list`). - -
    -
    -$ forever stop 1
    -
    -
    - -Alternativamente, especifique o caminho do arquivo: - -
    -
    -$ forever stop script.js
    -
    -
    - -Para parar todos os scripts que foram iniciados pelo Forever: - -
    -
    -$ forever stopall
    -
    -
    - -O Forever possui muitas outras opções, e ele também fornece uma API programática. - diff --git a/pt-br/advanced/security-updates.md b/pt-br/advanced/security-updates.md old mode 100755 new mode 100644 index 7206f79bd4..3bbb7e8f3f --- a/pt-br/advanced/security-updates.md +++ b/pt-br/advanced/security-updates.md @@ -1,8 +1,9 @@ --- layout: page title: Atualizações de segurança do Express +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: pt-br +redirect_from: " " --- # Atualizações de segurança @@ -10,53 +11,93 @@ lang: pt-br
    As vulnerabilidades do Node.js afetam diretamente o Express. Portanto [fique atento às -vulnerabilidades do Node.js](http://blog.nodejs.org/vulnerability/) e certifique-se de que você está +vulnerabilidades do Node.js](https://nodejs.org +/en/blog/vulnerability/) e certifique-se de que você está usando a versão estável mais recente do Node.js.
    A lista abaixo enumera as vulnerabilidades do Express que foram corrigidas na versão da atualização especificadas. -## 4.x +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} - * 4.11.1 - * Corrigida a vulnerabilidade de divulgação do caminho -raiz no `express.static`, `res.sendfile`, e `res.sendFile` - * 4.10.7 - * Corrigida a vulnerabilidade de redirecionamento aberto -no `express.static` ([recomendação](https://npmjs.com/advisories/35), -[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 4.8.8 - * Corrigida a vulnerabilidade de travessia de diretório no `express.static` ([recomendação](http://npmjs.com/advisories/32), [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)). - * 4.8.4 - * O Node.js 0.10 pode vazar os `fd`s em certas situações que afetam o `express.static` e o -`res.sendfile`. Solicitações maliciosas podem causar os `fd`s a vazar e eventualmente levar a erros -de `EMFILE` e servidores sem capacidade de resposta. - * 4.8.0 - * Matrizes esparsas que possuem índices extremamente altos na sequência de consulta podem fazer com que o processo sofra um -esgotamento de memória e derrubar o servidor. - * Objetos de sequência de consulta extremamente aninhados podem fazer com que o processo fique bloqueado e o servidor -temporariamente não responsivo. +## 4.x +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. + - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. +- 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +- 4.15.2 + - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - Corrigida a vulnerabilidade de divulgação do caminho + raiz no `express.static`, `res.sendfile`, e `res.sendFile` +- 4.10.7 + - Corrigida a vulnerabilidade de redirecionamento aberto no `express.static` ([recomendação](https://npmjs.com/advisories/35), + [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 4.8.8 + - Corrigida a vulnerabilidade de travessia de diretório no `express.static` ([recomendação](http://npmjs.com/advisories/32), [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)). +- 4.8.4 + - O Node.js 0.10 pode vazar os `fd`s em certas situações que afetam o `express.static` e o + `res.sendfile`. Solicitações maliciosas podem causar os `fd`s a vazar e eventualmente levar a erros de + `EMFILE` e servidores sem capacidade de resposta. +- 4.8.0 + - Matrizes esparsas que possuem índices extremamente altos na sequência de consulta podem fazer com que o processo sofra um + esgotamento de memória e derrubar o servidor. + - Objetos de sequência de consulta extremamente aninhados podem fazer com que o processo fique bloqueado e o servidor + temporariamente não responsivo. ## 3.x - * 3.19.1 - * Corrigida a vulnerabilidade de divulgação do caminho raiz no `express.static`, -`res.sendfile`, e `res.sendFile` - * 3.19.0 - * Corrigida a vulnerabilidade de redirecionamento aberto no `express.static` ([recomendação](https://npmjs.com/advisories/35), -[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Corrigida a vulnerabilidade de travessia de diretório no `express.static`. - * 3.16.6 - * O Node.js 0.10 pode vazar os `fd`s em certas situações que afetam o `express.static` e o -`res.sendfile`. Solicitações maliciosas podem causar os `fd`s a vazar e eventualmente levar a erros de -`EMFILE` e servidores sem capacidade de resposta. - * 3.16.0 - * Matrizes esparsas que possuem índices extremamente altos na sequência de consulta podem fazer com que o processo sofra um -esgotamento de memória e derrubar o servidor. - * Objetos de sequência de consulta extremamente aninhados podem fazer com que o processo fique bloqueado e o servidor -temporariamente não responsivo. - * 3.3.0 - * A resposta 404 de uma tentativa de substituição de um método não suportado era suscetível a ataques de cross-site scripting. +
    + **Express 3.x support is ending soon** + +This series will continue to receive only security updates and bug fixes until July 2015. It is highly recommended to upgrade to Express 4.x. + +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). + +
    + +- 3.19.1 + - Corrigida a vulnerabilidade de divulgação do caminho + raiz no `express.static`, `res.sendfile`, e `res.sendFile` +- 3.19.0 + - Corrigida a vulnerabilidade de redirecionamento aberto no `express.static` ([recomendação](https://npmjs.com/advisories/35), + [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). +- 3.16.10 + - Corrigida a vulnerabilidade de travessia de diretório no `express.static`. +- 3.16.6 + - O Node.js 0.10 pode vazar os `fd`s em certas situações que afetam o `express.static` e o + `res.sendfile`. Solicitações maliciosas podem causar os `fd`s a vazar e eventualmente levar a erros de + `EMFILE` e servidores sem capacidade de resposta. +- 3.16.0 + - Matrizes esparsas que possuem índices extremamente altos na sequência de consulta podem fazer com que o processo sofra um + esgotamento de memória e derrubar o servidor. + - Objetos de sequência de consulta extremamente aninhados podem fazer com que o processo fique bloqueado e o servidor + temporariamente não responsivo. +- 3.3.0 + - A resposta 404 de uma tentativa de substituição de um método não suportado era suscetível a ataques de cross-site scripting. \ No newline at end of file diff --git a/pt-br/api.md b/pt-br/api.md old mode 100755 new mode 100644 index 738fba44cf..d12a98b4f7 --- a/pt-br/api.md +++ b/pt-br/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - Referência de API -lang: pt-br +layout: api +version: 5x +title: Express 5.x - Referência da API +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api +redirect_from: " " --- -
    - -

    API 4.x

    - - - {% include api/en/4x/express.md %} +
    +

    5.x API

    + {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
    diff --git a/pt-br/changelog/index.md b/pt-br/changelog/index.md new file mode 100644 index 0000000000..2456265b18 --- /dev/null +++ b/pt-br/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/pt-br/guide/behind-proxies.md b/pt-br/guide/behind-proxies.md old mode 100755 new mode 100644 index 93b194f942..17c2d2f0cd --- a/pt-br/guide/behind-proxies.md +++ b/pt-br/guide/behind-proxies.md @@ -1,25 +1,24 @@ --- layout: page title: Express atrás de proxies +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: pt-br +redirect_from: " " --- # Express atrás de proxies +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy. + +
    +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates. +
    + Ao executar um aplicativo do Express atrás de um proxy, configure (usando [app.set()](/{{ page.lang }}/4x/api.html#app.set)) a variável do aplicativo `trust proxy` para um dos valores listados na seguinte tabela. -
    -Apesar de a execução do aplicativo não falhar se a variável do -aplicativo `trust proxy` não estiver configurada, -ele irá registrar incorretamente o endereço de IP do proxy como o -endereço de IP do cliente a não ser que o `trust -proxy` esteja configurado. -
    - @@ -33,60 +32,66 @@ Se `false`, o aplicativo é compreendido como exposto diretamente à Internet e o endereço de IP do cliente é derivado a partir do `req.connection.remoteAddress`. Esta é a configuração padrão. + +
    +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
    - + - +
    TipoValor
    Endereços IPIP addresses -Um endereço de IP, sub-rede, ou uma matriz de endereços de IP e -sub-redes confiáveis. A lista a seguir mostra os nomes de sub-rede -pré-configurados: +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` +- loopback - `127.0.0.1/8`, `::1/128` +- linklocal - `169.254.0.0/16`, `fe80::/10` +- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` É possível configurar endereços de IP de qualquer uma das formas a seguir: -
    -app.set('trust proxy', 'loopback') // specify a single subnet
    +```js
    +app.set('trust proxy', 'loopback') // specify a single subnet
     app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
     app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
    -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
    -
    +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` Quando especificados, os endereços de IP ou sub-redes são excluídos do processo de determinação de endereço, e o endereço de IP não confiável mais próximos do servidor de aplicativos é -determinado como o endereço de IP do cliente. +determinado como o endereço de IP do cliente. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. +
    Número -Confia no `n`-ésimo hop a partir do servidor de -proxy frontal como o cliente. +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. + +
    +When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
    FunçãoFunction -Implementação de confiança customizada. Use apenas se souber o que está fazendo. -
    -app.set('trust proxy', function (ip) {
    -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
    -  else return false;
    -});
    -
    +Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
    -Configurando um valor não-`false` para o -`trust -proxy` resulta em três mudanças importantes: +Enabling `trust proxy` will have the following impact:
    • O valor de [req.hostname](/{{ page.lang }}/api.html#req.hostname) é diff --git a/pt-br/guide/database-integration.md b/pt-br/guide/database-integration.md old mode 100755 new mode 100644 index 0572f9ff51..eb3fe81c84 --- a/pt-br/guide/database-integration.md +++ b/pt-br/guide/database-integration.md @@ -1,8 +1,9 @@ --- layout: page title: Integração de banco de dados do Express +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: pt-br +redirect_from: " " --- # Integração de Banco de dados @@ -11,355 +12,483 @@ A inclusão da capacidade de se conectar à banco de dados em aplicativos do Exp Node.js apropriado para o banco de dados no seu aplicativo. Este documento explica brevemente como incluir e utilizar alguns dos mais populares módulos do Node.js para sistemas de bancos de dados no seu aplicativo do Express: -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongo) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgres) +- [Redis](#redis) +- +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
      Estes drivers de banco de dados estão entre os muitos que estão disponíveis. Para obter outras opções, procure no site [npm](https://www.npmjs.com/).
      - - ## Cassandra **Módulo**: [cassandra-driver](https://github.com/datastax/nodejs-driver) **Instalação** -
      -
      +### Installation
      +
      +```bash
       $ npm install cassandra-driver
      -
      -
      +``` + +### Exemplo + +```js +const cassandra = require('cassandra-driver') +const client = new cassandra.Client({ contactPoints: ['localhost'] }) + +client.execute('select key from system.local', (err, result) => { + if (err) throw err + console.log(result.rows[0]) +}) +``` -**Exemplo** +## Couchbase -
      -
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      +**Module**: [couchnode](https://github.com/couchbase/couchnode)
       
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      -
      +### Installation - +```bash +$ npm install couchbase +``` + +### Exemplo + +```js +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') + +// add a document to a bucket +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) + +// get all documents with shoe size 13 +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) +``` ## CouchDB **Módulo**: [nano](https://github.com/dscape/nano) **Instalação** -
      -
      +### Installation
      +
      +```bash
       $ npm install nano
      -
      -
      +``` -**Exemplo** +### Exemplo -
      -
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      +```js
      +const nano = require('nano')('http://localhost:5984')
      +nano.db.create('books')
      +const books = nano.db.use('books')
       
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      +// Insert a book document in the books database
      +books.insert({ name: 'The Art of war' }, null, (err, body) => {
      +  if (err) {
      +    console.log(err)
      +  } else {
      +    console.log(body)
         }
      -});
      +})
       
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      -
      - - +// Get a list of all books +books.list((err, body) => { + if (err) { + console.log(err) + } else { + console.log(body.rows) + } +}) +``` ## LevelDB **Módulo**: [levelup](https://github.com/rvagg/node-levelup) **Instalação** -
      -
      -$ npm install level levelup leveldown
      -
      -
      +### Installation -**Exemplo** +```bash +$ npm install level levelup leveldown +``` -
      -
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      +### Exemplo
       
      -db.put('name', 'LevelUP', function (err) {
      +```js
      +const levelup = require('levelup')
      +const db = levelup('./mydb')
       
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      +db.put('name', 'LevelUP', (err) => {
      +  if (err) return console.log('Ooops!', err)
       
      -});
      -
      -
      + db.get('name', (err, value) => { + if (err) return console.log('Ooops!', err) - + console.log(`name=${value}`) + }) +}) +``` ## MySQL **Módulo**: [mysql](https://github.com/felixge/node-mysql/) **Instalação** -
      -
      +### Installation
      +
      +```bash
       $ npm install mysql
      -
      -
      +``` -**Exemplo** +### Exemplo -
      -
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      +```js
      +const mysql = require('mysql')
      +const connection = mysql.createConnection({
      +  host: 'localhost',
      +  user: 'dbuser',
      +  password: 's3kreee7',
      +  database: 'my_db'
      +})
       
      -connection.connect();
      +connection.connect()
       
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
      +  if (err) throw err
       
      -connection.end();
      -
      -
      + console.log('The solution is: ', rows[0].solution) +}) - +connection.end() +``` ## MongoDB **Módulo**: [mongodb](https://github.com/mongodb/node-mongodb-native) **Instalação** -
      -
      +### Installation
      +
      +```bash
       $ npm install mongodb
      -
      -
      +``` -**Exemplo** +### Example (v2.\*) -
      -
      -var MongoClient = require('mongodb').MongoClient;
      +```js
      +const MongoClient = require('mongodb').MongoClient
       
      -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
      -  if (err) {
      -    throw err;
      -  }
      -  db.collection('mammals').find().toArray(function(err, result) {
      -    if (err) {
      -      throw err;
      -    }
      -    console.log(result);
      -  });
      -});
      -
      -
      +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { + if (err) throw err + + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +### Example (v3.\*) + +```js +const MongoClient = require('mongodb').MongoClient + +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { + if (err) throw err + + const db = client.db('animals') + + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` Se desejar um driver de modelo de objeto para o MongoDB, consulte em [Mongoose](https://github.com/LearnBoost/mongoose). - - ## Neo4j **Módulo**: [apoc](https://github.com/hacksparrow/apoc) **Instalação** -
      -
      -$ npm install apoc
      -
      -
      +### Installation -**Exemplo** +```bash +$ npm install neo4j-driver +``` -
      -
      -var apoc = require('apoc');
      +### Exemplo
       
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      -  }
      -);
      -
      -
      +```js +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) - +const session = driver.session() -## PostgreSQL +session.readTransaction((tx) => { + return tx.run('MATCH (n) RETURN count(n) AS count') + .then((res) => { + console.log(res.records[0].get('count')) + }) + .catch((error) => { + console.log(error) + }) +}) +``` + +## Oracle **Módulo**: [pg](https://github.com/brianc/node-postgres) **Instalação** -
      -
      -$ npm install pg
      -
      -
      +### Installation -**Exemplo** +NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). -
      -
      -var pg = require('pg');
      -var conString = "postgres://username:password@localhost/database";
      +```bash
      +$ npm install oracledb
      +```
       
      -pg.connect(conString, function(err, client, done) {
      +### Exemplo
       
      -  if (err) {
      -    return console.error('error fetching client from pool', err);
      -  }
      -  client.query('SELECT $1::int AS number', ['1'], function(err, result) {
      -    done();
      -    if (err) {
      -      return console.error('error running query', err);
      +```js
      +const oracledb = require('oracledb')
      +const config = {
      +  user: '',
      +  password: '',
      +  connectString: 'localhost:1521/orcl'
      +}
      +
      +async function getEmployee (empId) {
      +  let conn
      +
      +  try {
      +    conn = await oracledb.getConnection(config)
      +
      +    const result = await conn.execute(
      +      'select * from employees where employee_id = :id',
      +      [empId]
      +    )
      +
      +    console.log(result.rows[0])
      +  } catch (err) {
      +    console.log('Ouch!', err)
      +  } finally {
      +    if (conn) { // conn assignment worked, need to close
      +      await conn.close()
           }
      -    console.log(result.rows[0].number);
      -  });
      +  }
      +}
       
      -});
      -
      -
      +getEmployee(101) +``` - +## PostgreSQL + +**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise) + +### Installation + +```bash +$ npm install pg-promise +``` + +### Exemplo + +```js +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') + +db.one('SELECT $1 AS value', 123) + .then((data) => { + console.log('DATA:', data.value) + }) + .catch((error) => { + console.log('ERROR:', error) + }) +``` ## Redis **Módulo**: [redis](https://github.com/mranney/node_redis) **Instalação** -
      -
      +### Installation
      +
      +```bash
       $ npm install redis
      -
      -
      +``` + +### Exemplo + +```js +const redis = require('redis') +const client = redis.createClient() -**Exemplo** +client.on('error', (err) => { + console.log(`Error ${err}`) +}) -
      -
      -var client = require('redis').createClient();
      +client.set('string key', 'string val', redis.print)
      +client.hset('hash key', 'hashtest 1', 'some value', redis.print)
      +client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
       
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      +client.hkeys('hash key', (err, replies) => {
      +  console.log(`${replies.length} replies:`)
       
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      +  replies.forEach((reply, i) => {
      +    console.log(`    ${i}: ${reply}`)
      +  })
       
      -client.hkeys('hash key', function (err, replies) {
      +  client.quit()
      +})
      +```
       
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      +## SQL Server
       
      -  client.quit();
      +**Module**: [tedious](https://github.com/tediousjs/tedious)
       
      -});
      -
      -
      +### Installation - +```bash +$ npm install tedious +``` + +### Exemplo + +```js +const Connection = require('tedious').Connection +const Request = require('tedious').Request + +const config = { + server: 'localhost', + authentication: { + type: 'default', + options: { + userName: 'your_username', // update me + password: 'your_password' // update me + } + } +} + +const connection = new Connection(config) + +connection.on('connect', (err) => { + if (err) { + console.log(err) + } else { + executeStatement() + } +}) + +function executeStatement () { + request = new Request("select 123, 'hello world'", (err, rowCount) => { + if (err) { + console.log(err) + } else { + console.log(`${rowCount} rows`) + } + connection.close() + }) + + request.on('row', (columns) => { + columns.forEach((column) => { + if (column.value === null) { + console.log('NULL') + } else { + console.log(column.value) + } + }) + }) + + connection.execSql(request) +} +``` ## SQLite **Módulo**: [sqlite3](https://github.com/mapbox/node-sqlite3) **Instalação** -
      -
      -$ npm install sqlite3
      -
      -
      +### Installation -**Exemplo** +```bash +$ npm install sqlite3 +``` -
      -
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      +### Exemplo
       
      -db.serialize(function() {
      +```js
      +const sqlite3 = require('sqlite3').verbose()
      +const db = new sqlite3.Database(':memory:')
       
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      +db.serialize(() => {
      +  db.run('CREATE TABLE lorem (info TEXT)')
      +  const stmt = db.prepare('INSERT INTO lorem VALUES (?)')
       
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      +  for (let i = 0; i < 10; i++) {
      +    stmt.run(`Ipsum ${i}`)
         }
       
      -  stmt.finalize();
      +  stmt.finalize()
       
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      +  db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
      +    console.log(`${row.id}: ${row.info}`)
      +  })
      +})
       
      -db.close();
      -
      -
      - - +db.close() +``` ## ElasticSearch **Módulo**: [elasticsearch](https://github.com/elastic/elasticsearch-js) **Instalação** -
      -
      +### Installation
      +
      +```bash
       $ npm install elasticsearch
      -
      -
      +``` -**Exemplo** +### Exemplo -
      -
      -var elasticsearch = require('elasticsearch');
      -var client = elasticsearch.Client({
      +```js
      +const elasticsearch = require('elasticsearch')
      +const client = elasticsearch.Client({
         host: 'localhost:9200'
      -});
      +})
       
       client.search({
         index: 'books',
      @@ -372,10 +501,9 @@ client.search({
             }
           }
         }
      -}).then(function(response) {
      -  var hits = response.hits.hits;
      -}, function(error) {
      -  console.trace(error.message);
      -});
      -
      -
      +}).then((response) => { + const hits = response.hits.hits +}, (error) => { + console.trace(error.message) +}) +``` diff --git a/pt-br/guide/debugging.md b/pt-br/guide/debugging.md old mode 100755 new mode 100644 index 4431cfd07b..a7e0a61f4c --- a/pt-br/guide/debugging.md +++ b/pt-br/guide/debugging.md @@ -1,47 +1,31 @@ --- layout: page title: Depurando o Express +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: pt-br +redirect_from: " " --- # Depurando o Express -O Express usa o módulo de [depuração](https://www.npmjs.com/package/debug) -internamente para registrar informações de log sobre a correspondência de rotas, as funções middleware que estão em uso, o modo de -aplicativo, e o fluxo do ciclo solicitação-resposta. - -
      -O `debug` é como uma versão aumentada do `console.log` mas, diferente do -`console.log`, não é preciso comentar os logs de -`debug` no código na produção. O registro de logs -está desligado por padrão e podem ser ligados condicionadamente -usando a variável de ambiente `DEBUG`. -
      - Para ver todos os logs interno usados no Express, configure a variável de ambiente `DEBUG` para `express:*` ao ativar seu aplicativo. -
      -
      +```bash
       $ DEBUG=express:* node index.js
      -
      -
      +``` No Windows, use o comando correspondente. -
      -
      -> set DEBUG=express:* & node index.js
      -
      -
      +```bash +> $env:DEBUG = "express:*"; node index.js +``` Executar este comando no aplicativo padrão gerado pelo [express generator](/{{ page.lang }}/starter/generator.html) imprime a seguinte saída: -
      -
      +```bash
       $ DEBUG=express:* node ./bin/www
         express:router:route new / +0ms
         express:router:layer new / +1ms
      @@ -77,20 +61,18 @@ $ DEBUG=express:* node ./bin/www
         express:router:layer new / +1ms
         express:router use /users router +0ms
         express:router:layer new /users +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -
      -
      +``` Quando uma solicitação é feita em seguida para o aplicativo, você verá os logs especificados no código do Express: -
      -
      +```bash
         express:router dispatching GET / +4h
         express:router query  : / +2ms
         express:router expressInit  : / +0ms
      @@ -106,8 +88,7 @@ você verá os logs especificados no código do Express:
         express:view lookup "index.pug" +338ms
         express:view stat "/projects/example/views/index.pug" +0ms
         express:view render "/projects/example/views/index.pug" +1ms
      -
      -
      +``` Para ver os logs apenas da implementação do roteador configure o valor de `DEBUG` para @@ -126,20 +107,37 @@ Por exemplo, se você gerou o aplicativo com o `$ express sample-app`, é possível ativar as instruções de depuração com o seguinte comando: -
      -
      +```bash
       $ DEBUG=sample-app:* node ./bin/www
      -
      -
      +``` É possível especificar mais do que um namespace de depuração designando uma lista de nomes separados por vírgulas: -
      -
      +```bash
       $ DEBUG=http,mail,express:* node index.js
      -
      -
      +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -Para obter mais informações sobre `debug`, -consulte o [debug](https://www.npmjs.com/package/debug). +{% include admonitions/note.html content=debug-text %} diff --git a/pt-br/guide/error-handling.md b/pt-br/guide/error-handling.md old mode 100755 new mode 100644 index d757e7362d..91716000a9 --- a/pt-br/guide/error-handling.md +++ b/pt-br/guide/error-handling.md @@ -1,48 +1,241 @@ --- layout: page title: Manipulação de erros do Express +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: pt-br +redirect_from: " " --- # Manipulação de erros +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. + +## Catching Errors + +It's important to ensure that Express catches all errors that occur while +running route handlers and middleware. + +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. Por exemplo: + +```js +app.get('/', (req, res) => { + throw new Error('BROKEN') // Express will catch this on its own. +}) +``` + Defina funções de middleware de manipulação de erros da mesma forma que outras funções de middleware, exceto que funções de manipulação de erros possuem quatro argumentos ao invés de três: +`(err, req, res, next)`. 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) + } + }) +}) +``` + +Se você tiver um manipulador de rota com as funções de retorno +de chamada é possível usar o parâmetro `route` +para ignorar o próximo manipulador de rota. +Por exemplo: + +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` + +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. + +Se passar qualquer coisa para a função `next()` +(exceto a sequência de caracteres `'route'`), +o Express considera a solicitação atual como estando em erro e irá +ignorar quaisquer funções restantes de roteamento e middleware que +não sejam de manipulação de erros. + +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') + } +]) +``` + +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. Por exemplo: + +```js +app.get('/', (req, res, next) => { + 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. + +Use promises to avoid the overhead of the `try...catch` block or when using functions +that return promises. Por exemplo: + +```js +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { + throw new Error('BROKEN') + }).catch(next) // Errors will be passed to Express. +}) +``` + +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. + +You could also use a chain of handlers to rely on synchronous error +catching, by reducing the asynchronous code to something trivial. Por exemplo: + +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +The above example has a couple of trivial statements from 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 +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. + +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. + +## O Manipulador de Erros Padrão + +O Express vem com um manipulador de erros integrado, que cuida +de qualquer erro que possa ser encontrado no aplicativo. Essa função +de middleware de manipulação de erros padrão é incluída no final da +pilha de funções de middleware. + +se você passar um erro para o `next()` e você +não manipulá-lo com um manipulador de erros, ele irá ser manipulado +por um manipulador de erros integrado; o erro será escrito no cliente +com o rastreio de pilha. O rastreio de pilha não será incluído no +ambiente de produção. + +
      +Configura a variável de ambiente `NODE_ENV` para +`production`, para executar o aplicativo em modo de +produção. +
      + +When an error is written, the following information is added to the +response: + +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. + +Se você chamar o `next()` com um erro após ter +inicializado escrevendo a resposta (por exemplo, se encontrar um erro +enquanto passa a resposta ao cliente) o manipulador de erros padrão do +Express fecha a conexão e falha a solicitação. + +Portanto ao incluir um manipulador de erro customizado, você +desejará delegar para o mecanismo de manipulação de erros padrão no +Express, quando os cabeçalhos já tiverem sido enviados para o cliente: + +```js +function errorHandler (err, req, res, next) { + if (res.headersSent) { + return next(err) + } + res.status(500) + res.render('error', { error: err }) +} +``` + +Note that the default error handler can get triggered if you call `next()` with an error +in your code more than once, even if custom error handling middleware is in place. + +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html). + +## Writing error handlers + +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)`. Por exemplo: -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Você define os middlewares de manipulação de erros por último, após outros `app.use()` e chamads de rota; por exemplo: -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +```js
      +const bodyParser = require('body-parser')
      +const methodOverride = require('method-override')
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      +app.use(bodyParser.urlencoded({
      +  extended: true
      +}))
      +app.use(bodyParser.json())
      +app.use(methodOverride())
      +app.use((err, req, res, next) => {
         // logic
      -});
      -
      -
      +}) +``` Repostas de dentro de uma função de middleware podem estar em qualquer formato que preferir, como uma página HTML de erros, uma mensagem simples, ou uma sequência de caracteres JSON. - Para propósitos organizacionais (e estrutura de alto nível), é possível definir várias funções de middleware de manipulação de erros, de forma muito parecida como você faria com funções de @@ -50,92 +243,74 @@ middleware comuns. Por exemplo, se desejar definir um manipulador de erros para solicitações feitas usando o `XHR`, e aqueles sem, você pode usar os seguintes comandos: +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      -
      +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use(logErrors) +app.use(clientErrorHandler) +app.use(errorHandler) +``` Neste exemplo, o `logErrors` genérico pode escrever informações de solicitações e erros no `stderr`, por exemplo: -
      -
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      +```js
      +function logErrors (err, req, res, next) {
      +  console.error(err.stack)
      +  next(err)
       }
      -
      -
      +``` Também neste exemplo, o `clientErrorHandler` é definido como segue; neste caso, o erro é explicitamente passado para o próximo: +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. -
      -
      -function clientErrorHandler(err, req, res, next) {
      +```js
      +function clientErrorHandler (err, req, res, next) {
         if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      +    res.status(500).send({ error: 'Something failed!' })
         } else {
      -    next(err);
      +    next(err)
         }
       }
      -
      -
      +``` A função "catch-all" `errorHandler` pode ser implementada como segue: - -
      -
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      +```js
      +function errorHandler (err, req, res, next) {
      +  res.status(500)
      +  res.render('error', { error: err })
       }
      -
      -
      - -Se passar qualquer coisa para a função `next()` -(exceto a sequência de caracteres `'route'`), -o Express considera a solicitação atual como estando em erro e irá -ignorar quaisquer funções restantes de roteamento e middleware que -não sejam de manipulação de erros. Se desejar manipular este erro de -alguma forma, você terá que criar uma rota de manipulação de erros na -próxima seção. +``` +If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. Por exemplo: -Se você tiver um manipulador de rota com as funções de retorno -de chamada é possível usar o parâmetro `route` -para ignorar o próximo manipulador de rota. Por exemplo: - -
      -
      +```js
       app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      -
      +  (req, res, next) => {
      +    if (!req.user.hasPaid) {
             // continue handling this request
      -      next('route');
      +      next('route')
      +    } else {
      +      next()
           }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      -
      + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` Neste exemplo, o manipulador `getPaidContent` será ignorado mas qualquer manipulador remanescente no @@ -143,55 +318,9 @@ será ignorado mas qualquer manipulador remanescente no `/a_route_behind_paywall` continuariam sendo executados. -
      Chamadas para `next()` e `next(err)` -indicam que o manipulador atual está completo e em qual estado. -`next(err)` irá ignorar todos os manipuladores +indicam que o manipulador atual está completo e em qual estado. `next(err)` irá ignorar todos os manipuladores remanescentes na cadeia exceto por aqueles que estão configurados para manipular erros como descrito acima.
      - -## O Manipulador de Erros Padrão - -O Express vem com um manipulador de erros integrado, que cuida -de qualquer erro que possa ser encontrado no aplicativo. Essa função -de middleware de manipulação de erros padrão é incluída no final da -pilha de funções de middleware. - - -se você passar um erro para o `next()` e você -não manipulá-lo com um manipulador de erros, ele irá ser manipulado -por um manipulador de erros integrado; o erro será escrito no cliente -com o rastreio de pilha. O rastreio de pilha não será incluído no -ambiente de produção. - - -
      -Configura a variável de ambiente `NODE_ENV` para -`production`, para executar o aplicativo em modo de -produção. -
      - -Se você chamar o `next()` com um erro após ter -inicializado escrevendo a resposta (por exemplo, se encontrar um erro -enquanto passa a resposta ao cliente) o manipulador de erros padrão do -Express fecha a conexão e falha a solicitação. - - -Portanto ao incluir um manipulador de erro customizado, você -desejará delegar para o mecanismo de manipulação de erros padrão no -Express, quando os cabeçalhos já tiverem sido enviados para o cliente: - - -
      -
      -function errorHandler(err, req, res, next) {
      -  if (res.headersSent) {
      -    return next(err);
      -  }
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      diff --git a/pt-br/guide/migrating-4.md b/pt-br/guide/migrating-4.md old mode 100755 new mode 100644 index 4932b0909c..ffeafaef8e --- a/pt-br/guide/migrating-4.md +++ b/pt-br/guide/migrating-4.md @@ -1,8 +1,9 @@ --- layout: page title: Migrando para o Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: pt-br +redirect_from: " " --- # Migrando para o Express 4 @@ -25,8 +26,7 @@ Este artigo cobre: Existem várias mudanças significativas no Express 4:
        -
      • Mudanças no núcleo e sistemas middleware do Express. As -dependências no Connect e middlewares integrados foram removidos, de forma que você mesmo deve incluir os middlewares. +
      • Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
      • Mudanças no sistema de roteamento.
      • Várias outras mudanças.
      • @@ -34,8 +34,8 @@ dependências no Connect e middlewares integrados foram removidos, de forma que Consulte também: -* [Novos recursos no 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrando do 3.x para o 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [Novos recursos no 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [Migrando do 3.x para o 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

        Mudanças no núcleo e sistemas middleware do Express @@ -57,7 +57,7 @@ Sem os middlewares integrados, você deve incluir explicitamente todos os middle A tabela a seguir lista os middlewares do Express 3 e suas contrapartes no Express 4. - + @@ -89,7 +89,7 @@ A tabela a seguir lista os middlewares do Express 3 e suas contrapartes no Expre -
        Express 3Express 4
        Express 3Express 4
        express.bodyParser body-parser + multer
        serve-index
        express.static serve-static
        + Aqui está a [lista completa](https://github.com/senchalabs/connect#middleware) de middlewares do Express 4. @@ -102,14 +102,13 @@ definir o caminho onde as funções do middleware estão carregadas, e em seguida ler o valor do parâmetro a partir do manipulador de rota. Por exemplo: -
        -
        -app.use('/book/:id', function(req, res, next) {
        -  console.log('ID:', req.params.id);
        -  next();
        -});
        -
        -
        +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` +

        O sistema de roteamento

        @@ -124,10 +123,11 @@ sistema de roteamento possui dois novos recursos para ajudá-lo a organizar suas rotas: {: .doclist } -* Um novo método, `app.route()`, para criar -manipuladores de rotas encadeáveis para um caminho de rota. -* Uma nova classe, `express.Router`, para -criar manipuladores de rotas modulares montáveis + +- Um novo método, `app.route()`, para criar + manipuladores de rotas encadeáveis para um caminho de rota. +- Uma nova classe, `express.Router`, para + criar manipuladores de rotas modulares montáveis

        O método app.route()

        @@ -139,20 +139,18 @@ obter mais informações sobre rotas, consulte a [`documentação do Router()` ] Aqui está um exemplo de manipuladores de rotas encadeáveis que são definidos usando a função `app.route()`. -
        -
        +```js
         app.route('/book')
        -  .get(function(req, res) {
        -    res.send('Get a random book');
        +  .get((req, res) => {
        +    res.send('Get a random book')
        +  })
        +  .post((req, res) => {
        +    res.send('Add a book')
           })
        -  .post(function(req, res) {
        -    res.send('Add a book');
        +  .put((req, res) => {
        +    res.send('Update the book')
           })
        -  .put(function(req, res) {
        -    res.send('Update the book');
        -  });
        -
        -
        +```

        classe express.Router

        @@ -170,38 +168,36 @@ Por exemplo, cria um arquivo roteador chamado `birds.js` no diretório do aplicativo, com o conteúdo a seguir: -
        -
        -var express = require('express');
        -var router = express.Router();
        +```js
        +var express = require('express')
        +var router = express.Router()
         
         // middleware specific to this router
        -router.use(function timeLog(req, res, next) {
        -  console.log('Time: ', Date.now());
        -  next();
        -});
        +router.use((req, res, next) => {
        +  console.log('Time: ', Date.now())
        +  next()
        +})
         // define the home page route
        -router.get('/', function(req, res) {
        -  res.send('Birds home page');
        -});
        +router.get('/', (req, res) => {
        +  res.send('Birds home page')
        +})
         // define the about route
        -router.get('/about', function(req, res) {
        -  res.send('About birds');
        -});
        +router.get('/about', (req, res) => {
        +  res.send('About birds')
        +})
         
        -module.exports = router;
        -
        -
        +module.exports = router +``` Em seguida, carregue o módulo roteador no aplicativo: -
        -
        -var birds = require('./birds');
        -...
        -app.use('/birds', birds);
        -
        -
        +```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` O aplicativo será agora capaz de manipular solicitações aos caminhos `/birds` e `/birds/about`, @@ -215,7 +211,7 @@ Outras mudanças A seguinte tabela lista outras pequenas, porém importantes, mudanças no Express 4: - + @@ -328,7 +324,7 @@ cookie. Use `res.cookie()` para funcionalidades adicionais. -
        Objeto Descrição
        +

        Exemplo de migração de aplicativo

        @@ -344,49 +340,46 @@ Aplicativo da Versão 3 Considere um aplicativo do Express v.3 com o seguinte arquivo `app.js`: -
        -
        -var express = require('express');
        -var routes = require('./routes');
        -var user = require('./routes/user');
        -var http = require('http');
        -var path = require('path');
        +```js
        +var express = require('express')
        +var routes = require('./routes')
        +var user = require('./routes/user')
        +var http = require('http')
        +var path = require('path')
         
        -var app = express();
        +var app = express()
         
         // all environments
        -app.set('port', process.env.PORT || 3000);
        -app.set('views', path.join(__dirname, 'views'));
        -app.set('view engine', 'pug');
        -app.use(express.favicon());
        -app.use(express.logger('dev'));
        -app.use(express.methodOverride());
        -app.use(express.session({ secret: 'your secret here' }));
        -app.use(express.bodyParser());
        -app.use(app.router);
        -app.use(express.static(path.join(__dirname, 'public')));
        +app.set('port', process.env.PORT || 3000)
        +app.set('views', path.join(__dirname, 'views'))
        +app.set('view engine', 'pug')
        +app.use(express.favicon())
        +app.use(express.logger('dev'))
        +app.use(express.methodOverride())
        +app.use(express.session({ secret: 'your secret here' }))
        +app.use(express.bodyParser())
        +app.use(app.router)
        +app.use(express.static(path.join(__dirname, 'public')))
         
         // development only
        -if ('development' == app.get('env')) {
        -  app.use(express.errorHandler());
        +if (app.get('env') === 'development') {
        +  app.use(express.errorHandler())
         }
         
        -app.get('/', routes.index);
        -app.get('/users', user.list);
        +app.get('/', routes.index)
        +app.get('/users', user.list)
         
        -http.createServer(app).listen(app.get('port'), function(){
        -  console.log('Express server listening on port ' + app.get('port'));
        -});
        -
        -
        +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

        package.json

        O arquivo `package.json` que acompanha a versão 3 pode parecer com algo assim: -
        -
        +```json
         {
           "name": "application-name",
           "version": "0.0.1",
        @@ -399,8 +392,7 @@ versão 3 pode parecer com algo assim:
             "pug": "*"
           }
         }
        -
        -
        +```

        Processo @@ -411,26 +403,24 @@ necessários para o aplicativo Express 4 e atualizando o Express e o Pug para as suas respectivas versões mais recentes com o seguinte comando: -
        -
        +```bash
         $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
        -
        -
        +``` Faça as seguintes alterações no `app.js`: 1. As funções de middleware integradas do Express `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` e - `express.errorHandler` não estão mais disponíveis no objeto `express`. É -preciso instalar manualmente as alternativas e carregá-las no aplicativo. + `express.logger`, `express.methodOverride`, + `express.session`, `express.bodyParser` e + `express.errorHandler` não estão mais disponíveis no objeto `express`. É + preciso instalar manualmente as alternativas e carregá-las no aplicativo. 2. Não é mais necessário carregar a função `app.router`. - Ela não é um objeto válido para aplicativos Express 4, portanto -remova o código do `app.use(app.router);`. + Ela não é um objeto válido para aplicativos Express 4, portanto + remova o código do `app.use(app.router);`. 3. Certifique-se deque as funções de middleware sejam carregadas na ordem correta - carregar a -`errorHandler` após carregar as rotas de aplicativo. + `errorHandler` após carregar as rotas de aplicativo.

        Aplicativo da Versão 4

        @@ -439,8 +429,7 @@ remova o código do `app.use(app.router);`. A execução do comando `npm` acima irá atualizar o `package.json` como a seguir: -
        -
        +```json
         {
           "name": "application-name",
           "version": "0.0.1",
        @@ -453,79 +442,80 @@ atualizar o `package.json` como a seguir:
             "errorhandler": "^1.1.1",
             "express": "^4.8.0",
             "express-session": "^1.7.2",
        -    "pug": "^2.0.0-beta6",
        +    "pug": "^2.0.0",
             "method-override": "^2.1.2",
             "morgan": "^1.2.2",
             "multer": "^0.1.3",
             "serve-favicon": "^2.0.1"
           }
         }
        -
        -
        +```

        app.js

        Em seguida, remova o código inválido, carregue o middleware necessário e faça outras alterações conforme necessárias. O arquivo `app.js` irá parecer com isso: -
        -
        -var http = require('http');
        -var express = require('express');
        -var routes = require('./routes');
        -var user = require('./routes/user');
        -var path = require('path');
        +```js
        +var http = require('http')
        +var express = require('express')
        +var routes = require('./routes')
        +var user = require('./routes/user')
        +var path = require('path')
         
        -var favicon = require('serve-favicon');
        -var logger = require('morgan');
        -var methodOverride = require('method-override');
        -var session = require('express-session');
        -var bodyParser = require('body-parser');
        -var multer = require('multer');
        -var errorHandler = require('errorhandler');
        +var favicon = require('serve-favicon')
        +var logger = require('morgan')
        +var methodOverride = require('method-override')
        +var session = require('express-session')
        +var bodyParser = require('body-parser')
        +var multer = require('multer')
        +var errorHandler = require('errorhandler')
         
        -var app = express();
        +var app = express()
         
         // all environments
        -app.set('port', process.env.PORT || 3000);
        -app.set('views', path.join(__dirname, 'views'));
        -app.set('view engine', 'pug');
        -app.use(favicon(__dirname + '/public/favicon.ico'));
        -app.use(logger('dev'));
        -app.use(methodOverride());
        -app.use(session({ resave: true,
        -                  saveUninitialized: true,
        -                  secret: 'uwotm8' }));
        -app.use(bodyParser.json());
        -app.use(bodyParser.urlencoded({ extended: true }));
        -app.use(multer());
        -app.use(express.static(path.join(__dirname, 'public')));
        -
        -app.get('/', routes.index);
        -app.get('/users', user.list);
        +app.set('port', process.env.PORT || 3000)
        +app.set('views', path.join(__dirname, 'views'))
        +app.set('view engine', 'pug')
        +app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
        +app.use(logger('dev'))
        +app.use(methodOverride())
        +app.use(session({
        +  resave: true,
        +  saveUninitialized: true,
        +  secret: 'uwotm8'
        +}))
        +app.use(bodyParser.json())
        +app.use(bodyParser.urlencoded({ extended: true }))
        +app.use(multer())
        +app.use(express.static(path.join(__dirname, 'public')))
        +
        +app.get('/', routes.index)
        +app.get('/users', user.list)
         
         // error handling middleware should be loaded after the loading the routes
        -if ('development' == app.get('env')) {
        -  app.use(errorHandler());
        +if (app.get('env') === 'development') {
        +  app.use(errorHandler())
         }
         
        -var server = http.createServer(app);
        -server.listen(app.get('port'), function(){
        -  console.log('Express server listening on port ' + app.get('port'));
        -});
        -
        -
        +var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```
        A não ser que precise trabalhar diretamente com o módulo `http` (socket.io/SPDY/HTTPS), carregá-lo não é necessário, e o aplicativo pode ser iniciado simplesmente desta forma: -
        -app.listen(app.get('port'), function(){
        -  console.log('Express server listening on port ' + app.get('port'));
        -});
        -
        + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +

        Execute o aplicativo

        @@ -534,14 +524,12 @@ O processo de migração está concluído, e o aplicativo é agora um aplicativo Express 4. Para confirmar, inicie o aplicativo usando o seguinte comando: -
        -
        +```bash
         $ node .
        -
        -
        +``` Carregue [http://localhost:3000](http://localhost:3000) - e veja a página inicial sendo renderizada pelo Express 4. +e veja a página inicial sendo renderizada pelo Express 4.

        Fazendo o upgrade para o gerador de aplicativos do Express 4

        @@ -556,25 +544,21 @@ aplicativos Express 3 e, em seguida, instalar o novo `express-generator`. Se já tiver o gerador de aplicativos do Express 3 instalado no seu sistema, é preciso desinstalá-lo: -
        -
        +```bash
         $ npm uninstall -g express
        -
        -
        +``` + Dependendo de como os seus privilégios de arquivos e diretórios estão configurados, pode ser necessário executar este comando com `sudo`. Agora instale o novo gerador: -
        -
        +```bash
         $ npm install -g express-generator
        -
        -
        +``` -Dependendo de como os seus privilégios de arquivos e diretórios -estão configurados, pode ser necessário executar este comando com -`sudo`. +Dependendo de como os seus privilégios de arquivos e diretórios estão +configurados, pode ser necessário executar este comando com `sudo`. Agora o comando `express` no seu sistema está atualizado para o gerador do Express 4. @@ -585,20 +569,19 @@ As opções e o uso do comando permanecem em grande parte as mesmas, com as seguintes exceções: {: .doclist } -* Foi removida a opção `--sessions`. -* Foi removida a opção `--jshtml`. -* Foi incluída a opção `--hogan` para -suportar o [Hogan.js](http://twitter.github.io/hogan.js/). + +- Foi removida a opção `--sessions`. +- Foi removida a opção `--jshtml`. +- Foi incluída a opção `--hogan` para + suportar o [Hogan.js](http://twitter.github.io/hogan.js/).

        Exemplo

        Execute o seguinte comando para criar um aplicativo do Express 4: -
        -
        +```bash
         $ express app4
        -
        -
        +``` Se olhar o conteúdo do arquivo `app4/app.js`, você verá que todas as funções de middleware (exceto @@ -614,11 +597,9 @@ gerado pelo antigo gerador. Após instalar as dependências, inicie o aplicativo usando o seguinte comando: -
        -
        +```bash
         $ npm start
        -
        -
        +``` Se olhar o script de inicialização npm no arquivo `package.json`, você irá notar que o comando real @@ -645,24 +626,20 @@ coisas "da maneira do Express 3", exclua a linha que diz `app.js`, em seguida cole o seguinte código em seu lugar: -
        -
        -app.set('port', process.env.PORT || 3000);
        +```js
        +app.set('port', process.env.PORT || 3000)
         
        -var server = app.listen(app.get('port'), function() {
        -  debug('Express server listening on port ' + server.address().port);
        -});
        -
        -
        +var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` Assegure-se de carregar o módulo `debug` em cima do arquivo `app.js` usando o seguinte código: -
        -
        -var debug = require('debug')('app4');
        -
        -
        +```js +var debug = require('debug')('app4') +``` Em seguida, mude o `"start": "node ./bin/www"` no arquivo `package.json` para `"start": "node @@ -670,7 +647,7 @@ app.js"`. Você agora moveu a funcionalidade do `./bin/www` de volta para o -`app.js`. Esta mudança não é recomendada, mas o +`app.js`. Esta mudança não é recomendada, mas o exercício ajuda você a entender como o arquivo `./bin/www` funciona, e porque o arquivo `app.js` não é mais iniciado por conta própria. diff --git a/pt-br/guide/migrating-5.md b/pt-br/guide/migrating-5.md old mode 100755 new mode 100644 index 1f3dd3152e..e37d38455f --- a/pt-br/guide/migrating-5.md +++ b/pt-br/guide/migrating-5.md @@ -1,32 +1,26 @@ --- layout: page title: Migrando para o Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: pt-br +redirect_from: " " --- # Migrando para o Express 5

        Visão Geral

        -O Express 5.0 ainda está no estágio de liberação alfa, mas aqui -está uma prévia das mudanças que estarão na liberação e como migrar -seu aplicativo do Express 4 app para o Express 5. - O Express 5 não é muito diferente do Express 4: As mudanças na -API não são tão significantes quanto as do 3.0 para o 4.0. Apesar de +API não são tão significantes quanto as do 3.0 para o 4.0. Apesar de a API básica permanecer a mesma, ainda existem mudanças disruptivas; em outras palavras um programa do Express 4 existente pode não funcionar se você atualizá-lo para usar o Express 5. -Para instalar o alfa mais recente e ter uma prévia do Express -5, digite o seguinte comando no diretório raiz do seu aplicativo: +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -
        -
        -$ npm install express@5.0.0-alpha.2 --save
        -
        -
        +```sh +npm install "express@5" +``` É possível em seguida executar seus testes automatizados para verificar o que falha, e corrigir os problemas de acordo com as @@ -35,14 +29,25 @@ seu aplicativo para verificar quais erros ocorrem. Você descobrirá imediatamente se o aplicativo utiliza quaisquer métodos ou propriedades que não são suportados. -

        Mudanças no Express 5

        +## Express 5 Codemods + +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: + +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). -Aqui está a lista de mudanças (até a liberação alpha 2) que -irão afetá-lo como um usuário do Express. -Consulte por -[solicitação -de pull](https://github.com/expressjs/express/pull/2237) para obter uma lista de todas funcionalidades -planejadas. +

        Mudanças no Express 5

        **Métodos e propriedades removidas** @@ -54,32 +59,47 @@ planejadas.
      • req.param(name)
      • res.json(obj, status)
      • res.jsonp(obj, status)
      • +
      • res.redirect('back') and res.location('back')
      • +
      • res.redirect(url, status)
      • res.send(body, status)
      • res.send(status)
      • res.sendfile()
      • +
      • router.param(fn)
      • +
      • express.static.mime
      • +
      • express:router debug logs
      -**Mudadas** +**Melhorias** -**Melhorias** +**Mudadas** -

      Métodos e propriedades removidas

      +## Métodos e propriedades removidas Se estiver usando qualquer um desses métodos ou propriedades no seu aplicativo, ele irá quebrar. Portanto, será necessário alterar o seu aplicativo após fazer a atualização para a versão 5. -

      app.del()

      +

      app.del()

      O Express 5 não suporta mais a função `app.del()`. Se você usas esta função um erro será lançado. Para registrar rotas HTTP DELETE, use a função `app.delete()` ao invés disso. @@ -88,28 +108,81 @@ Inicialmente `del` era usada ao invés de `delete`, porque `delete` é uma palavra-chave reservada no JavaScript. Entretanto, a partir do ECMAScript 6, `delete` e outras palavras-chave reservadas podem -legalmente ser usadas como nomes de propriedades. É possível ler a -discussão que levou à descontinuação da função `app.del` aqui. +legalmente ser usadas como nomes de propriedades. + +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` + +{% endcapture %} -

      app.param(fn)

      +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) + +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` + +

      app.param(fn)

      A assinatura `app.param(fn)` foi usada para modificar o comportamento da função `app.param(name, fn)`. Ela foi descontinuada desde a v4.11.0, e o Express 5 não a suporta mais de nenhuma forma. -

      Nomes de métodos pluralizados

      +

      Nomes de métodos pluralizados

      Os seguintes nomes de métodos podem ser pluralizados. No Express 4, o uso dos métodos antigos resultava em um aviso de -descontinuação. O Express 5 não os suporta mais de forma nenhuma: +descontinuação. O Express 5 não os suporta mais de forma nenhuma: Express 5 no longer supports them at all: + +`req.acceptsLanguage()` é substituído por `req.acceptsLanguages()`. `req.acceptsCharset()` é substituído por `req.acceptsCharsets()`. `req.acceptsEncoding()` é substituído por `req.acceptsEncodings()`. -`req.acceptsLanguage()` é substituído por `req.acceptsLanguages()`. +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} -

      Dois pontos no começo (:) do nome do app.param(name, fn)

      +{% include admonitions/note.html content=codemod-pluralized-methods %} + +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

      Dois pontos no começo (:) do nome do app.param(name, fn)

      Um caractere de dois pontos (:) no início do nome para a função `app.param(name, fn)` é um remanescente do Express @@ -122,30 +195,148 @@ Isso não deve afetar o seu código se você seguiu a documentação do Express 4 do [app.param](/{{ page.lang }}/4x/api.html#app.param), já que ela não menciona os dois pontos no início. -

      req.param(name)

      +

      req.param(name)

      Este é um método potencialmente confuso e perigoso de recuperação de dados de formulário foi removido. Você precisará agora especificamente olhar para o nome do parâmetro enviado no objeto `req.params`, `req.body`, ou `req.query`. -

      res.json(obj, status)

      +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

      res.json(obj, status)

      O Express 5 não suporta mais a assinatura `res.json(obj, status)`. Ao invés disso, configure o status e então encadeie-o ao método `res.json()` assim: `res.status(status).json(obj)`. -

      res.jsonp(obj, status)

      +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

      res.jsonp(obj, status)

      O Express 5 não suporta mais a assinatura `res.jsonp(obj, status)`. Ao invés disso, configure o status e então encadeie-o ao método `res.jsonp()` assim: `res.status(status).jsonp(obj)`. -

      res.send(body, status)

      +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

      res.redirect(url, status)

      O Express 5 não suporta mais a assinatura `res.send(obj, status)`. Ao invés disso, configure o status e então encadeie-o ao método `res.send()` assim: `res.status(status).send(obj)`. -

      res.send(status)

      +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

      res.redirect('back') and res.location('back')

      -O Express 5 não suporta mais a assinatura res.send(status), onde *`status`* +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

      res.send(body, status)

      + +Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) + +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` + +

      res.send(status)

      + +O Express 5 não suporta mais a assinatura res.send(status), onde _`status`_ é um número. Ao invés disso, use a função `res.sendStatus(statusCode)`, que configura o código do status do cabeçalho de resposta HTTP e envia a versão de texto do @@ -157,40 +348,251 @@ converte-lo para um sequência de caracteres, para que o Express não o interprete como uma tentativa de usar a assinatura antiga não suportada. -

      res.sendfile()

      +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) + +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

      res.sendfile()

      A função `res.sendfile()` foi substituída pela versão em formato camel-case `res.sendFile()` no Express 5. -

      Mudadas

      +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

      router.param(fn)

      + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. Ela +foi descontinuada desde a v4.11.0, e o Express 5 não a suporta mais de nenhuma forma. + +

      express.static.mime

      + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

      express:router debug logs

      + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## Mudadas + +

      Path route matching syntax

      + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. Por exemplo: -

      app.router

      +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

      Rejected promises handled from middleware and handlers

      + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

      express.urlencoded

      + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

      express.static dotfiles

      + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

      app.listen

      + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +Por exemplo: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

      app.router

      O objeto `app.router`, que foi removido no Express 4, está de volta no Express 5. Na nove versão, este objeto é apenas uma referência para o roteador Express base, diferentemente do Express 3, onde um aplicativo tinha que carregá-lo explicitamente. -

      req.host

      +

      req.body

      + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

      req.host

      No Express 4, a função `req.host` incorretamente removia o número da porta caso estivesse presente. No Express 5 o número da porta é mantido. -

      req.query

      +

      req.query

      + +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -No Express 4.7 e do Express 5 para frente, o analisador -sintático de consulta pode aceitar `false` para -desativar a análise sintática de sequência de consulta quando desejar -usar sua própria função para a lógica de análise sintática de -sequência de consultas. +

      res.clearCookie

      -

      Melhorias

      +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. -

      res.render()

      +

      res.status

      + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

      res.vary

      + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## Melhorias + +

      res.render()

      Este método agora impinge comportamento assíncrono para todos os mecanismos de visualização, evitando erros causados pelos mecanismos de visualização que tinham uma implementação síncrona e que violavam a interface recomendada. + +

      Brotli encoding support

      + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/pt-br/guide/overriding-express-api.md b/pt-br/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/pt-br/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/pt-br/guide/routing.md b/pt-br/guide/routing.md old mode 100755 new mode 100644 index e0ab105e58..b75f70ce50 --- a/pt-br/guide/routing.md +++ b/pt-br/guide/routing.md @@ -1,31 +1,40 @@ --- layout: page title: Roteamento no Express +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: pt-br +redirect_from: " " --- # Roteamento -O *Roteamento* refere-se à definição de terminais -do aplicativo (URIs) e como eles respondem às solicitações do -cliente. -Para obter uma introdução a roteamento, consulte -[Roteamento básico](/{{ page.lang }}/starter/basic-routing.html). +O _Roteamento_ refere-se a como os _endpoints_ de uma aplicação (URIs) respondem às requisições do cliente. +Para uma introdução ao roteamento, consulte [Roteamento básico](/{{ page.lang }}/starter/basic-routing.html). + +Rotas são definidas utilizando métodos do objeto `app` do Express que correspondem aos métodos HTTP; +por exemplo, `app.get()` para lidar com requisições GET e `app.post()` para requisições POST. Para a lista completa, veja [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). Você também pode utilizar [app.all()](/{{ page.lang }}/4x/api.html#app.all) para lidar com todos os métodos HTTP +e [app.use()](/{{ page.lang }}/4x/api.html#app.use) para especificar middleware como funções _callback_ +(Veja [Usando middlewares](/{{ page.lang }}/guide/using-middleware.html) para mais detalhes). + +Esses métodos de roteamento especificam uma função _callback_ a ser chamada quando a aplicação +recebe uma requisição à rota e método HTTP especificados. Em outras palavras, a aplicação "escuta" +requisições que se encaixam nas rotas e métodos especificados e, quando há alguma correspondência, +chama a função _callback_ especificada. + +Na realidade, métodos de roteamento podem possuir mais de uma função _callback_ como argumento. +Com múltiplas funções, é importante passar `next` como argumento da função e chamar `next()` para passar o controle para a próxima. O código a seguir é um exemplo de uma rota muito básica. -
      -
      -var express = require('express');
      -var app = express();
      +```js
      +const express = require('express')
      +const app = express()
       
       // respond with "hello world" when a GET request is made to the homepage
      -app.get('/', function(req, res) {
      -  res.send('hello world');
      -});
      -
      -
      +app.get('/', (req, res) => { + res.send('hello world') +}) +```

      Métodos de roteamento

      @@ -36,49 +45,32 @@ o código a seguir é um exemplo de rotas para a raiz do aplicativo que estão definidas para os métodos GET e POST. -
      -
      +```js
       // GET method route
      -app.get('/', function (req, res) {
      -  res.send('GET request to the homepage');
      -});
      +app.get('/', (req, res) => {
      +  res.send('GET request to the homepage')
      +})
       
       // POST method route
      -app.post('/', function (req, res) {
      -  res.send('POST request to the homepage');
      -});
      -
      -
      - -O Express suporta os seguintes métodos de roteamento que -correspondem aos métodos HTTP: `get`, -`post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search`, e `connect`. - -
      -Para métodos de rota que são traduzidos para nomes de variáveis -inválidas no Javascript, use a notação de colchetes. Por exemplo, -`app['m-search']('/', function ...` -
      +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` + +O Express suporta métodos que correspondem a todos os métodos de requisição HTTP: `get`, `post`, etc. +Pra uma lista completa, veja [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). Existe um método de roteamento especial, `app.all()`, que não é derivado de nenhum método HTTP. Este método é usado para carregar funções de middleware em um -caminho para todos os métodos de solicitação. - -No exemplo a seguir, o manipulador irá ser executado para -solicitações para "/secret" se você estiver usando GET, POST, PUT, -DELETE, ou qualquer outro método de solicitação HTTP que é suportado -no [módulo -http](https://nodejs.org/api/http.html#http_http_methods). - -
      -
      -app.all('/secret', function (req, res, next) {
      -  console.log('Accessing the secret section ...');
      -  next(); // pass control to the next handler
      -});
      -
      -
      +caminho para todos os métodos de solicitação. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). + +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +```

      Caminhos de rota

      @@ -87,128 +79,190 @@ definem os terminais em que as solicitações podem ser feitas. Caminhos de rota podem ser sequências de caracteres, padrões de sequência, ou expressões regulares. -
      - O Express usa o [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) para verificar a correspondência de caminhos de rota; consulte a -documentação do path-to-regexp para obter todas as possibilidades nas definições de caminhos de rota. O [Express -Route Tester](http://forbeslindesay.github.io/express-route-tester/) é uma ferramenta útil para testar rotas básicas do Express, apesar de não suportar a correspondência de padrões. -
      +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
      -Sequências de consulta não fazem parte dos caminhos de rota. -
      +{% include admonitions/caution.html content=caution-character %} -Aqui estão alguns exemplos de caminhos de rota baseados em sequências de caracteres +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} -Este caminho de rota corresponde a solicitações à rota raiz, `/`. +{% include admonitions/caution.html content=note-dollar-character %} -
      -
      -app.get('/', function (req, res) {
      -  res.send('root');
      -});
      -
      -
      +{% capture note-path-to-regexp %} -Este caminho de rota irá corresponder a solicitações ao `/about`. +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. O Express +Route Tester é uma ferramenta útil para testar rotas básicas do Express, apesar de não suportar a correspondência de padrões. -
      -
      -app.get('/about', function (req, res) {
      -  res.send('about');
      -});
      -
      -
      +{% endcapture %} -Este caminho de rota irá corresponder a solicitações ao `/random.text`. +{% include admonitions/note.html content=note-path-to-regexp %} -
      -
      -app.get('/random.text', function (req, res) {
      -  res.send('random.text');
      -});
      -
      -
      +{% capture query-string-note %} -Aqui estão alguns exemplos de caminhos de rota baseados em padrões de sequência +Query strings are not part of the route path. -Este caminho de rota irá corresponder ao `acd` e `abcd`. +{% endcapture %} -
      -
      -app.get('/ab?cd', function(req, res) {
      -  res.send('ab?cd');
      -});
      -
      -
      +{% include admonitions/warning.html content=query-string-note %} -Este caminho de rota irá corresponder ao `abcd`, `abbcd`, `abbbcd`, e assim por diante. +### Aqui estão alguns exemplos de caminhos de rota baseados em sequências de caracteres -
      -
      -app.get('/ab+cd', function(req, res) {
      -  res.send('ab+cd');
      -});
      -
      -
      +Este caminho de rota irá corresponder a solicitações ao `/qualquer.texto`. -Este caminho de rota irá corresponder ao `abcd`, `abxcd`, `abRABDOMcd`, `ab123cd`, e assim por diante. +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` -
      -
      -app.get('/ab*cd', function(req, res) {
      -  res.send('ab*cd');
      -});
      -
      -
      +Este caminho de rota irá corresponder a solicitações ao `/ajuda`. + +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` + +Este caminho de rota corresponde a solicitações à rota raiz, `/`. + +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` + +### Aqui estão alguns exemplos de caminhos de rota baseados em padrões de sequência + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} + +{% include admonitions/caution.html content=caution-string-patterns %} Este caminho de rota irá corresponder ao `/abe` e `/abcde`. -
      -
      -app.get('/ab(cd)?e', function(req, res) {
      - res.send('ab(cd)?e');
      -});
      -
      -
      - -
      -Os caracteres ?, +, *, e () são subconjuntos de suas contrapartes em -expressões regulares. O hífen (-) e o ponto (.) são interpretados -literalmente por caminhos baseados em sequências de caracteres. -
      +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` + +Este caminho de rota irá corresponder ao `abcd`, `abbcd`, `abbbcd`, e assim por diante. -Exemplos de caminhos de rota baseados em expressões regulares: +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` + +Este caminho de rota irá corresponder ao `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, e assim por diante. + +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` + +Este caminho de rota irá corresponder ao `acd` e `abcd`. + +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` + +### Exemplos de caminhos de rota baseados em expressões regulares: Este caminho de rota irá corresponder a qualquer coisa com um "a" no nome. -
      -
      -app.get(/a/, function(req, res) {
      -  res.send('/a/');
      -});
      -
      -
      +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` Este caminho de rota irá corresponder a `butterfly` e `dragonfly`, mas não a `butterflyman`, `dragonfly man`, e assim por diante. -
      -
      -app.get(/.*fly$/, function(req, res) {
      -  res.send('/.*fly$/');
      -});
      -
      -
      +```js +app.get(/.*fly$/, (req, res) => { + res.send('/.*fly$/') +}) +``` + +

      +Sequências de consulta não fazem parte dos caminhos de rota. +

      + +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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
      +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +
      + +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. + +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` + +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` + +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): + +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` + +{% capture escape-advisory %} + +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %}

      Manipuladores de rota

      -É possível fornecer várias funções de retorno de chamada +É possível fornecer várias funções _callback_ que se comportam como [middleware](/{{ page.lang }}/guide/using-middleware.html) para -manipular uma solicitação. A única exceção é que estes retornos de -chamada podem chamar `next('route')` para efetuar um -bypass nos retornos de chamada da rota restantes. É possível usar +manipular uma solicitação. A única exceção é que estes _callbacks_ podem chamar `next('route')` para efetuar um +bypass nos _callbacks_ restantes. É possível usar este mecanismo para impor pré-condições em uma rota, e em seguida passar o controle para rotas subsequentes se não houveram razões para continuar com a rota atual. @@ -217,76 +271,68 @@ Manipuladores de rota podem estar na forma de uma função, uma matriz de funções, ou combinações de ambas, como mostrado nos seguintes exemplos. -Uma única função de retorno de chamada pode manipular uma rota. Por exemplo: - -
      -
      -app.get('/example/a', function (req, res) {
      -  res.send('Hello from A!');
      -});
      -
      -
      - -Mais de uma função de retorno de chamada pode manipular uma -rota (certifique-se de especificar o objeto `next` object). Por exemplo: - -
      -
      -app.get('/example/b', function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from B!');
      -});
      -
      -
      - -Uma matriz de funções de retorno de chamada podem manipular uma -rota. Por exemplo: - -
      -
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      +Uma única função _callback_ pode manipular uma rota. Por exemplo:
      +
      +```js
      +app.get('/example/a', (req, res) => {
      +  res.send('Hello from A!')
      +})
      +```
      +
      +Mais de uma função _callback_ pode manipular uma
      +rota (certifique-se de especificar o objeto `next`). Por exemplo:
      +
      +```js
      +app.get('/example/b', (req, res, next) => {
      +  console.log('the response will be sent by the next function ...')
      +  next()
      +}, (req, res) => {
      +  res.send('Hello from B!')
      +})
      +```
      +
      +Uma matriz de funções _callback_ podem manipular uma
      +rota. Por exemplo:
      +
      +```js
      +const cb0 = function (req, res, next) {
      +  console.log('CB0')
      +  next()
       }
       
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      +const cb1 = function (req, res, next) {
      +  console.log('CB1')
      +  next()
       }
       
      -var cb2 = function (req, res) {
      -  res.send('Hello from C!');
      +const cb2 = function (req, res) {
      +  res.send('Hello from C!')
       }
       
      -app.get('/example/c', [cb0, cb1, cb2]);
      -
      -
      +app.get('/example/c', [cb0, cb1, cb2]) +``` Uma combinação de funções independentes e matrizes de funções -podem manipular uma rota. Por exemplo: +podem manipular uma rota. Por exemplo: -
      -
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      +```js
      +const cb0 = function (req, res, next) {
      +  console.log('CB0')
      +  next()
       }
       
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      +const cb1 = function (req, res, next) {
      +  console.log('CB1')
      +  next()
       }
       
      -app.get('/example/d', [cb0, cb1], function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from D!');
      -});
      -
      -
      +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +```

      Métodos de resposta

      @@ -296,17 +342,17 @@ ciclo solicitação-resposta. Se nenhum destes métodos forem chamados a partir de um manipulador de rota, a solicitação do cliente será deixada em suspenso. -| Método | Descrição -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Solicita que seja efetuado o download de um arquivo -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Termina o processo de resposta. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Envia uma resposta JSON. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Envia uma resposta JSON com suporta ao JSONP. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redireciona uma solicitação. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Renderiza um modelo de visualização. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Envia uma resposta de vários tipos. -| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | Envia um arquivo como um fluxo de octeto. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Configura o código do status de resposta e envia a sua representação em sequência de caracteres como o corpo de resposta. +| Método | Descrição | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Solicita que seja efetuado o download de um arquivo | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Termina o processo de resposta. | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Envia uma resposta JSON. | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Envia uma resposta JSON com suporta ao JSONP. | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redireciona uma solicitação. | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Renderiza um modelo de visualização. | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Envia uma resposta de vários tipos. | +| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | Envia um arquivo como um fluxo de octeto. | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Configura o código do status de resposta e envia a sua representação em sequência de caracteres como o corpo de resposta. |

      app.route()

      @@ -315,20 +361,18 @@ Como o caminho é especificado em uma localização única, criar rotas modulare Aqui está um exemplo de manipuladores de rotas encadeáveis que são definidos usando `app.route()`. -
      -
      +```js
       app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      +  .get((req, res) => {
      +    res.send('Get a random book')
         })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      +  .post((req, res) => {
      +    res.send('Add a book')
         })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      + .put((req, res) => { + res.send('Update the book') + }) +```

      express.Router

      @@ -343,43 +387,49 @@ função de middleware nele, define algumas rotas, e monta o módulo router em um caminho no aplicativo principal. Crie um arquivo de roteador com um arquivo chamado -`birds.js` no diretório do aplicativo, com o +`passaros.js` no diretório do aplicativo, com o seguinte conteúdo: -
      -
      -var express = require('express');
      -var router = express.Router();
      +```js
      +const express = require('express')
      +const router = express.Router()
       
       // middleware that is specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      +const timeLog = (req, res, next) => {
      +  console.log('Time: ', Date.now())
      +  next()
      +}
      +router.use(timeLog)
      +
       // define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      +router.get('/', (req, res) => {
      +  res.send('Birds home page')
      +})
       // define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      +router.get('/about', (req, res) => {
      +  res.send('About birds')
      +})
       
      -module.exports = router;
      -
      -
      +module.exports = router +``` Em seguida, carregue o módulo roteador no aplicativo: -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      +```js +const birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` O aplicativo será agora capaz de manipular solicitações aos -caminhos `/birds` e `/birds/about`, +caminhos `/passaros` e `/passaros/ajuda`, assim como chamar a função de middleware `timeLog` que é específica para a rota. + +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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/pt-br/guide/using-middleware.md b/pt-br/guide/using-middleware.md old mode 100755 new mode 100644 index ba6b0ab388..2fa96ea534 --- a/pt-br/guide/using-middleware.md +++ b/pt-br/guide/using-middleware.md @@ -1,8 +1,9 @@ --- layout: page title: Usando middlewares do Express +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: pt-br +redirect_from: " " --- # Usando middlewares @@ -11,19 +12,15 @@ O Express é uma estrutura web de roteamento e middlewares que tem uma funcionalidade mínima por si só: Um aplicativo do Express é essencialmente uma série de chamadas de funções de middleware. -Funções de *Middleware* são funções que tem acesso -ao [objeto de solicitação](/{{ page.lang }}/4x/api.html#req) -(`req`), o [objeto de resposta](/{{ page.lang }}/4x/api.html#res) -(`res`), e a próxima função de middleware no ciclo -solicitação-resposta do aplicativo. A próxima função middleware é +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the next middleware function in the application's request-response cycle. A próxima função middleware é comumente denotada por uma variável chamada `next`. Funções de middleware podem executar as seguintes tarefas: -* Executar qualquer código. -* Fazer mudanças nos objetos de solicitação e resposta. -* Encerrar o ciclo de solicitação-resposta. -* Chamar a próxima função de middleware na pilha. +- Executar qualquer código. +- Fazer mudanças nos objetos de solicitação e resposta. +- Encerrar o ciclo de solicitação-resposta. +- Chamar a próxima função de middleware na pilha. Se a atual função de middleware não terminar o ciclo de solicitação-resposta, ela precisa chamar `next()` @@ -32,62 +29,53 @@ contrário, a solicitação ficará suspensa. Um aplicativo Express pode usar os seguintes tipos de middleware: - - [Middleware de nível do aplicativo](#middleware.application) - - [Middleware de nível de roteador](#middleware.router) - - [Middleware de manipulação de erros](#middleware.error-handling) - - [Middleware integrado](#middleware.built-in) - - [Middleware de Terceiros](#middleware.third-party) +- [Middleware de nível do aplicativo](#middleware.application) +- [Middleware de nível de roteador](#middleware.router) +- [Middleware de manipulação de erros](#middleware.error-handling) +- [Middleware integrado](#middleware.built-in) +- [Middleware de Terceiros](#middleware.third-party) É possível carregar middlewares de nível de roteador e de nível do aplicativo com um caminho de montagem opcional. É possível também carregar uma série de funções de middleware juntas, o que cria uma sub-pilha do sistema de middleware em um ponto de montagem.

      Middleware de nível do aplicativo

      -Vincule middlewares de nível do aplicativo a uma instância do -[objeto app](/{{ page.lang }}/4x/api.html#app) usando as funções -`app.use()` e `app.METHOD()`, onde -`METHOD` é o método HTTP da solicitação que a função -de middleware manipula (como GET, PUT, ou POST) em letras minúsculas. +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. Este exemplo mostra uma função de middleware sem um caminho de montagem. A função é executada sempre que o aplicativo receber uma solicitação. -
      -
      -var app = express();
      +```js
      +const express = require('express')
      +const app = express()
       
      -app.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -
      +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` Este exemplo mostra uma função de middleware montada no caminho `/user/:id`. A função é executada para qualquer tipo de solicitação HTTP no caminho `/user/:id`. -
      -
      -app.use('/user/:id', function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -
      +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Este exemplo mostra uma rota e sua função manipuladora (sistema de middleware). A função manipula solicitações GET ao caminho `/user/:id`. -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  res.send('USER');
      -});
      -
      -
      +```js +app.get('/user/:id', (req, res, next) => { + res.send('USER') +}) +``` Aqui está um exemplo de carregamento de um série de funções de middleware em um ponto de montagem, com um caminho de montagem. @@ -95,17 +83,15 @@ Ele ilustra uma sub-pilha de middleware que imprime informações de solicitação para qualquer tipo de solicitação HTTP no caminho `/user/:id`. -
      -
      -app.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -
      +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` Manipuladores de rota permitem a você definir várias rotas para um caminho. O exemplo abaixo define duas rotas para solicitações GET @@ -116,50 +102,70 @@ rota termina o ciclo solicitação-resposta. Este exemplo mostra uma sub-pilha de middleware que manipula solicitações GET no caminho `/user/:id`. -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -}, function (req, res, next) {
      -  res.send('User Info');
      -});
      +```js
      +app.get('/user/:id', (req, res, next) => {
      +  console.log('ID:', req.params.id)
      +  next()
      +}, (req, res, next) => {
      +  res.send('User Info')
      +})
       
       // handler for the /user/:id path, which prints the user ID
      -app.get('/user/:id', function (req, res, next) {
      -  res.end(req.params.id);
      -});
      -
      -
      - -Para pular o restante das funções de middleware de uma pilha de -middlewares do roteador, chame `next('route')` -para passar o controle para a próxima rota. -**NOTA**: O `next('route')` irá -funcionar apenas em funções de middleware que são carregadas usando -as funções `app.METHOD()` ou `router.METHOD()`. +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) +}) +``` + +`redirect` + +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} Este exemplo mostra uma sub-pilha de middleware que manipula solicitações GET no caminho `/user/:id`. -
      -
      -app.get('/user/:id', function (req, res, next) {
      +```js
      +app.get('/user/:id', (req, res, next) => {
         // if the user ID is 0, skip to the next route
      -  if (req.params.id == 0) next('route');
      +  if (req.params.id === '0') next('route')
         // otherwise pass the control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      +  else next()
      +}, (req, res, next) => {
      +  // send a regular response
      +  res.send('regular')
      +})
       
      -// handler for the /user/:id path, which renders a special page
      -app.get('/user/:id', function (req, res, next) {
      -  res.render('special');
      -});
      -
      -
      +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +É possível ter mais do que um diretório estático por aplicativo: + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

      Middleware de nível de roteador

      @@ -167,63 +173,87 @@ Middlewares de nível de roteador funcionam da mesma forma que os middlewares de nível do aplicativo, mas estão vinculados a uma instância do `express.Router()`. -
      -
      -var router = express.Router();
      -
      -
      +```js +const router = express.Router() +``` + Carregue os middlewares de nível de roteador usando as funções `router.use()` e `router.METHOD()`. O seguinte código de exemplo replica o sistema de middleware que é mostrado acima para o middleware de nível do aplicativo, usando um middleware de nível de roteador: -
      -
      -var app = express();
      -var router = express.Router();
      +```js
      +const express = require('express')
      +const app = express()
      +const router = express.Router()
       
       // a middleware function with no mount path. This code is executed for every request to the router
      -router.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      +router.use((req, res, next) => {
      +  console.log('Time:', Date.now())
      +  next()
      +})
       
       // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
      -router.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      +router.use('/user/:id', (req, res, next) => {
      +  console.log('Request URL:', req.originalUrl)
      +  next()
      +}, (req, res, next) => {
      +  console.log('Request Type:', req.method)
      +  next()
      +})
       
       // a middleware sub-stack that handles GET requests to the /user/:id path
      -router.get('/user/:id', function (req, res, next) {
      +router.get('/user/:id', (req, res, next) => {
         // if the user ID is 0, skip to the next router
      -  if (req.params.id == 0) next('route');
      +  if (req.params.id === '0') next('route')
         // otherwise pass control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      +  else next()
      +}, (req, res, next) => {
         // render a regular page
      -  res.render('regular');
      -});
      +  res.render('regular')
      +})
       
       // handler for the /user/:id path, which renders a special page
      -router.get('/user/:id', function (req, res, next) {
      -  console.log(req.params.id);
      -  res.render('special');
      -});
      +router.get('/user/:id', (req, res, next) => {
      +  console.log(req.params.id)
      +  res.render('special')
      +})
       
       // mount the router on the app
      -app.use('/', router);
      -
      -
      +app.use('/', router) +``` + +Para obter mais detalhes sobre a função `serve-static` e suas opções, consulte: documentação do[serve-static](https://github.com/expressjs/serve-static). + +Este exemplo mostra uma sub-pilha de middleware que manipula +solicitações GET no caminho `/user/:id`. + +```js +const express = require('express') +const app = express() +const router = express.Router() + +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) + +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) + +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +```

      Middleware de manipulação de erros

      -Middlewares de manipulação de erros sempre levam *quatro* argumentos. Você deve fornecer quatro argumentos para identificá-lo como uma +Middlewares de manipulação de erros sempre levam *quatro* argumentos. Você deve fornecer quatro argumentos para identificá-lo como uma função de middleware de 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 @@ -236,14 +266,12 @@ erros da mesma forma que outras funções de middleware, exceto que com quatro argumentos ao invés de três, especificamente com a assinatura `(err, req, res, next)`): -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Para obter detalhes sobre middleware de manipulação de erros, consulte [Manipulação de erros](/{{ page.lang }}/guide/error-handling.html). @@ -253,65 +281,14 @@ consulte [Manipulação de erros](/{{ page.lang }}/guide/error-handling.html). Desde a versão 4.x, o Express não depende mais do [Connect](https://github.com/senchalabs/connect). Com exceção da `express.static`, todas as funções de middleware que eram previamente incluídas com o Express estão agora -em módulos separados. Visualize [a lista -de funções de middleware](https://github.com/senchalabs/connect#middleware). - -

      express.static(root, [options])

      - -A única função de middleware integrada no Express é a -`express.static`. Esta função é baseada no -[serve-static](https://github.com/expressjs/serve-static), -e é responsável por entregar os ativos estáticos de um aplicativo do -Express. - -O argumento `root` especifica o diretório raiz -a partir do qual entregar os ativos estáticos. - -O objeto opcional `options` pode ter as -seguintes propriedades: - -| Propriedade | Descrição | Tipo | Padrão | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | Opção para entregar dotfiles. Os valores possíveis são "allow", "deny", e "ignore" | Sequência de caracteres | "ignore" | -| `etag` | Ativa ou desativa a geração de etag | Booleano | `true` | -| `extensions` | Configura os fallbacks de extensão de arquivo | Matriz | `[]` | -| `index` | Envia o arquivo de índice do diretório. Configure `false` para desativar a indexação de diretórios. | Variado | "index.html" | - `lastModified` | Configura o cabeçalho `Last-Modified` para a última data de modificação do arquivo no sistema operacional. Os valores possíveis são `true` ou `false`. | Booleano | `true` | -| `maxAge` | Configura a propriedade max-age do cabeçalho Cache-Control, em milissegundos ou uma sequência de caracteres no [formato ms](https://www.npmjs.org/package/ms) | Número | 0 | -| `redirect` | Redireciona para o "/" final quando o caminho do arquivo é um diretório. | Booleano | `true` | -| `setHeaders` | Função para configurar cabeçalhos HTTP para entregar com o arquivo. | Função | | +em módulos separados. Visualize a lista +de funções de middleware. Aqui está um exemplo de uso da função de middleware `express.static` com um objeto options elaborado: -
      -
      -var options = {
      -  dotfiles: 'ignore',
      -  etag: false,
      -  extensions: ['htm', 'html'],
      -  index: false,
      -  maxAge: '1d',
      -  redirect: false,
      -  setHeaders: function (res, path, stat) {
      -    res.set('x-timestamp', Date.now());
      -  }
      -}
      -
      -app.use(express.static('public', options));
      -
      -
      - -É possível ter mais do que um diretório estático por aplicativo: - -
      -
      -app.use(express.static('public'));
      -app.use(express.static('uploads'));
      -app.use(express.static('files'));
      -
      -
      - -Para obter mais detalhes sobre a função `serve-static` e suas opções, consulte: documentação do[serve-static](https://github.com/expressjs/serve-static). +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**

      Middleware de Terceiros

      @@ -322,22 +299,18 @@ Instale o módulo Node.js para a funcionalidade requerida, em seguida carregue-a O exemplo a seguir ilustra a instalação e carregamento da função de middleware para análise sintática de cookies `cookie-parser`. -
      -
      +```bash
       $ npm install cookie-parser
      -
      -
      +``` -
      -
      -var express = require('express');
      -var app = express();
      -var cookieParser = require('cookie-parser');
      +```js
      +const express = require('express')
      +const app = express()
      +const cookieParser = require('cookie-parser')
       
       // load the cookie-parsing middleware
      -app.use(cookieParser());
      -
      -
      +app.use(cookieParser()) +``` Para obter uma lista parcial de funções de middleware de terceiros que são comumente utilizadas com o Express, consulte: diff --git a/pt-br/guide/using-template-engines.md b/pt-br/guide/using-template-engines.md old mode 100755 new mode 100644 index e53d7ad397..f7ee62fc3e --- a/pt-br/guide/using-template-engines.md +++ b/pt-br/guide/using-template-engines.md @@ -1,28 +1,33 @@ --- layout: page title: Usando mecanismos de modelo com o Express +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: pt-br +redirect_from: " " --- # Usando mecanismos de modelo com o Express -Antes do Express poder renderizar arquivos de modelo, as -seguintes configurações do aplicativo devem ser configuradas: +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +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. -* `views`, é o diretório onde os arquivos de -modelo estão localizados. Por exemplo: `app.set('views', -'./views')` -* `view engine`, o mecanismo de modelo a ser -usado. Por Exemplo: `app.set('view engine', 'pug')` +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. + +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: + +- `views`, é o diretório onde os arquivos de + modelo estão localizados. Por exemplo: `app.set('views', + './views')` + This defaults to the `views` directory in the application root directory. +- `view engine`, o mecanismo de modelo a ser + usado. Por Exemplo: `app.set('view engine', 'pug')` Em seguida instale o pacote npm correspondente ao mecanismo de modelo: -
      -
      +```bash
       $ npm install pug --save
      -
      -
      +```
      Mecanismos de modelo compatíveis com o Express como o Pug exportam @@ -34,6 +39,7 @@ Alguns mecanismos de modelo não seguem esta convenção. A biblioteca [Consolidate.js](https://www.npmjs.org/package/consolidate) segue esta convenção mapeando todos os mecanismos de modelo populares do Node.js, e portanto funciona de forma harmoniosa com o Express. +
      Após o mecanismo de visualização estar configurado, você não @@ -41,25 +47,21 @@ precisa especificar o mecanismo ou carregar o módulo do mecanismo de modelo no seu aplicativo; o Express carrega o módulo internamente, como mostrado abaixo (para o exemplo acima). -
      -
      -app.set('view engine', 'pug');
      -
      -
      +```js +app.set('view engine', 'pug') +``` Crie um arquivo de modelo do Pug chamado `index.pug` no diretório `views`, com o seguinte conteúdo: -
      -
      +```pug
       html
         head
           title= title
         body
           h1= message
      -
      -
      +``` Em seguida crie uma rota para renderizar o arquivo `index.pug`. Se a propriedade `view @@ -67,15 +69,12 @@ engine` não estiver configurada, é preciso especificar a extensão do arquivo `view`. Caso contrário, é possível omití-la. -
      -
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -
      +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` Ao fazer uma solicitação à página inicial, o arquivo `index.pug` será renderizado como HTML. -Para aprender mais sobre como mecanismos de modelo funcionam no -Express, consulte: ["Desenvolvendo mecanismos de para o Express"](/{{ page.lang }}/advanced/developing-template-engines.html). +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/pt-br/guide/writing-middleware.md b/pt-br/guide/writing-middleware.md old mode 100755 new mode 100644 index cf2951520b..c85f6681d6 --- a/pt-br/guide/writing-middleware.md +++ b/pt-br/guide/writing-middleware.md @@ -1,15 +1,16 @@ --- layout: page title: Escrevendo middlewares para uso em aplicativos do Express +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: pt-br +redirect_from: " " --- -# Escrevendo middlewares pra uso em aplicativos do Express +# Escrevendo middlewares para uso em aplicativos do Express

      Visão Geral

      -Funções de *Middleware* são funções que tem acesso +Funções de _Middleware_ são funções que tem acesso ao [objeto de solicitação](/{{ page.lang }}/4x/api.html#req) (`req`), o [objeto de resposta](/{{ page.lang }}/4x/api.html#res) (`res`), e a próxima função de middleware no ciclo @@ -18,10 +19,10 @@ comumente denotada por uma variável chamada `next`. Funções de middleware podem executar as seguintes tarefas: -* Executar qualquer código. -* Fazer mudanças nos objetos de solicitação e resposta. -* Encerrar o ciclo de solicitação-resposta. -* Chamar o próximo middleware na pilha. +- Executar qualquer código. +- Fazer mudanças nos objetos de solicitação e resposta. +- Encerrar o ciclo de solicitação-resposta. +- Chamar o próximo middleware na pilha. Se a atual função de middleware não terminar o ciclo de solicitação-resposta, ela precisa chamar `next()` @@ -30,12 +31,13 @@ contrário, a solicitação ficará suspensa. O exemplo a seguir mostra os elementos de uma chamada de função de middleware: - -
      - +
      + +
      Caminho (rota) para o qual a função de middleware é aplicada.
      @@ -48,76 +50,77 @@ O exemplo a seguir mostra os elementos de uma chamada de função de middleware:
      Argumento de solicitação HTTP para a função de middleware, chamado de "req" por convenção.
      +Elements of a middleware function call -
      O método HTTP para o qual a função de middleware é aplicada.
      +
      O método HTTP para o qual a função de middleware é aplicada.
      +
      + +Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error. + +

      Exemplo

      Aqui está um exemplo de um simples aplicativo "Hello World" do Express, para o qual serão definidas duas funções de middleware: +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. -
      -
      -var express = require('express');
      -var app = express();
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      +```js
      +const express = require('express')
      +const app = express()
       
      -app.listen(3000);
      -
      -
      +app.get('/', (req, res) => { + res.send('Hello World!') +}) -

      Desenvolvimento

      +app.listen(3000) +``` +

      Middleware function myLogger

      Aqui está um exemplo simples de uma função de middleware chamada "myLogger". Esta função apenas imprime "LOGGED" quando uma solicitação para o aplicativo passa por ela. A função de middleware é designada para uma variável chamada `myLogger`. -
      -
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      -
      -
      +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
      -Observe a chamada acima para `next()`. A chamada +Observe a chamada acima para `next()`. A chamada desta função chama a próxima função de middleware no aplicativo. A função `next()` não faz parte do Node.js ou da API Express, mas é o terceiro argumento que é passado para a função de middleware. A função `next()` poderia ter -qualquer nome, mas por convenção ela é sempre chamada de "next". Para +qualquer nome, mas por convenção ela é sempre chamada de "next". +Para evitar confusão, sempre use esta convenção.
      Para carregar a função de middleware, chame `app.use()`, especificando a função de middleware. Por exemplo, o código a seguir carrega a função de middleware do `myLogger` antes da rota para o caminho raiz (/). -
      -
      -var express = require('express');
      -var app = express();
      +```js
      +const express = require('express')
      +const app = express()
       
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      +const myLogger = function (req, res, next) {
      +  console.log('LOGGED')
      +  next()
      +}
       
      -app.use(myLogger);
      +app.use(myLogger)
       
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      +app.get('/', (req, res) => {
      +  res.send('Hello World!')
      +})
       
      -app.listen(3000);
      -
      -
      +app.listen(3000) +``` Sempre que o aplicativo recebe uma chamada, ele imprime a mensagem "LOGGED" no terminal. A ordem de carregamento do middleware é importante: funções de middleware que são carregadas primeiro também são executadas primeiro. - Se `myLogger` é carregada após a rota para o caminho raiz, a chamada nunca chegará a ela e o aplicativo não imprimirá "LOGGED", pois o manipulador de rota do caminho raiz @@ -126,50 +129,94 @@ encerra o ciclo de solicitação-resposta. A função de middleware `myLogger` simplesmente imprime uma mensagem, e em seguida passa a solicitação para a próxima função de middleware na pilha chamando a função `next()`. +

      Middleware function requestTime

      + O próximo exemplo inclui uma propriedade chamada `requestTime` ao objeto da solicitação. Iremos chamar esta função de middleware de "requestTime". -
      -
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      -
      -
      +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` O aplicativo agora usa a função de middleware `requestTime`. Além disso, a função de retorno de chamada do caminho raiz usa a propriedade que a função de middleware inclui no `req` (o objeto da solicitação). -
      -
      -var express = require('express');
      -var app = express();
      +```js
      +const express = require('express')
      +const app = express()
       
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      +const requestTime = function (req, res, next) {
      +  req.requestTime = Date.now()
      +  next()
      +}
       
      -app.use(requestTime);
      +app.use(requestTime)
       
      -app.get('/', function (req, res) {
      -  var responseText = 'Hello World!
      '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +app.get('/', (req, res) => { + let responseText = 'Hello World!
      ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) -app.listen(3000); -
      -
      +app.listen(3000) +``` Ao fazer uma solicitação para a raiz do aplicativo, o aplicativo agora exibe o registro de data e hora da sua solicitação no navegador. +

      Middleware function validateCookies

      + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
      +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
      + Como você tem acesso ao objeto da solicitação, ao objeto de resposta, à próxima função de middleware na pilha, e à API completa do Node.js, as possibilidades com as funções de middleware são ilimitadas. @@ -177,3 +224,28 @@ Node.js, as possibilidades com as funções de middleware são ilimitadas. Para obter mais informações sobre middlewares no Express, consulte: [Usando middlewares no Express](/{{ page.lang }}/guide/using-middleware.html). + +

      Configurable middleware

      + +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. + +File: `my-middleware.js` + +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` + +The middleware can now be used as shown below. + +```js +const mw = require('./my-middleware.js') + +app.use(mw({ option1: '1', option2: '2' })) +``` + +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/pt-br/index.md b/pt-br/index.md index 0aeb6ac3e9..be45482a6a 100644 --- a/pt-br/index.md +++ b/pt-br/index.md @@ -1,57 +1,61 @@ --- layout: home -title: Express - framework de aplicativo da web Node.js +title: Express - Node.js web application framework +description: "Express is a fast, unopinionated, minimalist web framework for Node.js, providing a robust set of features for web and mobile applications." menu: home -lang: pt-br +redirect_from: " " --- +
      - {% include header/header-{{ page.lang }}.html %} -
      - - Framework web rápido, flexível e minimalista para Node.js + +

      Fast, unopinionated, minimalist web framework for Node.js

      -
      $ npm install express --save
      -
      -
      - +
      $ npm install express --save
      -
      - +
      -
      +```javascript +const express = require('express') +const app = express() +const port = 3000 -
      -
      -

      Aplicativos da Web

      O Express é um framework para aplicativo da web do Node.js mínimo e flexível que fornece um conjunto -robusto de recursos para aplicativos web e móvel. -
      - -
      -

      APIs

      Com uma miríade de métodos utilitários HTTP e middleware a seu dispor, criar uma API robusta é rápido e fácil. -
      - -
      -

      Desempenho

      O Express fornece uma camada fina de recursos fundamentais para aplicativos da web, sem obscurecer os -recursos do Node.js que você conhece e ama. -
      - - -
      +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` +
      - diff --git a/pt-br/resources/community.md b/pt-br/resources/community.md old mode 100755 new mode 100644 index b1f924245b..622e3012b7 --- a/pt-br/resources/community.md +++ b/pt-br/resources/community.md @@ -1,43 +1,91 @@ --- layout: page title: Comunidade do Express +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: pt-br +redirect_from: " " --- # Comunidade -## Lista de Distribuição +## Comitê técnico -Junte-se a mais de 2000 usuários do Express ou navegue por mais -de 5000 discussões no [Grupo do -Google](https://groups.google.com/group/express-js). +O comitê técnico do Express se reúne on-line a cada duas semanas (conforme necessário) para discutir o desenvolvimento e a manutenção do Express, +e outras questões relevantes para o projeto Express. Cada reunião é normalmente anunciada em um +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) com um link para participar ou visualizar a reunião, que é +aberto a todos os observadores. -## Gitter +As reuniões são gravadas; para obter uma lista das gravações, consulte o [ canal no YouTube do Express.js](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -A [sala -de bate-papo expressjs/express](https://gitter.im/expressjs/express) é um ótimo lugar para -desenvolvedores interessados nas discussões de dia-a-dia relacionadas -ao Express. +Os membros do comitê técnico do Express são: -## Canal do IRC +**Ativo:** -Há centenas de desenvolvedores livres em #express no freenode todos os dias. -Se tiver questões sobre o framework, entre para obter feedbacks rápidos. +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida + +**Inativo:** + +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express é feito de vários módulos + +Nossa vibrante comunidade criou uma grande variedade de extensões, +[middleware módulos](/{{ page.lang }}/resources/middleware.html) e frameworks de alto nível. + +Além disso, a comunidade Express mantém módulos nestes duas organizações no GitHub: + +- [jshttp](https://jshttp.github.io/) módulos que fornecem função utilitária útil; ver [Módulos utilitários](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): módulos de baixo nível que o Express usa internamente. + +Para acompanhar o que está acontecendo em toda a comunidade, Confira a [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). + +## Issues + +Se você se deparou com o que acha que é um bug ou apenas deseja fazer +uma solicitação de recurso abre um ticket no [issue queue](https://github.com/expressjs/express/issues). ## Exemplos -Visualize dezenas de [exemplos](https://github.com/expressjs/express/tree/master/examples) -de aplicativos do Express no repositório, cobrindo tudo desde o design de API e autenticação até a integração de mecanismo de modelo. +Veja dezenas de aplicativos Express [exemplos](https://github.com/expressjs/express/tree/master/examples) +no repositório temos de tudo, desde design de API e autenticação até integração de mecanismo de template. + +## Github Discussions -## Problemas +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. -Se se deparar com o que pensa ser um erro, ou apenas desejar fazer uma solicitação de recurso, abra um chamado na -[fila de problemas](https://github.com/expressjs/express/issues). +# Branding of Express.js -## Terceiros +## Express.js Logo -Nossa vibrante comunidade criou uma ampla variedade de -extensões, [módulos middleware](/{{ page.lang }}/resources/middleware.html) e frameworks de -alto nível. Confira na [wiki](https://github.com/expressjs/express/wiki). +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
      +
      +

      Logotype

      + Express.js logo + + + Express.js logo + +
      +
      +

      Logomark

      + Express.js mark + + + Express.js mark + +
      +
      +
      \ No newline at end of file diff --git a/pt-br/resources/contributing.md b/pt-br/resources/contributing.md new file mode 100644 index 0000000000..b47fb49104 --- /dev/null +++ b/pt-br/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Comitê técnico + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/pt-br/resources/glossary.md b/pt-br/resources/glossary.md old mode 100755 new mode 100644 index 14df3391f5..3e1314a92c --- a/pt-br/resources/glossary.md +++ b/pt-br/resources/glossary.md @@ -1,14 +1,13 @@ --- layout: page title: Glossário do Express +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: pt-br +redirect_from: " " --- # Glossário -
      Este é atualmente um rascunho de trabalho
      - ### aplicativo Em geral, um ou mais programas que são designados a executar @@ -18,11 +17,11 @@ também se referir a um [objeto app](/{{ page.lang }}/api.html#express). ### API -Interface de programação de aplicativos. Especifique o significado da abreviação no seu primeiro uso. +Interface de programação de aplicativos. Especifique o significado da abreviação no seu primeiro uso. ### Express -Uma estrutura web rápida, flexível e minimalista para aplicativos Node.js. Em +Uma estrutura web rápida, flexível e minimalista para aplicativos Node.js. Em geral, "Express" é preferido a "Express.js," apesar de que o último ser aceitável. ### libuv @@ -34,34 +33,48 @@ assíncrona, primeiramente desenvolvida para uso pelo Node.js. Uma função que é chamada pela camada de roteamento do Express antes do manipulador final da solicitação, e assim ficando no meio, -entre uma solicitação bruta a rota final desejada. Alguns poucos +entre uma solicitação bruta a rota final desejada. Alguns poucos pontos de refinamento da terminologia envolvendo middleware: - * `var foo = require('middleware')` é -chamado *requerendo* ou *usando* um módulo -do Node.js. Então a instrução `var mw = foo()` -tipicamente retorna o middleware. - * `app.use(mw)` é chamado *incluindo -o middleware na pilha global de processamento*. - * `app.get('/foo', mw, function (req, res) { ... })` -é chamado *incluindo o middleware para a pilha de -processamento do "GET /foo" *. +- `var foo = require('middleware')` é + chamado _requerendo_ ou _usando_ um módulo + do Node.js. Então a instrução `var mw = foo()` + tipicamente retorna o middleware. +- `app.use(mw)` é chamado _incluindo + o middleware na pilha global de processamento_. +- `app.get('/foo', mw, function (req, res) { ... })` + é chamado \*incluindo o middleware para a pilha de + processamento do "GET /foo" \*. ### Node.js Uma plataforma de software que é usada para construir aplicativos de rede escaláveis. O Node.js usa o JavaScript como linguagem de script, e alcança rendimentos altos através de E/S não -bloqueante e um loop de eventos de thread única. Consulte [nodejs.org](http://nodejs.org/). **Nota +bloqueante e um loop de eventos de thread única. Consulte [nodejs.org](http://nodejs.org/). **Nota de uso**: Inicialmente, "Node.js," posteriormente "Node". ### open-source, open source Quando usado como adjetivo, colocar o hífen; por exemplo "Este é um software open-source". Consulte -[Software -Open-source na Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Nota: Apesar de ser comum não -colocar o hífen neste termo, estamos usando as regras padrões do -Inglês para colocar o hífen em adjetivos compostos. +Software +Open-source na Wikipedia. + +{% capture english-rules %} + +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. + +{% endcapture %} + +{% include admonitions/note.html content=english-rules %} + +### solicitação + +Uma solicitação HTTP. Um cliente envia uma mensagem HTTP para +um servidor, que retorna uma resposta. A solicitação deve usar um dos +vários +métodos +de solicitação como GET, POST, e assim por diante. ### resposta @@ -72,18 +85,10 @@ solicitação no corpo da mensagem. ### rota -Parte de uma URL que identifica um recurso. Por exemplo, em +Parte de uma URL que identifica um recurso. Por exemplo, em `http://foo.com/products/id`, "/products/id" é a rota. ### roteador Consulte [roteador](/{{ page.lang }}/4x/api.html#router) na referência da API. - -### solicitação - -Uma solicitação HTTP. Um cliente envia uma mensagem HTTP para -um servidor, que retorna uma resposta. A solicitação deve usar um dos -vários -[métodos -de solicitação](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) como GET, POST, e assim por diante. diff --git a/pt-br/resources/learning.md b/pt-br/resources/learning.md deleted file mode 100644 index d3aea1a271..0000000000 --- a/pt-br/resources/learning.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -layout: page -title: Aprendizagem adicional -menu: Recursos -lang: pt-br ---- - -# Aprendizagem adicional - -
      Atenção: Este conteúdo não é de responsabilidade da comunidade.
      - -## Livros - -Aqui estão alguns dos vários livros sobre Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, Packt Publishing, June 2013. - - **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, texxtoor, September 2015. Em Alemão. - - **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, texxtoor, September 2015. Em Alemão. - - **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Adicione seu livro aqui! - -[Edite o arquivo Markdown](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) e adicione um link para o seu livro, então envie um pull request (necessário login no GitHub). Siga o formato da listagem acima. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Adicione seu blog aqui! - -[Edite o arquivo Markdown](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) e adicione um link para o seu blog, então envie um pull request (necessário login no GitHub). Siga o formato da listagem acima. diff --git a/pt-br/resources/middleware.md b/pt-br/resources/middleware.md old mode 100755 new mode 100644 index 6f49de9592..bd0f46cdf5 --- a/pt-br/resources/middleware.md +++ b/pt-br/resources/middleware.md @@ -1,75 +1,43 @@ --- -layout: page +layout: middleware title: Middleware do Express +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: pt-br +redirect_from: " " +module: mw-home --- -# Middleware de Terceiros +## Middleware do Express Aqui estão alguns módulos middleware do Express: - - - [body-parser](https://github.com/expressjs/body-parser): anteriormente `express.bodyParser`, `json`, e `urlencoded`. - Consulte também: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): anteriormente `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): Módulos de middleware do Connect/Express para entrega otimizada de imagens. Alterna imagens para `.webp` ou `.jxr`, se possível. - - [connect-timeout](https://github.com/expressjs/timeout): anteriormente `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): anteriormente `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): anteriormente `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): anteriormente `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): anteriormente `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): ferramenta não obstrutiva de desenvolvimento que inclui uma guia com informações sobre variáveis de modelo (locais), sessão corrente, dados de solicitação úteis e mais para o seu aplicativo. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): módulo de middleware do Express para filtrar partes das respostas JSON baseado nos `fields` da sequência de consultas; usando a Resposta parcial da API do Google. - - - [express-session](https://github.com/expressjs/session): anteriormente `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): Módulo middleware do Express para usar um CDN para ativos estáticos, com suporte a múltiplos hosts (Por exemplo: cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): Módulo middleware do Express para pessoas rigorosas quanto ao uso de barras no fim. - - - [express-stormpath](https://github.com/stormpath/stormpath-express): Módulo middleware do Express para armazenamento de usuário, autenticação, autorização,SSO e segurança de dados. - - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): módulo middleware para redirecionamento de solicitações HTTP contendo letras maiúsculas para a forma canônica minúscula. - - - [helmet](https://github.com/helmetjs/helmet): módulo para ajudar a proteger seus aplicativos configurando vários cabeçalhos HTTP. - - [join-io](https://github.com/coderaiser/join-io "join-io"): módulo para junção de arquivos em tempo de execução para reduzir a contagem de solicitações. - - [method-override](https://github.com/expressjs/method-override): anteriormente `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): anteriormente `logger` - - [passport](https://github.com/jaredhanson/passport): módulo middleware do Express para autenticação. - - [response-time](https://github.com/expressjs/response-time): anteriormente `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): anteriormente `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): anteriormente `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): módulo para entregar conteúdo estático. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): URLs identificadas ou Armazenamento em cache de Cabeçalhos para ativos estáticos incluindo suporte para um ou mais domínios externos. - - - [vhost](https://github.com/expressjs/vhost): anteriormente `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): módulo middleware do Express que fornece métodos auxiliares comuns para as visualizações. - - - [sriracha-admin](https://github.com/hdngr/siracha): módulo middleware do Express que gera dinamicamente um site de administração para o Mongoose. - -Alguns módulos de middleware anteriormente incluídos com o -Connect não são mais suportados pelo time Connect/Express. Estes -módulos foram substituídos por um módulo alternativo, ou devem ser -substituídos por um módulo melhor. Use uma das alternativas a seguir: - - - - express.cookieParser - - [cookies](https://github.com/jed/cookies) e [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) - -Para obter mais módulos middleware, consulte: - - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| Middleware module | Descrição | +| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | + +## Para obter mais módulos middleware, consulte: + +These are some additional popular middleware modules. + +{% include community-caveat.html %} + +| Middleware module | Descrição | +| ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [st](https://github.com/isaacs/st) | [helmet](https://github.com/helmetjs/helmet): módulo para ajudar a proteger seus aplicativos configurando vários cabeçalhos HTTP. | +| [passport](https://github.com/jaredhanson/passport): módulo middleware do Express para autenticação. | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/pt-br/resources/middleware/body-parser.md b/pt-br/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/pt-br/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/pt-br/resources/middleware/compression.md b/pt-br/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/pt-br/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/pt-br/resources/middleware/connect-rid.md b/pt-br/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/pt-br/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/pt-br/resources/middleware/cookie-parser.md b/pt-br/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/pt-br/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/pt-br/resources/middleware/cookie-session.md b/pt-br/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/pt-br/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/pt-br/resources/middleware/cors.md b/pt-br/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/pt-br/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/pt-br/resources/middleware/errorhandler.md b/pt-br/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/pt-br/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/pt-br/resources/middleware/method-override.md b/pt-br/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/pt-br/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/pt-br/resources/middleware/morgan.md b/pt-br/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/pt-br/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/pt-br/resources/middleware/multer.md b/pt-br/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/pt-br/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/pt-br/resources/middleware/response-time.md b/pt-br/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/pt-br/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/pt-br/resources/middleware/serve-favicon.md b/pt-br/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/pt-br/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/pt-br/resources/middleware/serve-index.md b/pt-br/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/pt-br/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/pt-br/resources/middleware/serve-static.md b/pt-br/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/pt-br/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/pt-br/resources/middleware/session.md b/pt-br/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/pt-br/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/pt-br/resources/middleware/timeout.md b/pt-br/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/pt-br/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/pt-br/resources/middleware/vhost.md b/pt-br/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/pt-br/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/pt-br/resources/utils.md b/pt-br/resources/utils.md new file mode 100644 index 0000000000..990e8b0c72 --- /dev/null +++ b/pt-br/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/pt-br/starter/basic-routing.md b/pt-br/starter/basic-routing.md old mode 100755 new mode 100644 index a4923c2770..bc36360510 --- a/pt-br/starter/basic-routing.md +++ b/pt-br/starter/basic-routing.md @@ -1,13 +1,14 @@ --- layout: page title: Roteamento básico no Express +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: pt-br +redirect_from: " " --- # Roteamento Básico -O *Roteamento* refere-se à determinação de como um +O _Roteamento_ refere-se à determinação de como um aplicativo responde a uma solicitação do cliente por um endpoint específico, que é uma URI (ou caminho) e um método de solicitação HTTP específico (GET, POST, e assim por diante). @@ -16,11 +17,10 @@ Cada rota pode ter uma ou mais funções de manipulação, que são executadas quando a rota é correspondida. A definição de rotas aceita a seguinte estrutura: -
      -
      +
      +```js
       app.METHOD(PATH, HANDLER)
      -
      -
      +``` Onde: @@ -40,42 +40,36 @@ Os seguintes exemplos ilustram a definição de rotas simples. Responder com `Hello World!` na página inicial: -
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -
      +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -Responder a uma solicitação POST na rota raiz (`/`) com a página inicial do aplicativo: +Respond to a POST request on the root route (`/`), the application's home page: -
      -
      -app.post('/', function (req, res) {
      -  res.send('Got a POST request');
      -});
      -
      -
      +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` Responder a uma solicitação PUT para a rota `/user`: -
      -
      -app.put('/user', function (req, res) {
      -  res.send('Got a PUT request at /user');
      -});
      -
      -
      +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` Responder a uma solicitação DELETE para a rota `/user`: -
      -
      -app.delete('/user', function (req, res) {
      -  res.send('Got a DELETE request at /user');
      -});
      -
      -
      +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` Para obter mais detalhes sobre roteamento, consulte o [guia de roteamento](/{{ page.lang }}/guide/routing.html). + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/pt-br/starter/examples.md b/pt-br/starter/examples.md new file mode 100644 index 0000000000..0f3f30f313 --- /dev/null +++ b/pt-br/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Exemplos do Express +description: Explore uma coleção de exemplos de aplicações em Express.js cobrindo diversos casos de uso, integrações e configurações avançadas para te ajudar a aprender e construir seus projetos. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Exemplos adicionais + +Estes são alguns exemplos adicionais com integrações mais extensas. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Aplicativo Fullstack com Express e Next.js utilizando [Prisma](https://www.npmjs.com/package/prisma) como ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - API REST com Express em TypeScript utilizando [Prisma](https://www.npmjs.com/package/prisma) como ORM + +### [Anterior: Arquivos Estáticos ](/{{ page.lang }}/starter/static-files.html)    [Próximo: Perguntas mais frequentes ](/{{ page.lang }}/starter/faq.html) diff --git a/pt-br/starter/faq.md b/pt-br/starter/faq.md old mode 100755 new mode 100644 index 2fd038c2af..ed81379f7a --- a/pt-br/starter/faq.md +++ b/pt-br/starter/faq.md @@ -1,8 +1,9 @@ --- layout: page title: Pergunta mais Frequentes do Express +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: pt-br +redirect_from: " " --- # Perguntas mais frequentes @@ -18,19 +19,19 @@ Rotas e outras lógicas específicas do aplicativo podem ficar em quantos arquivos quiser, em qualquer estrutura de diretórios que preferir. Visualize os seguintes exemplos para obter inspiração: -* [Listagens de rota](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Mapa de rota](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [Controladores com estilo MVC](https://github.com/expressjs/express/tree/master/examples/mvc) +- [Listagens de rota](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [Mapa de rota](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [Controladores com estilo MVC](https://github.com/expressjs/express/tree/master/examples/mvc) Além disso, existem extensões de terceiros para o Express, que simplificam alguns desses padrões: -* [Roteamento engenhoso](https://github.com/expressjs/express-resource) +- [Resourceful routing](https://github.com/expressjs/express-resource) ## Como eu defino modelos? O Express não tem noção de banco de dados. Este conceito é -deixado para módulos do Node de terceiros, permitindo que você fazer +deixado para módulos do Node de terceiros, permitindo que você faça a interface com praticamente qualquer banco de dados. Consulte [LoopBack](http://loopback.io) para @@ -39,11 +40,10 @@ uma estrutura baseada no Express que é centrada em modelos. ## Como posso autenticar usuários? Autenticação é outra área muito opinada que o Express não -se arrisca a entrar. Você pode usar qualquer esquema que desejar. +se arrisca a entrar. Você pode usar qualquer esquema que desejar. Para um esquema simples com nome de usuário / senha, consulte -[este -exemplo](https://github.com/expressjs/express/tree/master/examples/auth). - +este +exemplo. ## Quais mecanismos de modelo o Express suporta? @@ -56,6 +56,8 @@ cache de mecanismo de modelo, consulte o projeto para obter suporte. Mecanismos de modelo não listados podem ainda assim suportar a assinatura do Express. +[Roteamento engenhoso](https://github.com/expressjs/express-resource) + ## Como manipulo respostas 404? No Express, respostas 404 não são o resultado de um erro, @@ -66,13 +68,14 @@ que nenhuma delas respondeu. Tudo que você precisa fazer é incluir uma função de middleware no final da pilha (abaixo de todas as outras funções) para manipular uma resposta 404: -
      -
      -app.use(function(req, res, next) {
      -  res.status(404).send('Sorry cant find that!');
      -});
      -
      -
      +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` + +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## Como configuro um manipulador de erros? @@ -80,14 +83,12 @@ Você define middlewares de manipulação de erros da mesma forma que outros middlewares, exceto que com quatro argumentos ao invés de três; especificamente com a assinatura `(err, req, res, next)`: -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` Para obter mais informações, consulte [Manipulação de erros](/{{ page.lang }}/guide/error-handling.html). @@ -99,3 +100,10 @@ se você tiver um arquivo específico, use a função `res.sendFile()`. Se estiver entregando muitos ativos a partir de um diretório, use a função de middleware `express.static()`. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/pt-br/starter/generator.md b/pt-br/starter/generator.md old mode 100755 new mode 100644 index 5e58344d2d..6a31dd71f8 --- a/pt-br/starter/generator.md +++ b/pt-br/starter/generator.md @@ -1,8 +1,9 @@ --- layout: page title: Gerador de aplicativos do Express +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: pt-br +redirect_from: " " --- # Gerador de aplicativos do Express @@ -10,21 +11,25 @@ lang: pt-br Use a ferramenta geradora de aplicativos, `express`, para rapidamente criar uma estrutura básica de aplicativo. -Instale o `express` com o comando a seguir: +You can run the application generator with the `npx` command (available in Node.js 8.2.0). + +```bash +$ npx express-generator +``` -
      -
      -$ npm install express-generator -g
      -
      -
      +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` Exiba as opções de comando com a opção `-h`: -
      -
      +```bash
       $ express -h
       
      -  Usage: express [options][dir]
      +  Usage: express [options] [dir]
       
         Options:
       
      @@ -35,18 +40,16 @@ $ express -h
               --pug           add pug engine support
           -H, --hogan         add hogan.js engine support
               --no-view       generate without view engine
      -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
      -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
      +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
      +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
               --git           add .gitignore
           -f, --force         force on non-empty directory
      -
      -
      +``` Por exemplo, o seguinte cria um aplicativo do Express chamado _myapp_ -no diretório atualmente em funcionamento: +no diretório atualmente em funcionamento: The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: -
      -
      +```bash
       $ express --view=pug myapp
       
          create : myapp
      @@ -66,41 +69,38 @@ $ express --view=pug myapp
          create : myapp/views/error.pug
          create : myapp/bin
          create : myapp/bin/www
      -
      -
      +``` Em seguida instale as dependências: -
      -
      +```bash
       $ cd myapp
       $ npm install
      -
      -
      +``` No MacOS ou Linux, execute o aplicativo com este comando: -
      -
      +```bash
       $ DEBUG=myapp:* npm start
      -
      -
      +``` No Windows, use este comando: -
      -
      +```bash
       > set DEBUG=myapp:* & npm start
      -
      -
      +``` -Em seguida carregue `http://localhost:3000/` no seu navegador para acessar o aplicativo. +Instale o `express` com o comando a seguir: + +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` +Em seguida carregue `http://localhost:3000/` no seu navegador para acessar o aplicativo. O aplicativo gerado possui a seguinte estrutura de diretórios: -
      -
      +```bash
       .
       ├── app.js
       ├── bin
      @@ -120,10 +120,10 @@ O aplicativo gerado possui a seguinte estrutura de diretórios:
           └── layout.pug
       
       7 directories, 9 files
      -
      -
      +```
      -A estrutura de aplicativo criada pelo gerador é apenas uma das várias maneiras de estruturar aplicativos do Express. -É possível utilizar esta estrutura ou modificá-la para melhor se adequar às suas necessidades. +A estrutura de aplicativo criada pelo gerador é apenas uma das várias maneiras de estruturar aplicativos do Express. É possível utilizar esta estrutura ou modificá-la para melhor se adequar às suas necessidades.
      + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/pt-br/starter/hello-world.md b/pt-br/starter/hello-world.md old mode 100755 new mode 100644 index e95837a373..a3295c3cb5 --- a/pt-br/starter/hello-world.md +++ b/pt-br/starter/hello-world.md @@ -1,8 +1,9 @@ --- layout: page title: Exemplo "Hello World" do Express +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: pt-br +redirect_from: " " --- # Exemplo Hello World @@ -14,14 +15,7 @@ que cria a estrutura para um aplicativo completo com inúmeros arquivos JavaScri propósitos.
      -Primeiro crie um diretório chamado `myapp`, -mude para ele e execute o `npm init`. Em seguida -instale o `express` como uma dependência, de acordo com o [guia de instalação](/{{ page.lang }}/starter/installing.html). - -No diretório `myapp`, crie um arquivo chamado `app.js` e inclua o seguinte código: - -
      -
      +```js
       const express = require('express')
       const app = express()
       const port = 3000
      @@ -31,16 +25,23 @@ app.get('/', (req, res) => {
       })
       
       app.listen(port, () => {
      -  console.log(`Example app listening at http://localhost:${port}`)
      +  console.log(`Example app listening on port ${port}`)
       })
      -
      -
      +``` O aplicativo inicia um servidor e escuta a porta 3000 por conexões. O aplicativo responde com "Hello World!" à solicitações -para a URL raiz (`/`) ou *rota*. Para +para a URL raiz (`/`) ou _rota_. Para todos os outros caminhos, ele irá responder com um **404 Não Encontrado**. +### Running Locally + +Primeiro crie um diretório chamado `myapp`, +mude para ele e execute o `npm init`. Em seguida +instale o `express` como uma dependência, de acordo com o [guia de instalação](/{{ page.lang }}/starter/installing.html). + +No diretório `myapp`, crie um arquivo chamado `app.js` e inclua o seguinte código: +
      O `req` (solicitação) e `res` (resposta) são os mesmos objetos que o Node fornece, para que seja @@ -51,12 +52,11 @@ que desejaria fazer sem o envolvimento do Express. Execute o aplicativo com o seguinte comando: -
      -
      +```bash
       $ node app.js
      -
      -
      +``` Em seguida, carregue [http://localhost:3000/](http://localhost:3000/) em um navegador para visualizar a saída +### [Previous: Installing ](/{{ page.lang }}/starter/installing.html)    [Next: Express Generator ](/{{ page.lang }}/starter/generator.html) diff --git a/pt-br/starter/installing.md b/pt-br/starter/installing.md old mode 100755 new mode 100644 index 5d0d307c05..0df59c460b --- a/pt-br/starter/installing.md +++ b/pt-br/starter/installing.md @@ -1,8 +1,9 @@ --- layout: page title: Instalando o Express +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: pt-br +redirect_from: " " --- # Instalação @@ -10,34 +11,29 @@ lang: pt-br Assumindo que já tenha instalado o [Node.js](https://nodejs.org/), crie um diretório para conter o seu aplicativo, e torne-o seu diretório ativo. +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. -
      -
      +```bash
       $ mkdir myapp
       $ cd myapp
      -
      -
      +``` Use o comando `npm init` para criar um arquivo `package.json` para o seu aplicativo. Para obter mais informações sobre como o `package.json` funciona, consulte [Detalhes do tratamento de package.json do npm](https://docs.npmjs.com/files/package.json). -
      -
      +```bash
       $ npm init
      -
      -
      +``` Este comando solicita por várias coisas, como o nome e versão do seu aplicativo. Por enquanto, é possível simplesmente pressionar RETURN para aceitar os padrões para a maioria deles, com as seguintes exceções: - -
      -
      +```
       entry point: (index.js)
      -
      -
      +``` Insira `app.js`, ou qualquer nome que deseje para o arquivo principal. Se desejar que seja `index.js`, pressione RETURN para aceitar o nome de @@ -46,26 +42,23 @@ arquivo padrão sugerido. Agora instale o Express no diretório `myapp` e salve-o na lista de dependências. Por exemplo: -
      -
      -$ npm install express --save
      -
      -
      +```bash +$ npm install express +``` Para instalar o Express temporariamente não o inclua na lista de dependências, omita a opção `--save`: -
      -
      -$ npm install express
      -
      -
      +```bash +$ npm install express --no-save +```
      Módulos do Node instalados com a opção `--save` são incluídas na lista `dependencies` no arquivo -`package.json`. -Posteriormente, executando `npm install` no diretório +`package.json`. Posteriormente, executando `npm install` no diretório `app` irá automaticamente instalar os módulos na lista de dependências.
      + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/pt-br/starter/static-files.md b/pt-br/starter/static-files.md old mode 100755 new mode 100644 index 3e4ced13d5..3e0950fa75 --- a/pt-br/starter/static-files.md +++ b/pt-br/starter/static-files.md @@ -1,8 +1,9 @@ --- layout: page title: Entregando arquivos estáticos no Express +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: pt-br +redirect_from: " " --- # Entregando arquivos estáticos no Express @@ -11,29 +12,32 @@ Para entregar arquivos estáticos como imagens, arquivos CSS, e arquivos JavaScript, use a função de middleware `express.static` integrada no Express. -Passe o nome do diretório que contém os ativos estáticos para a -função de middleware `express.static` para iniciar a -entregar os arquivos diretamente. Por exemplo, use o código a seguir +The function signature is: + +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +Por exemplo, use o código a seguir para entregar imagens, arquivos CSS, e arquivos JavaScript em um diretório chamado `public`: -
      -
      -app.use(express.static('public'));
      -
      -
      +```js +app.use(express.static('public')) +``` Agora, é possível carregar os arquivos que estão no diretório `public`: -
      -
      +```text
       http://localhost:3000/images/kitten.jpg
       http://localhost:3000/css/style.css
       http://localhost:3000/js/app.js
       http://localhost:3000/images/bg.png
       http://localhost:3000/hello.html
      -
      -
      +```
      O Express consulta os arquivos em relação ao diretório estático, para @@ -43,41 +47,36 @@ que o nome do diretório estático não faça parte da URL. Para usar vários diretórios de ativos estáticos, chame a função de middleware `express.static` várias vezes: -
      -
      -app.use(express.static('public'));
      -app.use(express.static('files'));
      -
      -
      +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` O Express consulta os arquivos na ordem em que você configurar os diretórios estáticos com a função de middleware `express.static`. -Para criar um prefixo de caminho virtual (onde o caminho não -existe realmente no sistema de arquivos) para arquivos que são -entregues pela função `express.static`, -[especifique um caminho de montagem](/{{ page.lang }}/4x/api.html#app.use) para o -diretório estático, como mostrado abaixo: +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
      -
      -app.use('/static', express.static('public'));
      -
      -
      +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` Agora, é possível carregar os arquivos que estão no diretório `public` a partir do prefixo do caminho `/static`. -
      -
      +```text
       http://localhost:3000/static/images/kitten.jpg
       http://localhost:3000/static/css/style.css
       http://localhost:3000/static/js/app.js
       http://localhost:3000/static/images/bg.png
       http://localhost:3000/static/hello.html
      -
      -
      +``` Entretanto, o caminho fornecido para a função `express.static` é relativa ao diretório a partir do @@ -86,8 +85,11 @@ executar o aplicativo express a partir de outro diretório, é mais seguro utilizar o caminho absoluto do diretório para o qual deseja entregar. -
      -
      -app.use('/static', express.static(__dirname + '/public'));
      -
      -
      +```js +const path = require('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.html). + +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/pt-br/support/index.md b/pt-br/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/pt-br/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/ru/3x/api.md b/ru/3x/api.md deleted file mode 100755 index 4cb1058d94..0000000000 --- a/ru/3x/api.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: 3x-api -title: Express 3.x - Справочник по API -menu: api -lang: ru ---- -
      - -
      - **Express 3.x НЕ ПОДДЕРЖИВАЕТСЯ** - - Известные и неизвестные проблемы безопасности и производительности в 3.x не устранялись с момента последнего обновления (1 августа 2015 г.). Настоятельно рекомендуется использовать последнюю версию Express. -
      - -

      API 3.x

      - - - {% include api/en/3x/express.md %} - - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} - - - {% include api/en/3x/res.md %} - - - {% include api/en/3x/middleware.md %} - -
      diff --git a/ru/4x/api.md b/ru/4x/api.md deleted file mode 100755 index 67d7e39c9c..0000000000 --- a/ru/4x/api.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - Справочник по API -menu: api -lang: ru ---- -
      - -

      API 4.x

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/ru/advanced/best-practice-performance.md b/ru/advanced/best-practice-performance.md deleted file mode 100755 index 5656442ca2..0000000000 --- a/ru/advanced/best-practice-performance.md +++ /dev/null @@ -1,458 +0,0 @@ ---- -layout: page -title: Лучшие практические методы улучшения производительности при использовании Express в рабочей среде -menu: advanced -lang: ru ---- - -# Лучшие практические методы для рабочей среды: производительность и надежность - -## Обзор - -В статье рассматриваются лучшие практические методы обеспечения производительности и надежности приложений Express, развернутых в рабочей среде. - -Рассматриваемая тема, без сомнения, относится к категории "DevOps", которая рассматривает процесс традиционной разработки программного обеспечения во взаимосвязи с эксплуатацией. Соответственно, представленную в ней информацию можно разделить на две части: - -* [что можно сделать в коде](#code) (разработка, Dev). -* [что можно сделать в среде / при настройке](#env) (эксплуатация, Ops). - - - -## Что можно сделать в коде - -Ниже приведены некоторые примеры того, что можно сделать в коде для улучшения производительности приложений. - -* Использовать сжатие gzip -* Не использовать синхронные функции -* Использовать промежуточные обработчики для обслуживания статических файлов -* Организовать корректное ведение протоколов -* Правильно обрабатывать исключительные ситуации - -### Использовать сжатие gzip - -Сжатие gzip может значительно уменьшить размер тела ответа и, соответственно, увеличить быстродействие веб-приложения. Используйте промежуточный обработчик для [сжатия](https://www.npmjs.com/package/compression) gzip в приложениях Express. Например: - -```js -var compression = require('compression') -var express = require('express') -var app = express() -app.use(compression()) -``` - -Для активно используемого веб-сайта в рабочей среде разумнее всего реализовать сжатие на уровне обратного прокси (см. раздел [Использование обратного прокси-сервера](#proxy)). В этом случае можно обойтись без промежуточного обработчика для сжатия данных. Более подробная информация об активации сжатия в Nginx приведена в разделе [Модуль сжатия ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html) документации по Nginx. - -### Не использовать синхронные функции - -Синхронные функции и методы задерживают выполнение процесса до возвращения ответа. Один вызов синхронной функции может возвращать значение через несколько микросекунд или миллисекунд, однако в активно используемых веб-сайтах эти вызовы дают суммарный эффект снижения производительности приложения. В рабочей среде от них лучше отказаться. - -Модуль Node и многие другие модули поддерживают синхронную и асинхронную версию выполнения функций; однако в рабочей среде следует использовать только асинхронную версию. Синхронное выполнение функций может быть оправдано только при первоначальном запуске. - -При работе с Node.js 4.0+ или io.js 2.1.0+ можно воспользоваться флагом командной строки `--trace-sync-io`, который выводит предупреждение и трассировку стека, если в приложении используется синхронный API. В рабочей системе это, конечно, лишнее; скорее, это позволяет убедиться, что код готов для рабочей среды. Дополнительная информация приведена в разделе [Еженедельное обновление io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0). - -### Использовать промежуточный обработчик для обслуживания статических файлов - -В среде разработки для обслуживания статических файлов можно использовать метод [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile). Для рабочей среды этот метод не подходит: при обработке каждого запроса файла он выполняет чтение из файловой системы, создавая большую задержку и снижая общую производительность приложения. Заметьте, что метод `res.sendFile()` *не* реализован для системного вызова [sendfile](http://linux.die.net/man/2/sendfile), который мог бы существенно повысить его эффективность. - -Рекомендуем воспользоваться промежуточным обработчиком [serve-static](https://www.npmjs.com/package/serve-static) (или аналогичным ему), оптимизированным для обслуживания файлов приложений Express. - -Еще лучше воспользоваться для обслуживания статических файлов обратным прокси; дополнительная информация приведена в разделе [Использование обратного прокси-сервера](#proxy). - -### Организовать корректное ведение протоколов - -В целом вести протоколы работы приложения необходимо по двум причинам: в целях отладки и в целях регистрации работы приложения (по сути, сюда относится все остальное). На этапе разработки, сообщения протокола обычно выводят на терминал при помощи `console.log()` или `console.err()`. Но в случае вывода на терминал или в файл [эти функции выполняются синхронно,](https://nodejs.org/api/console.html#console_console_1) поэтому для рабочей среды они подойдут только при условии вывода в другую программу. - -#### В целях отладки - -При ведении протокола в целях отладки рекомендуется вместо `console.log()` воспользоваться специальным отладочным модулем типа [debug](https://www.npmjs.com/package/debug). При работе с этим модулем можно использовать переменную среды DEBUG, которая определяет, какие отладочные сообщения будут переданы в `console.err()`. А для того чтобы приложения оставались чисто асинхронными, рекомендуется выводить результаты `console.err()` в другую программу. Но вы же не собираетесь заниматься отладкой в рабочей среде, верно? - -#### В целях регистрации работы приложения - -Для регистрации работы приложения (например, учета переданных данных или отслеживания вызовов API-функций) можно вместо `console.log()` воспользоваться библиотекой регистрации типа [Winston](https://www.npmjs.com/package/winston) или [Bunyan](https://www.npmjs.com/package/bunyan). Подробное сравнение двух библиотек проведено в корпоративном блоге StrongLoop [Сравнение протоколирования Node.js с использованием Winston и Bunyan](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - - - -### Правильно обрабатывать исключительные ситуации - -При наступлении необрабатываемой исключительной ситуации в приложениях Node происходит сбой. Если не обрабатывать исключительные ситуации и не принимать необходимых мер, это приведет к сбою и отключению приложения Express. Рекомендация из следующего раздела [Автоматический перезапуск приложения](#restart) поможет вам обеспечить восстановление приложения после сбоя. К счастью, приложения Express обычно имеют небольшое время запуска. Тем не менее, нужно позаботиться прежде всего о недопущении сбоев, для чего необходимо правильно обрабатывать исключительные ситуации. - -Для того чтобы в системе обрабатывались все исключительные ситуации, можно воспользоваться следующими методами: - -* [метод try-catch](#try-catch) -* [метод Promise](#promises) - -Прежде чем перейти к этим темам, необходимо понимать основные принципы обработки ошибок в Node/Express: использование функции обратного вызова, в которой первый аргумент зарезервирован за объектом ошибки, и распространение ошибок в промежуточном обработчике. В Node принято соглашение "error-first callback" для возврата ошибок асинхронных функций: первый параметр любой функции обратного вызова всегда является объектом-ошибкой, за ним следуют параметры, содержащие результат обработки. Для того чтобы сообщить об ошибке, в качестве первого параметра передайте нуль. Для правильной обработки ошибки функция обратного вызова должна соответствующим образом выполнять соглашение "error-first callback". В Express, как показала практика, лучший метод состоит в распространении ошибок по цепочке промежуточных обработчиков с использованием функции next(). - -Более подробная информация об основных принципах обработки ошибок приведена в разделе: - -* [Обработка ошибок в Node.js](https://www.joyent.com/developers/node/design/errors) -* [Разработка устойчивых к сбоям приложений Node: обработка ошибок](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (корпоративный блог StrongLoop) - -#### Чего не нужно делать - -Вам точно *не* нужно обрабатывать событие `uncaughtException`, порожденное при передаче исключительной ситуации обратно в цикл ожидания событий. Добавление обработчика события `uncaughtException` изменит стандартное поведение процесса, в котором произошла исключительная ситуация; процесс продолжит выполнение, несмотря на исключительную ситуацию. На первый взгляд, это неплохой способ защиты от сбоя приложения. Однако выполнение приложения после того, как произошла необрабатываемая исключительная ситуация, весьма опасно само по себе и не может быть рекомендовано: состояние процесса становится ненадежным и непредсказуемым. - -Кроме того, использование `uncaughtException` официально считается [crude](https://nodejs.org/api/process.html#process_event_uncaughtexception), и имеется вариант [proposal](https://github.com/nodejs/node-v0.x-archive/issues/2582) исключить его из ядра. Значит, обработка `uncaughtException` - идея неудачная. Поэтому мы и рекомендуем иметь несколько процессов и супервизоров: часто самым надежным способом восстановления после ошибки является удаление и перезапуск системы. - -Также мы не рекомендуем использовать модуль [domains](https://nodejs.org/api/domain.html). Он очень редко помогает решить проблему и является устаревшим. - - - -#### Метод try-catch - -Конструкция try-catch в языке JavaScript позволяет перехватывать исключительные ситуации в синхронном коде. Например, при помощи try-catch можно обрабатывать ошибки анализа JSON, как показано ниже. - -Инструменты типа [JSHint](http://jshint.com/) или [JSLint](http://www.jslint.com/) помогут вам найти неявные исключительные ситуации, подобные описанным в разделе [Ошибки ReferenceError в неопределенных переменных](http://www.jshint.com/docs/options/#undef). - -Ниже приводится пример использования конструкции try-catch для обработки потенциальной исключительной ситуации, приводящей к отказу процесса. -Этот промежуточный обработчик принимает параметр поля запроса "params", который является объектом JSON. - -```js -app.get('/search', (req, res) => { - // Simulating async operation - setImmediate(() => { - var jsonStr = req.query.params - try { - var jsonObj = JSON.parse(jsonStr) - res.send('Success') - } catch (e) { - res.status(400).send('Invalid JSON string') - } - }) -}) -``` - -Однако конструкция try-catch работает только для синхронного кода. Поскольку платформа Node является преимущественно асинхронной (в частности, в рабочей среде), с помощью конструкции try-catch удастся перехватить не так уж много исключительных ситуаций. - - - -#### Метод Promises - -Промисы (promises) обрабатывают любые исключительные ситуации (явные и неявные) в блоках асинхронного кода, в которых используется метод `then()`. Просто добавьте `.catch(next)` в конце цепочки промисов. Например: - -```js -app.get('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) -}) - -app.use((err, req, res, next) => { - // handle error -}) -``` - -Теперь все ошибки, асинхронные и синхронные, будут передаваться в промежуточный обработчик ошибок. - -Однако здесь необходимо разъяснить два момента: - -1. Весь асинхронный код должен возвращать промисы (кроме отправителей). Если какая-то библиотека не возвращает промисы, преобразуйте объект base при помощи вспомогательной функции типа [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Отправители событий (такие как потоки) могут вызывать необрабатываемые исключительные ситуации. Поэтому проверьте правильность обработки событий ошибки; например: - -```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) - -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) -``` - -Дополнительная информация об обработке ошибок с использованием промисов приведена в разделе: - -* [Обработка ошибок асинхронного кода в Express с использованием промисов, генераторов и ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Промисы в Node.js с Q - альтернатива функции обратного вызова](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) - - - -## Что можно сделать в среде / при настройке - -Ниже приведены некоторые примеры того, что можно сделать в среде функционирования системы для улучшения производительности приложений. - -* Задать в переменной NODE_ENV значение "production" -* Обеспечить автоматический перезапуск приложения -* Выполнять приложение в кластере -* Сохранять результаты запросов в кэше -* Использовать распределитель нагрузки -* Использовать обратный прокси-сервер - -### Задать в переменной NODE_ENV значение "production" - -Переменная среды NODE_ENV задает среду выполнения приложения (обычно это среда разработки или рабочая среда). Простейший способ улучшить производительность - задать в переменной NODE_ENV рабочую среду (значение "production"). - -Если NODE_ENV имеет значение "production", то в Express: - -* сохраняются в кэше шаблоны представления; -* сохраняются в кэше файлы CSS, сгенерированные из расширений CSS; -* генерируются менее подробные сообщения об ошибках. - -[Тестирование показывает,](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) что в результате только этих действий производительность увеличивается втрое. - -Если вам необходимо написать код для определенной среды, значение переменной NODE_ENV можно проверить в `process.env.NODE_ENV`. Следует помнить, что при проверке значения любой переменной среды производительность снижается, поэтому желательно производить эту операцию пореже. - -В среде разработки переменные среды обычно указываются в интерактивной оболочке, например при помощи `export` или файла `.bash_profile`. На рабочем сервере лучше использовать систему инициализации ОС (systemd или Upstart). В следующем разделе мы уделим больше внимания системе инициализации в целом, но задание значения переменной NODE_ENV настолько важно для производительности (и при этом настолько легко достижимо), что рассматривается здесь отдельно. - -Для Upstart укажите в своем файле файле задания ключевое слово `env`. Например: - -
      -
      -# /etc/init/env.conf
      - env NODE_ENV=production
      -
      -
      - -Дополнительная информация приведена в разделе [Upstart: введение, справочное руководство и лучшие практические методы](http://upstart.ubuntu.com/cookbook/#environment-variables). - -Для systemd укажите директиву `Environment` в своем файле юнитов. Например: - -
      -
      -# /etc/systemd/system/myservice.service
      -Environment=NODE_ENV=production
      -
      -
      - -Дополнительная информация приведена в разделе [Использование переменных среды в юнитах systemd](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). - -При работе с StrongLoop Process Manager можно также [задать переменную среды во время установки StrongLoop PM как службы](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). - -### Обеспечить автоматический перезапуск приложения - -В рабочей среде приложение не должно отключатся ни при каких условиях. Следовательно, необходимо обеспечить его перезапуск не только при сбое самого приложения, но и при сбое сервера. Надеясь на то, что этого не случится, мы должны быть реалистами и на всякий случай подготовиться, чтобы: - -* использовать диспетчер процессов для перезапуска приложения (и Node), когда произойдет его сбой; -* использовать систему инициализации ОС для перезапуска диспетчера процессов, когда произойдет сбой ОС. Систему инициализации можно использовать и без диспетчера процессов. - -При наступлении необрабатываемой исключительной ситуации в приложениях Node происходит сбой. Поэтому самое главное, что нужно сделать, - обеспечить, чтобы приложение было тщательно протестировано и обрабатывало все исключительные ситуации (дополнительная информация приведена в разделе [Правильно обрабатывать исключительные ситуации](#exceptions)). А для устойчивости к отказам необходимо иметь механизм, который обеспечит автоматический перезапуск приложения, если произойдет его сбой. - -#### Использовать диспетчер процессов - -В среде разработки запустить приложение можно прямо из командной строки, указав `node server.js` или нечто подобное. В рабочей среде это верный путь к беде: в случае сбоя приложение будет отключено до тех пор, пока вы не выполните его перезапуск. Для того чтобы приложение перезапускалось после сбоя, используется диспетчер процессов. Диспетчер процессов - это "контейнер" для приложений, обеспечивающий развертывание и высокую готовность и позволяющий управлять приложением в среде выполнения. - -Помимо перезапуска приложения после сбоя, диспетчер процессов позволяет: - -* получать аналитическую информацию о производительности среды выполнения и потреблении ресурсов; -* изменять параметры в динамическом режиме в целях повышения производительности; -* управлять кластеризацией (StrongLoop PM и pm2). - -Наиболее популярные диспетчеры процессов перечислены ниже: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -Сравнение трех диспетчеров процессов по каждой характеристике можно найти в разделе [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Более подробное представление трех диспетчеров приведено в разделе [Диспетчеры процессов для приложений Express](/{{ page.lang }}/advanced/pm.html). - -Наличие любого из этих диспетчеров процессов позволит обеспечить работоспособность приложения даже в случае возможных сбоев. - -Однако StrongLoop PM имеет массу характеристик, рассчитанных специально на развертывание в среде выполнения. StrongLoop и связанные с ним инструменты позволяют: - -* разрабатывать приложение и создавать его пакет в локальной системе и развертывать его в безопасном режиме в рабочей системе; -* автоматически перезапускать приложение после его сбоя независимо от причины; -* управлять кластерами в удаленном режиме; -* просматривать профайлы CPU и моментальные снимки кучи в целях оптимизации производительности и диагностирования утечек памяти; -* просматривать показатели производительности приложения; -* легко масштабировать для работы на нескольких хостах с возможностями встроенного управления распределителем нагрузки. - -Как объясняется ниже, при установке StrongLoop PM в качестве службы операционной системы с помощью системы инициализации, этот диспетчер будет автоматически выполнять перезапуск после перезагрузки системы. То есть, поддерживать постоянную активность процессов и кластеров. - -#### Использовать систему инициализации - -Следующий уровень надежности призван обеспечить перезапуск приложения при перезапуске сервера. Системы могут зависать по разным причинам. Для перезапуска приложения в случае сбоя сервера используйте систему инициализации, встроенную в вашу ОС. На данный момент используются две основные системы инициализации - [systemd](https://wiki.debian.org/systemd) и [Upstart](http://upstart.ubuntu.com/). - -Системы инициализации можно использовать с приложением Express двумя способами: - -* запустите приложение в диспетчере процессов и установите диспетчер процессов как службу в системе инициализации. Диспетчер процессов будет перезапускать приложение в случае сбоя приложения, система инициализации будет перезапускать диспетчер процессов в случае перезапуска ОС. Это рекомендуемый способ; -* запустите приложение (и Node) прямо в системе инициализации. Этот способ немного проще, но он лишает вас дополнительного преимущества - возможности использовать диспетчер процессов. - -##### Systemd - -Systemd - менеджер системы и служб для Linux. В большинстве основных дистрибутивов Linux systemd принят в качестве системы инициализации по умолчанию. - -Файл конфигурации службы systemd имеет имя *unit file* с расширением .service. Ниже приведен пример файла юнитов для непосредственного управления приложением Node (вместо выделенного жирным шрифтом текста укажите значения для своей системы и приложения): - -
      -
      -[Unit]
      -Description=Awesome Express App
      -
      -[Service]
      -Type=simple
      -ExecStart=/usr/local/bin/node /projects/myapp/index.js
      -WorkingDirectory=/projects/myapp
      -
      -User=nobody
      -Group=nogroup
      -
      -# Environment variables:
      -Environment=NODE_ENV=production
      -
      -# Allow many incoming connections
      -LimitNOFILE=infinity
      -
      -# Allow core dumps for debugging
      -LimitCORE=infinity
      -
      -StandardInput=null
      -StandardOutput=syslog
      -StandardError=syslog
      -Restart=always
      -
      -[Install]
      -WantedBy=multi-user.target
      -
      -
      -Дополнительная информация о systemd приведена в разделе [Справочник по systemd (страница справки)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM как служба systemd - -Диспетчер процессов StrongLoop можно легко установить как службу systemd. В этом случае во время перезапуска сервера автоматически выполняется перезапуск StrongLoop PM; он, в свою очередь, перезапускает все приложения, которыми он управляет. - -Для установки StrongLoop PM как службы systemd выполните следующие действия: - -
      -
      -$ sudo sl-pm-install --systemd
      -
      -
      - -Затем запустите службу в следующем порядке: - -
      -
      -$ sudo /usr/bin/systemctl start strong-pm
      -
      -
      - -Дополнительная информация приведена в разделе [Настройка хоста рабочей среды (документация по StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart - системный инструмент, доступный во многих дистрибутивах Linux; позволяет запускать задачи и службы во время запуска системы, останавливать их во время выключения и осуществлять наблюдение за их работой. Если приложение Express или диспетчер процессов настроен как служба, Upstart будет автоматически перезапускать их в случае сбоя. - -Служба Upstart определяется в файле конфигурации задания (другое название - "задание") с расширением `.conf`. Ниже приведен пример создания задания "myapp" для приложения "myapp", где главный файл находится в каталоге `/projects/myapp/index.js`. - -Создайте файл `myapp.conf` в каталоге `/etc/init/` со следующим содержимым (вместо выделенного жирным шрифтом текста укажите значения для своей системы и приложения): - -
      -
      -# When to start the process
      -start on runlevel [2345]
      -
      -# When to stop the process
      -stop on runlevel [016]
      -
      -# Increase file descriptor limit to be able to handle more requests
      -limit nofile 50000 50000
      -
      -# Use production mode
      -env NODE_ENV=production
      -
      -# Run as www-data
      -setuid www-data
      -setgid www-data
      -
      -# Run from inside the app dir
      -chdir /projects/myapp
      -
      -# The process to start
      -exec /usr/local/bin/node /projects/myapp/index.js
      -
      -# Restart the process if it is down
      -respawn
      -
      -# Limit restart attempt to 10 times within 10 seconds
      -respawn limit 10 10
      -
      -
      - -ПРИМЕЧАНИЕ. Для этого сценария требуется Upstart 1.4 или старшей версии с поддержкой в Ubuntu 12.04-14.10. - -Поскольку задание настроено для выполнения при запуске системы, ваше приложение будет запускаться вместе с операционной системой и автоматически перезапускаться в случае сбоя приложения или зависания системы. - -Помимо автоматического перезапуска приложения, Upstart позволяет выполнять следующие команды: - -* `start myapp` - запуск приложения -* `restart myapp` - перезапуск приложения -* `stop myapp` - остановка приложения - -Дополнительная информация об Upstart приведена в разделе [Upstart: введение, справочное руководство и лучшие практические методы](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM как служба Upstart - -Диспетчер процессов StrongLoop можно легко установить как службу Upstart. В этом случае во время перезапуска сервера автоматически выполняется перезапуск StrongLoop PM; он, в свою очередь, перезапускает все приложения, которыми он управляет. - -Для установки StrongLoop PM как службы Upstart 1.4 выполните следующие действия: - -
      -
      -$ sudo sl-pm-install
      -
      -
      - -Затем запустите службу в следующем порядке: - -
      -
      -$ sudo /sbin/initctl start strong-pm
      -
      -
      - -ПРИМЕЧАНИЕ. В системах, не поддерживающих Upstart 1.4, команды будут иметь некоторые отличия. Дополнительная информация приведена в разделе [Настройка хоста рабочей среды (документация по StrongLoop)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10). - -### Выполнять приложение в кластере - -В многоядерных системах производительность приложения Node можно увеличить многократно, если запустить группу процессов. В группе выполняется несколько экземпляров приложения, в идеале - один экземпляр на каждом ядре ЦП, что позволяет распределять нагрузку и задачи по экземплярам. - - - -ВАЖНОЕ ЗАМЕЧАНИЕ. Экземпляры приложения выполняются как отдельные процессы, поэтому они используют разные пространства памяти. То есть, объекты будут локальными для каждого экземпляра приложения. Значит, в коде приложения состояние не сохраняется. Зато можно использовать хранилище данных в оперативной памяти типа [Redis](http://redis.io/), в котором будут храниться связанные с сеансом данные и данные о состоянии. Эта оговорка относится по сути ко всем формам горизонтального масштабирования - в равной мере к и группам процессов, и к группам физических серверов. - -В кластерных приложениях сбой может произойти в процессах отдельного экземпляра приложения, не оказывая влияния на другие процессы. Помимо преимуществ улучшения производительности, изоляция сбоев также говорит в пользу выполнения процессов приложений в кластере. При любом сбое процесса экземпляра приложения обязательно занесите событие в протокол и породите новый процесс, используя метод cluster.fork(). - -#### Использовать модуль cluster Node - -Поддержка кластеров возможна благодаря модулю Node [cluster module](https://nodejs.org/docs/latest/api/cluster.html). Он позволяет главному процессу порождать процессы экземпляра приложения и распределять входящие соединения между экземплярами приложения. Но лучше использовать не сам этот модуль, а один из его инструментов, который будет выполнять необходимые действия автоматически, например [node-pm](https://www.npmjs.com/package/node-pm) или [cluster-service](https://www.npmjs.com/package/cluster-service). - -#### Использовать StrongLoop PM - -Если приложение развернуто в диспетчере процессов StrongLoop Process Manager (PM), вы можете пользоваться поддержкой кластеров, *не* изменяя код приложения. - -Когда диспетчер процессов StrongLoop Process Manager (PM) выполняет приложение, то приложение автоматически будет выполняться в кластере с числом экземпляров приложения, равным числу ядер ЦП в системе. В кластере число процессов экземпляра приложения невозможно изменить вручную при помощи инструмента командной строки slc без остановки приложения. - -Например, если вы развернули приложение на prod.foo.com и StrongLoop PM слушает соединения на порте 8701 (значение по умолчанию), укажите размер кластера, равный восьми, используя slc: - -
      -
      -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
      -
      -
      - -Дополнительная информация о поддержке кластеров при помощи StrongLoop PM приведена в разделе [Кластеризация](https://docs.strongloop.com/display/SLC/Clustering) документации по StrongLoop. - -### Сохранять результаты запросов в кэше - -Еще одна стратегия улучшения производительности в рабочей среде заключается в том, чтобы сохранять в кэше результат запросов, тогда приложению не нужно будет повторять операцию для многократного обслуживания этого запроса. - -Используйте сервер кэширования типа [Varnish](https://www.varnish-cache.org/) или [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (см. также [Кэширование Nginx](https://serversforhackers.com/nginx-caching/)), чтобы существенно увеличить быстродействие и производительность своего приложения. - -### Использовать распределитель нагрузки - -Вне зависимости от оптимизации приложения отдельный экземпляр может обработать лишь определенную часть рабочей нагрузки и передаваемых данных. Один из способов масштабирования приложения состоит в запуске нескольких его экземпляров и распределении передаваемых данных при помощи распределителя нагрузки. Настройка распределителя нагрузки может улучшить производительность и быстродействие приложения и нарастить его возможности сверх того, что может делать один экземпляр приложения. - -Распределителем нагрузки обычно выступает обратный прокси-сервер, который управляет передачей данных между несколькими экземплярами приложений и серверами. Распределитель нагрузки приложения можно легко настроить при помощи [Nginx](http://nginx.org/en/docs/http/load_balancing.html) или [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). - -При работе с распределителем нагрузки рекомендуется убедиться, что запросы, связанные с определенным идентификатором сеанса, подключены к породившему их процессу. Это называется *привязка к сеансу* или *закрепленные сеансы*, и решается с помощью описанной выше рекомендации использовать для сеансовых данных хранилище данных типа Redis (в зависимости от приложения). Описание приведено в разделе [Использовать несколько узлов](http://socket.io/docs/using-multiple-nodes/). - -#### Использовать StrongLoop PM с распределителем нагрузки Nginx - -[StrongLoop Process Manager](http://strong-pm.io/) интегрируется с Nginx Controller, позволяя легко настраивать конфигурации рабочих сред на нескольких хостах. Дополнительная информация приведена в разделе [Масштабирование на нескольких серверах](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (документация по StrongLoop). - - -### Использовать обратный прокси-сервер - -Обратный прокси-сервер расположен перед веб-приложением. Помимо направления запросов к приложению, он выполняет операции поддержки запросов. В частности, он способен обрабатывать страницы ошибок, операции сжатия, кэширования, обслуживания файлов и распределения нагрузки. - -Передача задач, для которых не требуется знать состояние приложения, обратному прокси-серверу разгружает Express для выполнения специализированных прикладных задач. В связи с этим в рабочей среде рекомендуется располагать Express за обратным прокси-сервером типа [Nginx](https://www.nginx.com/) или [HAProxy](http://www.haproxy.org/). diff --git a/ru/advanced/best-practice-security.md b/ru/advanced/best-practice-security.md deleted file mode 100755 index 4f97a5fa35..0000000000 --- a/ru/advanced/best-practice-security.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -layout: page -title: Лучшие практические методы защиты для Express в рабочей среде -menu: advanced -lang: ru ---- - -# Лучшие практические методы для рабочей среды: Защита - -## Обзор - -Термин *"рабочий режим"* означает тот этап жизненного цикла программного обеспечения, на котором приложение или API является в целом доступным для конечных пользователей или потребителей. Напротив, на этапе *"разработки"* происходит активное создание и тестирование кода, и приложение не является открытым для внешнего доступа. Соответствующие системные среды называются, соответственно, *рабочей* средой и средой *разработки*. - -Настройки среды разработки и рабочей среды при установке, как правило, являются различными, и к этим средам предъявляются абсолютно разные требования. То, что идеально для разработки, не всегда приемлемо в рабочем режиме. Например, в среде разработки можно задать подробное протоколирование ошибок для отладки, тогда как в рабочей среде такая особенность настройки может привести к уязвимости защиты. Во время разработки можно не беспокоиться о масштабируемости, надежности и производительности, тогда как в рабочем режиме все эти вопросы играют решающую роль. - -В настоящей статье речь пойдет о лучших практических методах в области защиты приложений Express, развернутых в рабочей среде. - -## Не используйте устаревшие или уязвимые версии Express - -Версии Express 2.x и 3.x больше не поддерживаются. Проблемы, связанные с защитой и производительностью в этих версиях, не будут подлежать решению. Не используйте эти версии! Если вы еще не перешли к работе с версией 4, выполните инструкции, приведенные в [руководстве по миграции](/{{ page.lang }}/guide/migrating-4.html). - -Кроме того, убедитесь в том, что уязвимые версии Express, перечисленные на странице [Обновления системы защиты](/{{ page.lang }}/advanced/security-updates.html), вами не используются. В противном случае, выполните обновление до одного из стабильных выпусков, предпочтительно, до последнего. - -## Использование TLS - -Если ваше приложение предназначено для работы с чувствительными данными или для их передачи, для защиты соединения и данных необходимо использовать криптографический протокол [Transport Layer Security](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). - -Возможно, вам знаком криптографический протокол Secure Socket Layer (SSL). [SSL является предшественником TLS](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). Другими словами, если раньше вы пользовались SSL, пора переходить к TLS. В целом, для работы с TLS мы рекомендуем использовать сервер Nginx. Подробные инструкции по настройке TLS на Nginx (и на других серверах) можно найти в разделе [Рекомендуемые конфигурации серверов (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). - -Кроме того, удобным инструментом для получения бесплатного сертификата TLS является [Let's Encrypt](https://letsencrypt.org/about/) - бесплатная, автоматическая и открытая сертификатная компания (CA), предоставленная корпорацией [Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/). - -## Использование Helmet - -[Helmet](https://www.npmjs.com/package/helmet) помогает защитить приложение от некоторых широко известных веб-уязвимостей путем соответствующей настройки заголовков HTTP. - -Helmet, по сути, представляет собой набор из девяти более мелких функций промежуточной обработки, обеспечивающих настройку заголовков HTTP, связанную с защитой: - -* [csp](https://github.com/helmetjs/csp) задает заголовок `Content-Security-Policy` для предотвращения атак межсайтового скриптинга и прочих межсайтовых вмешательств. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) удаляет заголовок `X-Powered-By`. -* [hsts](https://github.com/helmetjs/hsts) задает заголовок `Strict-Transport-Security`, принудительно активирующий защиту соединений с сервером (по протоколу HTTP с использованием SSL/TLS). -* [ieNoOpen](https://github.com/helmetjs/ienoopen) задает заголовок `X-Download-Options` для IE8+. -* [noCache](https://github.com/helmetjs/nocache) задает заголовок `Cache-Control` и заголовки Pragma для отключения кеширования на стороне клиента. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) задает заголовок `X-Content-Type-Options` для защиты браузеров от прослушивания (сниффинга) MIME ответов с отличным от объявленного типом содержимого (content-type). -* [frameguard](https://github.com/helmetjs/frameguard) задает заголовок `X-Frame-Options` для защиты от [кликджекинга](https://www.owasp.org/index.php/Clickjacking). -* [xssFilter](https://github.com/helmetjs/x-xss-protection) задает заголовок `X-XSS-Protection` для активации фильтра XSS (фильтра межсайтового скриптинга) в большинстве современных веб-браузеров. - -Установите Helmet, как обычный модуль: - -
      -
      -$ npm install --save helmet
      -
      -
      - -Затем используйте его в своем коде: - -
      -
      -...
      -var helmet = require('helmet');
      -app.use(helmet());
      -...
      -
      -
      - -### Как минимум, отключите заголовок X-Powered-By - -Если использовать Helmet не нужно, как минимум, отключите заголовок `X-Powered-By`. Злоумышленники могут использовать этот заголовок (включенный по умолчанию) для выявления приложений на базе Express и активации целенаправленных атак. - -Поэтому рекомендуется отключить данный заголовок с помощью метода `app.disable()`. - -
      -
      -app.disable('x-powered-by');
      -
      -
      - -Если вы используете `helmet.js`, это будет сделано автоматически. - -## Безопасное использование cookie - -Для того чтобы файлы cookie не подвергали опасности ваши приложения, не используйте стандартные имена сеансовых cookie и соответствующим образом настройте опции защиты файлов cookie. - -Существует два основных сеансовых модуля cookie для промежуточной обработки: - -* Модуль [express-session](https://www.npmjs.com/package/express-session), заменяющий собой промежуточный обработчик `express.session`, встроенный в Express 3.x. -* Модуль [cookie-session](https://www.npmjs.com/package/cookie-session), заменяющий собой промежуточный обработчик `express.cookieSession`, встроенный в Express 3.x. - -Основное различие между этими двумя модулями состоит в способе сохранения сеансовых данных cookie. Промежуточный обработчик [express-session](https://www.npmjs.com/package/express-session) сохраняет данные о сеансе на сервере; в самом файле cookie сохраняется только ИД сеанса, но не данные сеанса. По умолчанию, используется хранилище в оперативной памяти, но данный способ не предназначен для рабочей среды. В рабочей среде необходимо настроить масштабируемое хранилище сеансов; см. список [совместимых хранилищ сеансов](https://github.com/expressjs/session#compatible-session-stores). - -Промежуточный обработчик [cookie-session](https://www.npmjs.com/package/cookie-session), в отличие от описанного выше, реализует хранение на основе файлов cookie: выполняется полная сериализация сеанса в файл cookie, вместо того, чтобы сохранять только ключ сеанса. Этот способ следует использовать только при условии, что данные сеанса имеют относительно небольшой объем и легко могут быть преобразованы в элементарные значения (а не объекты). Хотя браузеры должны поддерживать не менее 4096 байт на каждый файл cookie, позаботьтесь о том, чтобы не допустить превышения данного ограничения. Размер не должен превышать 4093 байт на каждый домен. Кроме того, помните о том, что данные cookie являются видимыми для клиента, поэтому, если по какой-либо причине их следует защитить или скрыть, остановите свой выбор на модуле express-session как на более подходящем. - -### Не используйте стандартные имена сеансовых cookie - -Использование имен сеансовых cookie, предлагаемых по умолчанию, может сделать ваше приложение уязвимым для разного рода атак. В данном случае возникает та же проблема с безопасностью, что и при использовании заголовка `X-Powered-By`: потенциальный злоумышленник может воспользоваться им для идентификации на сервере и организации целенаправленных атак. - -Для того чтобы избежать такой проблемы, используйте обобщенные имена cookie; например, при использовании промежуточного обработчика [express-session](https://www.npmjs.com/package/express-session): - -
      -
      -var session = require('express-session');
      -app.set('trust proxy', 1) // trust first proxy
      -app.use( session({
      -   secret : 's3Cur3',
      -   name : 'sessionId',
      -  })
      -);
      -
      -
      - -### Настройка опций защиты cookie - -Для обеспечения защиты необходимо настроить следующие опции защиты файлов cookie: - -* `secure` - обеспечивает отправку файлов cookie браузером только с использованием протокола HTTPS. -* `httpOnly` - обеспечивает отправку cookie только с использованием протокола HTTP(S), а не клиентского JavaScript, что способствует защите от атак межсайтового скриптинга. -* `domain` - указывает домен cookie; используется для сравнения с доменом сервера, на котором запрашивается данный URL. В случае совпадения выполняется проверка следующего атрибута - пути. -* `path` - указывает путь cookie; используется для сравнения с путем запроса. Если путь и домен совпадают, выполняется отправка cookie в запросе. -* `expires` - используется для настройки даты окончания срока хранения для постоянных cookie. - -Ниже приведен пример с использованием промежуточного обработчика [cookie-session](https://www.npmjs.com/package/cookie-session): - -
      -
      -var session = require('cookie-session');
      -var express = require('express');
      -var app = express();
      -
      -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
      -app.use(session({
      -  name: 'session',
      -  keys: ['key1', 'key2'],
      -  cookie: { secure: true,
      -            httpOnly: true,
      -            domain: 'example.com',
      -            path: 'foo/bar',
      -            expires: expiryDate
      -          }
      -  })
      -);
      -
      -
      - -## Дополнительные замечания - -Ниже приводится несколько дополнительных рекомендаций, взятых из исчерпывающего [Контрольного списка требований к защите Node.js](https://blog.risingstack.com/node-js-security-checklist/). В этой публикации можно найти дополнительную информацию по всем приведенным ниже рекомендациям: - -* Введите ограничение скорости передачи данных во избежание атак методом грубого подбора сочетаний символов для идентификации. Для реализации стратегии ограничения скорости передачи данных можно воспользоваться [Шлюзом API StrongLoop](https://strongloop.com/node-js/api-gateway/). В качестве альтернативы, можно использовать промежуточный обработчик, например, [express-limiter](https://www.npmjs.com/package/express-limiter), но для этого придется внести некоторые изменения в код. -* Используйте промежуточный обработчик [csurf](https://www.npmjs.com/package/csurf) для защиты от подделки межсайтовых запросов (CSRF). -* Всегда применяйте фильтрацию и очистку пользовательского ввода в целях защиты от атак межсайтового скриптинга (XSS) и ввода ложных команд. -* Обеспечьте защиту от атак внедрения SQL-кода с помощью параметризованных запросов или подготовленных операторов. -* Используйте инструмент [sqlmap](http://sqlmap.org/) с открытым исходным кодом для выявления уязвимостей к внедрению SQL-кода в приложение. -* Используйте инструменты [nmap](https://nmap.org/) и [sslyze](https://github.com/nabla-c0d3/sslyze) для проверки конфигурации шифров, ключей и повторных согласований SSL, а также действительности сертификата. -* Используйте [safe-regex](https://www.npmjs.com/package/safe-regex), чтобы убедиться в невосприимчивости регулярных выражений к атакам [отказа в обслуживании регулярных выражений](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). - -## Избегайте прочих известных уязвимостей - -Следите за рекомендациями [Node Security Project](https://npmjs.com/advisories), касающимися Express или других модулей, используемых вашим приложением. В целом, Node Security Project - это непревзойденный ресурс, предоставляющий ценные знания и инструменты, связанные с безопасностью Node. - -И наконец, приложения Express - как и любые другие приложения - могут быть уязвимы к разнообразным веб-атакам. Ознакомьтесь с описаниями известных [веб-уязвимостей](https://www.owasp.org/index.php/Top_10_2013-Top_10) и примите соответствующие меры предосторожности, чтобы их избежать. diff --git a/ru/advanced/developing-template-engines.md b/ru/advanced/developing-template-engines.md deleted file mode 100755 index 9c4953427c..0000000000 --- a/ru/advanced/developing-template-engines.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -layout: page -title: Разработка шаблонизаторов для Express -menu: advanced -lang: ru ---- - -# Разработка шаблонизаторов для Express - -Для создания собственного шаблонизатора воспользуйтесь методом `app.engine(ext, callback)`. `ext` соответствует расширению имени файла, а `callback` является функцией шаблонизатора, принимающей в качестве параметров следующие элементы: расположение файла, объект опций и функцию обратного вызова. - -Приведенный ниже код служит примером реализации самого простого шаблонизатора для вывода файлов `.ntl`. - -
      -
      -var fs = require('fs'); // this engine requires the fs module
      -app.engine('ntl', function (filePath, options, callback) { // define the template engine
      -  fs.readFile(filePath, function (err, content) {
      -    if (err) return callback(new Error(err));
      -    // this is an extremely simple template engine
      -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
      -    .replace('#message#', '

      '+ options.message +'

      '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
      -
      - -Теперь ваше приложение сможет отображать файлы `.ntl`. Создайте файл с именем `index.ntl` в каталоге `views` со следующим содержимым. - -
      -
      -#title#
      -#message#
      -
      -
      -Затем создайте следующий маршрут в своем приложении. - -
      -
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -
      -При выполнении запроса к домашней странице файл `index.ntl` будет отображаться как HTML. diff --git a/ru/advanced/pm.md b/ru/advanced/pm.md deleted file mode 100755 index 181c188812..0000000000 --- a/ru/advanced/pm.md +++ /dev/null @@ -1,283 +0,0 @@ ---- -layout: page -title: Диспетчеры процессов для приложений Express -menu: advanced -lang: ru ---- - -# Диспетчеры процессов для приложений Express - -При запуске приложения Express для рабочей среды использование *диспетчера процессов* позволяет выполнять следующие задачи: - -- Автоматически перезапускать приложение в случае сбоя. -- Получать аналитическую информацию о производительности среды выполнения и потреблении ресурсов. -- Изменять параметры в динамическом режиме в целях повышения производительности. -- Управлять кластеризацией. - -Диспетчер процессов можно сравнить с сервером приложений: это "контейнер" для приложений, обеспечивающий развертывание и высокую готовность и позволяющий управлять приложением в среде выполнения. - -Наиболее популярные диспетчеры процессов для Express и других приложений Node.js перечислены ниже: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -Использование любого из этих трех инструментов может быть исключительно полезным, тем не менее StrongLoop Process Manager является единственным инструментом, предоставляющим универсальное решение для среды выполнения и развертывания в течение всего жизненного цикла приложения Node.js и включающим в себя, в виде единого интерфейса, все средства для каждого этапа, как до перехода в рабочий режим, так и в рабочей среде. - -Ниже приводится краткий обзор каждого из этих инструментов. -Подробное сравнение можно найти в разделе [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) - это рабочий диспетчер процессов для приложений Node.js. В StrongLoop PM предусмотрено встроенное распределение нагрузки, мониторинг, развертывание на нескольких хостах и графическая консоль. -С помощью StrongLoop PM можно выполнять следующие задачи: - -- Компоновать, объединять в пакет и развертывать приложение Node.js в локальной или удаленной системе. -- Просматривать профайлы CPU и моментальные снимки кучи в целях оптимизации производительности и диагностирования утечек памяти. -- Поддерживать постоянную активность процессов и кластеров. -- Просматривать показатели производительности приложения. -- Без затруднений управлять развертываниями на нескольких хостах с интеграцией Nginx. -- Объединять несколько диспетчеров StrongLoop PM в распределенную среду выполнения микрослужб, управляемую из Arc. - -Работать с StrongLoop PM можно посредством многофункционального интерфейса командной строки, называемого `slc`, или графического инструмента Arc. Arc имеет открытый исходный код и обеспечен экспертной поддержкой StrongLoop. - -Дополнительная информация содержится на странице [http://strong-pm.io/](http://strong-pm.io/). - -Полная версия документации: - -- [Управляющие приложения Node (Документация StrongLoop)](http://docs.strongloop.com/display/SLC) -- [Использование StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Установка -
      -
      -$ [sudo] npm install -g strongloop
      -
      -
      - -### Основы использования -
      -
      -$ cd my-app
      -$ slc start
      -
      -
      - -Просмотр состояния диспетчера процессов и всех развернутых приложений: - -
      -
      -$ slc ctl
      -Service ID: 1
      -Service Name: my-app
      -Environment variables:
      -  No environment variables defined
      -Instances:
      -    Version  Agent version  Cluster size
      -     4.1.13      1.5.14           4
      -Processes:
      -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
      -    1.1.57692  57692   0
      -    1.1.57693  57693   1     0.0.0.0:3001
      -    1.1.57694  57694   2     0.0.0.0:3001
      -    1.1.57695  57695   3     0.0.0.0:3001
      -    1.1.57696  57696   4     0.0.0.0:3001
      -
      -
      - -Вывод списка всех приложений (служб), подлежащих управлению: - -
      -
      -$ slc ctl ls
      -Id          Name         Scale
      - 1          my-app       1
      -
      -
      - -Остановка приложения: - -
      -
      -$ slc ctl stop my-app
      -
      -
      - -Перезапуск приложения: - -
      -
      -$ slc ctl restart my-app
      -
      -
      - -Также можно выполнить "мягкий перезапуск", при котором рабочим процессам выделяется определенное время на закрытие существующих соединений, после чего текущее приложение перезапускается: - -
      -
      -$ slc ctl soft-restart my-app
      -
      -
      - -Удаление приложения из числа подлежащих управлению: - -
      -
      -$ slc ctl remove my-app
      -
      -
      - -## PM2 - -PM2 - это диспетчер процессов рабочей среды для приложений Node.js, в котором предусмотрен встроенный инструмент распределения нагрузки. PM2 позволяет всегда поддерживать приложения в рабочем состоянии и перезагружать их без простоев, а также обеспечивает выполнение общих задач системного администрирования. PM2 также позволяет управлять ведением протоколов, мониторингом и кластеризацией приложений. - -Дополнительная информация содержится на странице [https://github.com/Unitech/pm2/](https://github.com/Unitech/pm2). - -### Установка - -
      -
      -$ [sudo] npm install pm2 -g
      -
      -
      - -### Основы использования - -При запуске приложения с помощью команды `pm2` необходимо указать путь к приложению. Тем не менее, при остановке, перезапуске или удалении приложения можно указать только имя или ИД приложения. - -
      -
      -$ pm2 start npm --name my-app -- start
      -[PM2] restartProcessId process id 0
      -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
      -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
      -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
      -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
      -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
      - Use the `pm2 show ` command to get more details about an app.
      -
      -
      - -При запуске приложения с помощью команды `pm2` оно немедленно переводится в фоновый режим. Фоновым приложением можно управлять из командной строки с помощью различных команд `pm2`. - -После запуска приложения с помощью команды `pm2` оно регистрируется в списке процессов PM2 с указанием ИД. Затем можно управлять приложениями с тем же именем из различных каталогов в системе, используя только их ИД. - -Обратите внимание на то, что если запущено несколько приложений с одинаковым именем, команды `pm2` применяются ко всем таким приложениям. Поэтому для управления отдельными приложениями используйте не имена, а ИД. - -Список всех запущенных процессов: - -
      -
      -$ pm2 list
      -
      -
      - -Остановка приложения: - -
      -
      -$ pm2 stop 0
      -
      -
      - -Перезапуск приложения: - -
      -
      -$ pm2 restart 0
      -
      -
      - -Просмотр подробной информации о приложении: - -
      -
      -$ pm2 show 0
      -
      -
      - -Удаление приложения из реестра PM2: - -
      -
      -$ pm2 delete 0
      -
      -
      - - -## Forever - -Forever представляет собой простой инструмент интерфейса командной строки, обеспечивающий непрерывное (бесконечное) выполнение определенного сценария. Благодаря простому интерфейсу Forever является идеальным инструментом для выполнения не столь масштабных развертываний приложений и сценариев Node.js. - -Дополнительная информация содержится на странице [https://github.com/foreverjs/forever/](https://github.com/foreverjs/forever). - -### Установка - -
      -
      -$ [sudo] npm install forever -g
      -
      -
      - -### Основы использования - -Для запуска сценария воспользуйтесь командой `forever start` и укажите путь к сценарию: - -
      -
      -$ forever start script.js
      -
      -
      - -Эта команда запустит сценарий в режиме демона (в фоновом режиме). - -Для запуска сценария таким образом, чтобы он был соединен с терминалом, не указывайте `start`: - -
      -
      -$ forever script.js
      -
      -
      - -Целесообразно регистрировать вывод инструмента Forever и сценария в протоколе, используя для этого опции ведения протоколов `-l`, `-o` и `-e`, как показано в примере ниже: - -
      -
      -$ forever start -l forever.log -o out.log -e err.log script.js
      -
      -
      - -Для просмотра списка сценариев, запущенных с помощью Forever: - -
      -
      -$ forever list
      -
      -
      - -Для остановки сценария, запущенного с помощью Forever, воспользуйтесь командой `forever stop` и укажите индекс процесса (согласно списку, выведенному с помощью команды `forever list`). - -
      -
      -$ forever stop 1
      -
      -
      - -В качестве альтернативы, укажите путь к файлу: - -
      -
      -$ forever stop script.js
      -
      -
      - -Для остановки всех сценариев, запущенных с помощью Forever: - -
      -
      -$ forever stopall
      -
      -
      - -В Forever предусмотрено множество других опций, и, кроме того, данным инструментом предоставляется программный API. diff --git a/ru/advanced/security-updates.md b/ru/advanced/security-updates.md deleted file mode 100755 index cf57a10d70..0000000000 --- a/ru/advanced/security-updates.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -layout: page -title: Обновления системы безопасности Express -menu: advanced -lang: ru ---- - -# Обновления системы безопасности - -
      -Уязвимости Node.js оказывают непосредственное влияние на Express. Поэтому необходимо [пристально отслеживать уязвимости Node.js](http://blog.nodejs.org/vulnerability/) и обязательно использовать только последнюю, стабильную версию Node.js. -
      - -В приведенном ниже списке перечислены уязвимости Express, которые были устранены в указанном обновлении версии. - -## 4.x - - * 4.11.1 - * Исправлена уязвимость раскрытия корневого пути в `express.static`, `res.sendfile` и `res.sendFile` - * 4.10.7 - * Исправлена уязвимость открытого перенаправления в `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 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 возможна утечка `fd` в некоторых ситуациях, что влияет на `express.static` и `res.sendfile`. Утечка `fd` может возникнуть вследствие вредоносных запросов и в итоге привести к ошибкам `EMFILE` и недоступности сервера. - * 4.8.0 - * Разреженные массивы с крайне высокими индексами в строке запроса могут привести к исчерпанию памяти процессом и сбою на сервере. - * Объекты строки запроса с очень высокой степенью вложенности могут привести к блокировке процесса и временной недоступности сервера. - -## 3.x - - * 3.19.1 - * Исправлена уязвимость раскрытия корневого пути в `express.static`, `res.sendfile` и `res.sendFile` - * 3.19.0 - * Исправлена уязвимость открытого перенаправления в `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Исправлены уязвимости обхода каталогов в `express.static`. - * 3.16.6 - * В Node.js 0.10 возможна утечка `fd` в некоторых ситуациях, что влияет на `express.static` и `res.sendfile`. Утечка `fd` может возникнуть вследствие вредоносных запросов и в итоге привести к ошибкам `EMFILE` и недоступности сервера. - * 3.16.0 - * Разреженные массивы с крайне высокими индексами в строке запроса могут привести к исчерпанию памяти процессом и сбою на сервере. - * Объекты строки запроса с очень высокой степенью вложенности могут привести к блокировке процесса и временной недоступности сервера. - * 3.3.0 - * Код ответа 404, полученный вследствие попытки переопределения неподдерживаемого метода, был подвержен атакам межсайтового скриптинга. diff --git a/ru/api.md b/ru/api.md deleted file mode 100755 index 273d948a23..0000000000 --- a/ru/api.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - Справочник API -lang: ru ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/ru/guide/behind-proxies.md b/ru/guide/behind-proxies.md deleted file mode 100755 index 3c1a05a5ed..0000000000 --- a/ru/guide/behind-proxies.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -layout: page -title: Express за прокси -menu: guide -lang: ru ---- - -# Express за прокси - -При запуске приложения Express за прокси-сервером, необходимо указать (с помощью [app.set()](/{{ page.lang }}/4x/api.html#app.set)) для переменной приложения `trust proxy` одно из значений, приведенных в таблице ниже. - -
      -Хотя приложение будет запущено и без указания значения переменной приложения `trust proxy`, отсутствие заданного значения `trust proxy` приведет к некорректной регистрации IP-адреса прокси в качестве клиентского IP-адреса. -
      - - - - - - - - - - - - - - - - - - - - - -
      ТипЗначение
      Булевский -Если указано значение `true`, клиентским IP-адресом считается первая слева запись в заголовке `X-Forwarded-*`. - -Если указано значение `false`, приложение считается имеющим прямой выход в Интернет, и IP-адрес клиента будет производным от `req.connection.remoteAddress`. Это значение используется по умолчанию. -
      IP-адреса -IP-адрес, подсеть или массив IP-адресов и подсетей, считающихся надежными. В приведенном ниже списке перечислены предварительно заданные имена подсетей: - -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` - -IP-адреса можно задать любым из указанных ниже способов: - -
      -app.set('trust proxy', 'loopback') // specify a single subnet
      -app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
      -app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
      -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
      -
      - -Если IP-адреса или подсети указаны, они исключаются из процесса определения адреса, и незащищенный IP-адрес, ближайший к серверу приложений, будет определен как IP-адрес клиента. -
      Число -Считать защищенным `n`-й элемент пути от прокси-сервера со стороны клиента, в качестве клиента. -
      Функция -Реализация нестандартного механизма защиты. Используйте этот метод, только если вы уверены в своих знаниях. -
      -app.set('trust proxy', function (ip) {
      -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
      -  else return false;
      -});
      -
      -
      - -Установка значения, отличного от `false`, для `trust proxy` ведет к трем существенным изменениям: - -
        -
      • Значение [req.hostname](/{{ page.lang }}/api.html#req.hostname) является производным от значения, указанного в заголовке `X-Forwarded-Host`, который может быть задан клиентом или прокси. -
      • -
      • Заголовок `X-Forwarded-Proto` может быть задан обратным прокси-сервером и указывает приложению на использование протокола `https`, или `http`, или даже недопустимого имени. Это значение отражается в [req.protocol](/{{ page.lang }}/api.html#req.protocol). -
      • -
      • Значения [req.ip](/{{ page.lang }}/api.html#req.ip) и [req.ips](/{{ page.lang }}/api.html#req.ips) заполняются собой списком адресов, взятых из `X-Forwarded-For`. -
      • -
      - -Параметр `trust proxy` реализуется с помощью пакета [proxy-addr](https://www.npmjs.com/package/proxy-addr). Дополнительная информация приведена в документации к нему. diff --git a/ru/guide/database-integration.md b/ru/guide/database-integration.md deleted file mode 100755 index 7708ed75f0..0000000000 --- a/ru/guide/database-integration.md +++ /dev/null @@ -1,370 +0,0 @@ ---- -layout: page -title: Интеграция Express с базами данных -menu: guide -lang: ru ---- - -# Интеграция с базами данных - -Для того чтобы добавить функциональную возможность подключения базы данных к приложению Express, необходимо всего лишь загрузить в ваше приложение драйвер Node.js для соответствующей базы данных. В настоящем документе кратко описан способ добавления и использования в приложении Express некоторых наиболее популярных моделей Node.js для систем баз данных: - -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) - -
      -Это неполный список доступных драйверов баз данных. С другими вариантами можно ознакомиться на сайте [npm](https://www.npmjs.com/). -
      - - - -## Cassandra - -**Модуль**: [cassandra-driver](https://github.com/datastax/nodejs-driver) - -**Установка** - -
      -
      -$ npm install cassandra-driver
      -
      -
      - -**Пример** - -
      -
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      -
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      -
      - - - -## CouchDB - -**Модуль**: [nano](https://github.com/dscape/nano) - -**Установка** - -
      -
      -$ npm install nano
      -
      -
      - -**Пример** - -
      -
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      -
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      -  }
      -});
      -
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      -
      - - - -## LevelDB - -**Модуль**: [levelup](https://github.com/rvagg/node-levelup) - -**Установка** - -
      -
      -$ npm install level levelup leveldown
      -
      -
      - -**Пример** - -
      -
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      -
      -db.put('name', 'LevelUP', function (err) {
      -
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      -
      -});
      -
      -
      - - - -## MySQL - -**Модуль**: [mysql](https://github.com/felixge/node-mysql/) - -**Установка** - -
      -
      -$ npm install mysql
      -
      -
      - -**Пример** - -
      -
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      -
      -connection.connect();
      -
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      -
      -connection.end();
      -
      -
      - - - -## MongoDB - -**Модуль**: [mongodb](https://github.com/mongodb/node-mongodb-native) - -**Установка** - -
      -
      -$ npm install mongodb
      -
      -
      - -**Пример** - -
      -
      -var MongoClient = require('mongodb').MongoClient;
      -
      -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
      -  if (err) {
      -    throw err;
      -  }
      -  db.collection('mammals').find().toArray(function(err, result) {
      -    if (err) {
      -      throw err;
      -    }
      -    console.log(result);
      -  });
      -});
      -
      -
      - -Если вам необходим драйвер объектной модели для MongoDB, его можно найти на странице [Mongoose](https://github.com/LearnBoost/mongoose). - - - -## Neo4j - -**Модуль**: [apoc](https://github.com/hacksparrow/apoc) - -**Установка** - -
      -
      -$ npm install apoc
      -
      -
      - -**Пример** - -
      -
      -var apoc = require('apoc');
      -
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      -  }
      -);
      -
      -
      - - - -## PostgreSQL - -**Модуль**: [pg-promise](https://github.com/vitaly-t/pg-promise) - -**Установка** - -
      -
      -$ npm install pg-promise
      -
      -
      - -**Пример** - -
      -
      -var pgp = require("pg-promise")(/*options*/);
      -var db = pgp("postgres://username:password@host:port/database");
      -
      -db.one("SELECT $1 AS value", 123)
      -    .then(function (data) {
      -        console.log("DATA:", data.value);
      -    })
      -    .catch(function (error) {
      -        console.log("ERROR:", error);
      -    });
      -
      -
      - - - -## Redis - -**Модуль**: [redis](https://github.com/mranney/node_redis) - -**Установка** - -
      -
      -$ npm install redis
      -
      -
      - -**Пример** - -
      -
      -var client = require('redis').createClient();
      -
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      -
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      -
      -client.hkeys('hash key', function (err, replies) {
      -
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      -
      -  client.quit();
      -
      -});
      -
      -
      - - - -## SQLite - -**Модуль**: [sqlite3](https://github.com/mapbox/node-sqlite3) - -**Установка** - -
      -
      -$ npm install sqlite3
      -
      -
      - -**Пример** - -
      -
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      -
      -db.serialize(function() {
      -
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      -
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      -  }
      -
      -  stmt.finalize();
      -
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      -
      -db.close();
      -
      -
      - - - -## ElasticSearch - -**Модуль**: [elasticsearch](https://github.com/elastic/elasticsearch-js) - -**Установка** - -
      -
      -$ npm install elasticsearch
      -
      -
      - -**Пример** - -
      -
      -var elasticsearch = require('elasticsearch');
      -var client = elasticsearch.Client({
      -  host: 'localhost:9200'
      -});
      -
      -client.search({
      -  index: 'books',
      -  type: 'book',
      -  body: {
      -    query: {
      -      multi_match: {
      -        query: 'express js',
      -        fields: ['title', 'description']
      -      }
      -    }
      -  }
      -}).then(function(response) {
      -  var hits = response.hits.hits;
      -}, function(error) {
      -  console.trace(error.message);
      -});
      -
      -
      diff --git a/ru/guide/debugging.md b/ru/guide/debugging.md deleted file mode 100755 index ae6bc1d79e..0000000000 --- a/ru/guide/debugging.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -layout: page -title: Отладка Express -menu: guide -lang: ru ---- - -# Отладка Express - -В Express используется внутренний модуль [debug](https://www.npmjs.com/package/debug) для -регистрации информации о сопоставлениях маршрутов, используемых функциях промежуточной обработки, режиме приложения и выполнении цикла "запрос-ответ". - -
      -`debug` можно сравнить с расширенной версией `console.log`, но, в отличие от `console.log`, в рабочем коде не нужно добавлять символы комментария к протоколам `debug`. Ведение протокола по умолчанию выключено, но его можно условно активировать с помощью среды переменной `DEBUG`. -
      - -Для просмотра всех внутренних протоколов, используемых в Express, при запуске приложения задайте для переменной среды `DEBUG` значение `express:*`. - -
      -
      -$ DEBUG=express:* node index.js
      -
      -
      - -В Windows используется соответствующая команда. - -
      -
      -> set DEBUG=express:* & node index.js
      -
      -
      - -При запуске этой команды в стандартном приложении, созданном с помощью [генератора приложений Express](/{{ page.lang }}/starter/generator.html), будет получен следующий вывод: - -
      -
      -$ 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 / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -
      -
      - -При последующем запросе, адресованном приложению, вы увидите протоколы, заданные в коде Express: - -
      -
      -  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
      -
      -
      - -Для просмотра протоколов только из реализации маршрутизатора, задайте для переменной `DEBUG` значение `express:router`. Аналгичным образом, для просмотра протоколов только из реализации приложения, задайте для переменной `DEBUG` значение `express:application` и т.д. - -## Приложения, генерируемые с помощью команды `express` - -Приложение, генерируемое с помощью команды `express`, также использует модуль `debug`, и область действия пространства имен отладки определяется именем приложения. - -Например, если приложение сгенерировано с помощью команды `$ express sample-app`, операторы отладки (операторы debug) можно активировать с помощью следующей команды: - -
      -
      -$ DEBUG=sample-app:* node ./bin/www
      -
      -
      - -Можно указать несколько пространств имен для отладки, путем ввода списка имен через запятую: - -
      -
      -$ DEBUG=http,mail,express:* node index.js
      -
      -
      - -Дополнительная информация о модуле `debug` приведена на странице [debug](https://www.npmjs.com/package/debug). diff --git a/ru/guide/error-handling.md b/ru/guide/error-handling.md deleted file mode 100755 index c9def1af81..0000000000 --- a/ru/guide/error-handling.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -layout: page -title: Обработка ошибок в Express -menu: guide -lang: ru ---- - -# Обработка ошибок - -Функции промежуточного обработчика для обработки ошибок определяются так же, как и другие функции промежуточной обработки, но с указанием для функции обработки ошибок не трех, а четырех аргументов: `(err, req, res, next)`. Например: - -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      - -Промежуточный обработчик для обработки ошибок должен быть определен последним, после указания всех `app.use()` и вызовов маршрутов; например: - -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      -  // logic
      -});
      -
      -
      - -Ответы, поступающие из функции промежуточной обработки, могут иметь любой формат, в зависимости от ваших предпочтений. Например, это может быть страница сообщения об ошибке HTML, простое сообщение или строка JSON. - -В целях упорядочения (и для фреймворков более высокого уровня) можно определить несколько функций промежуточной обработки ошибок, точно так же, как это допускается для обычных функций промежуточной обработки. Например, для того чтобы определить обработчик ошибок для запросов, совершаемых с помощью `XHR`, и для остальных запросов, можно воспользоваться следующими командами: - -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      -
      - -В данном примере базовый код `logErrors` может записывать информацию о запросах и ошибках в `stderr`, например: - -
      -
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      -
      - -Кроме того, в данном примере `clientErrorHandler` определен, как указано ниже; в таком случае ошибка явным образом передается далее следующему обработчику: - -
      -
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      -  } else {
      -    next(err);
      -  }
      -}
      -
      -
      - -"Обобщающая" функция `errorHandler` может быть реализована так: - -
      -
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      - -При передаче какого-либо объекта в функцию `next()` (кроме строки `'route'`), Express интерпретирует текущий запрос как ошибку и пропустит все остальные функции маршрутизации и промежуточной обработки, не являющиеся функциями обработки ошибок. Для того чтобы обработать данную ошибку определенным образом, необходимо создать маршрут обработки ошибок, как описано в следующем разделе. - -Если задан обработчик ошибок с несколькими функциями обратного вызова, можно воспользоваться параметром `route`, чтобы перейти к следующему обработчику маршрута. Например: - -
      -
      -app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      -
      -      // continue handling this request
      -      next('route');
      -    }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      -
      - -В данном примере обработчик `getPaidContent` будет пропущен, но выполнение всех остальных обработчиков в `app` для `/a_route_behind_paywall` будет продолжено. - -
      -Вызовы `next()` и `next(err)` указывают на завершение выполнения текущего обработчика и на его состояние. `next(err)` пропускает все остальные обработчики в цепочке, кроме заданных для обработки ошибок, как описано выше. -
      - -## Стандартный обработчик ошибок - -В Express предусмотрен встроенный обработчик ошибок, который обрабатывает любые возможные ошибки, встречающиеся в приложении. Этот стандартный обработчик ошибок добавляется в конец стека функций промежуточной обработки. - -В случае передачи ошибки в `next()` без обработки с помощью обработчика ошибок, такая ошибка будет обработана встроенным обработчиком ошибок. Ошибка будет записана на клиенте с помощью трассировки стека. Трассировка стека не включена в рабочую среду. - -
      -Для запуска приложения в рабочем режиме необходимо задать для переменной среды `NODE_ENV` значение `production`. -
      - -При вызове `next()` с ошибкой после начала записи ответа -(например, если ошибка обнаружена во время включения ответа в поток, направляемый клиенту), стандартный обработчик ошибок Express закрывает соединение и отклоняет запрос. - -Поэтому при добавлении нестандартного обработчика ошибок вам потребуется делегирование в стандартные -механизмы обработки ошибок в Express в случае, если заголовки уже были отправлены клиенту: - -
      -
      -function errorHandler(err, req, res, next) {
      -  if (res.headersSent) {
      -    return next(err);
      -  }
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      diff --git a/ru/guide/migrating-4.md b/ru/guide/migrating-4.md deleted file mode 100755 index 78181e0182..0000000000 --- a/ru/guide/migrating-4.md +++ /dev/null @@ -1,601 +0,0 @@ ---- -layout: page -title: Миграция до версии Express 4 -menu: guide -lang: ru ---- - -# Переход к Express 4 - -

      Обзор

      - -Express 4, на самом деле, ломает существующий код Express 3. Это означает, что существующее приложение Express 3 не будет работать, если обновить версию Express в установленных зависимостях данного приложения. - -В этой статье содержится следующая информация: - - - -

      Изменения в Express 4

      - -В Express 4 реализованы следующие существенные изменения: - - - -См. также: - -* [Новые функции в 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Миграция из 3.x в 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) - -

      -Изменения ядра Express и системы промежуточных обработчиков -

      - -Express 4 больше не является зависимым от Connect, и из его ядра удалены все встроенные промежуточные обработчики, -за исключением функции `express.static`. Это означает, что теперь -Express представляет собой независимый веб-фреймворк маршрутизации и промежуточной обработки, и обновления промежуточных обработчиков никак не влияют на новые версии и выпуски Express. - -Без встроенных промежуточных обработчиков вам необходимо явным образом установить все средства промежуточной обработки, необходимые для запуска вашего приложения. Выполните следующие действия: - -1. Установите модуль: `npm install --save ` -2. В своем приложении затребуйте модуль: `require('module-name')` -3. Используйте модуль согласно документации к нему: `app.use( ... )` - -В таблице ниже приводится список соответствий между промежуточными обработчиками Express 3 и Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Express 3Express 4
      express.bodyParserbody-parser + -multer
      express.compresscompression
      express.cookieSessioncookie-session
      express.cookieParsercookie-parser
      express.loggermorgan
      express.sessionexpress-session
      express.faviconserve-favicon
      express.responseTimeresponse-time
      express.errorHandlererrorhandler
      express.methodOverridemethod-override
      express.timeoutconnect-timeout
      express.vhostvhost
      express.csrfcsurf
      express.directoryserve-index
      express.staticserve-static
      - -Это [полный список](https://github.com/senchalabs/connect#middleware) промежуточных обработчиков Express 4. - -В большинстве случаев можно просто заменить промежуточные обработчики старой, 3-й, версии на соответствующие обработчики Express 4. Дополнительную информацию можно найти в документации к модулю в GitHub. - -

      app.use принимает параметры

      - -В версии 4 можно использовать параметр переменной для определения пути загрузки функций промежуточной обработки, после чего считать значение параметра из обработчика маршрута. -Например: - -
      -
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -});
      -
      -
      -

      -Система маршрутизации -

      - -Теперь промежуточные обработчики маршрутизации загружаются в приложения неявным образом, поэтому вам не нужно обращать внимание на порядок загрузки промежуточных обработчиков `router`. - -Способ определения маршрутов остается неизменным, но в системе маршрутизации предусмотрено две новые функции, предназначенные для упорядочения маршрутов: - -{: .doclist } -* Новый метод `app.route()` - для создания обработчиков маршрутов, образующих цепочки, для пути маршрута. -* Новый класс `express.Router` - для создания модульных монтируемых обработчиков маршрутов. - -

      Метод app.route()

      - -Новый метод `app.route()` позволяет создавать обработчики маршрутов, образующие цепочки, для пути маршрута. Поскольку путь указан в одном расположении, удобно создавать модульные маршруты, чтобы минимизировать избыточность и количество опечаток. Дополнительная информация -о маршрутах приводится в документации по [`Router()`](/{{ page.lang }}/4x/api.html#router). - -Ниже приведен пример объединенных в цепочку обработчиков маршрутов, определенных с помощью функции `app.route()`. - -
      -
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      - -

      Класс express.Router

      - -Еще одной функцией, позволяющей упорядочить маршруты, является новый класс `express.Router`, с помощью которого можно создавать модульные монтируемые обработчики маршрутов. Экземпляр `Router` представляет собой комплексную систему промежуточных обработчиков и маршрутизации; по этой причине его часто называют "мини-приложением". - -В приведенном ниже примере создается маршрутизатор в виде модуля, в него загружается промежуточный обработчик, определяется несколько маршрутов, и модуль монтируется в путь в главном приложении. - -Например, создайте файл маршрутизатора с именем `birds.js` в каталоге приложения со следующим содержанием: - -
      -
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      -
      -module.exports = router;
      -
      -
      - -Потом загрузите модуль маршрутизации в приложение: - -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      - -Данное приложение теперь сможет обрабатывать запросы, адресованные ресурсам в путях `/birds` и -`/birds/about`, и вызывать специальный промежуточный обработчик `timeLog` данного маршрута. - -

      -Прочие изменения -

      - -В приведенной ниже таблице перечислены прочие, не слишком масштабные, но важные изменения, внесенные в версии Express 4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ОбъектОписание
      Node.jsExpress 4 требуется 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` - -Свойство приложения `json spaces` в Express 4 по умолчанию отключено. -
      -`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()`. -
      - -

      Пример миграции приложения

      - -Ниже приводится пример миграции приложения Express 3 в Express 4. -Рассмотрим файлы `app.js` и `package.json`. - -

      -Приложение версии 3 -

      - -

      app.js

      - -Рассмотрим приложение Express v.3, включающее в себя следующий файл `app.js`: - -
      -
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -// development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      -}
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      - -

      package.json

      - -Сопутствующий ему файл `package.json` версии 3, может выглядеть примерно так: - -
      -
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "express": "3.12.0",
      -    "pug": "*"
      -  }
      -}
      -
      -
      - -

      -Процесс -

      - -Процесс миграции начинается с установки обязательных промежуточных обработчиков для приложения Express 4 и обновления Express и Pug до соответствующих последних версий с помощью следующей команды: - -
      -
      -$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      -
      - -Внесите в файл `app.js` следующие изменения: - -1. Встроенные функции промежуточной обработки Express `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` и - `express.errorHandler` более не доступны в объекте - `express`. Необходимо вручную установить соответствующие им альтернативные объекты и загрузить их в приложение. - -2. Функцию `app.router` загружать не нужно. - Она не является действительным объектом приложения Express 4, поэтому удалите код - `app.use(app.router);`. - -3. Убедитесь в том, что функции промежуточной обработки загружаются в соответствующем порядке, - загрузите `errorHandler` после загрузки маршрутов приложения. - -

      Приложение версии 4

      - -

      package.json

      - -При запуске указанной выше команды `npm` будет выполнено обновление `package.json` следующим образом: - -
      -
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "body-parser": "^1.5.2",
      -    "errorhandler": "^1.1.1",
      -    "express": "^4.8.0",
      -    "express-session": "^1.7.2",
      -    "pug": "^2.0.0-beta6",
      -    "method-override": "^2.1.2",
      -    "morgan": "^1.2.2",
      -    "multer": "^0.1.3",
      -    "serve-favicon": "^2.0.1"
      -  }
      -}
      -
      -
      - -

      app.js

      - -Затем удалите недействительный код, загрузите обязательные промежуточные обработчики и внесите остальные необходимые изменения. Файл `app.js` будет иметь вид: - -
      -
      -var http = require('http');
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      -
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -// error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      -}
      -
      -var server = http.createServer(app);
      -server.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      - -
      -Если вам не нужно работать непосредственно с модулем `http` (socket.io/SPDY/HTTPS), загружать его не обязательно, а приложение можно просто запустить следующим образом: -
      -app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      - -

      Запустите приложение

      - -Процесс миграции завершен, и данное приложение теперь является приложением версии -Express 4. Для подтверждения запустите приложение с помощью следующей команды: - -
      -
      -$ node .
      -
      -
      - -Загрузите [http://localhost:3000](http://localhost:3000). Будет отображена домашняя страница в Express 4. - -

      Обновление до версии генератора приложений Express 4

      - -Инструмент командной строки для генерации приложений Express остается неизменным - - `express`, но для обновления его до новой версии необходимо удалить установку - генератора приложений Express 3, а затем установить новый `express-generator`. - -

      Установка

      - -Если в системе уже установлен генератор приложений Express 3, его необходимо удалить: - -
      -
      -$ npm uninstall -g express
      -
      -
      -В зависимости от настроек прав доступа к файлам и каталогам, эту команду, возможно, следует вызвать с помощью `sudo`. - -Теперь установите новый генератор: - -
      -
      -$ npm install -g express-generator
      -
      -
      - -В зависимости от настроек прав доступа к файлам и каталогам, эту команду, возможно, следует вызвать с помощью `sudo`. - -Итак, команда `express` в вашей системе обновлена до версии генератора -Express 4. - -

      Изменения генератора приложений

      - -Опции команд и их использование, в основном, остались без изменений, за исключением следующих: - -{: .doclist } -* Удалена опция `--sessions`. -* Удалена опция `--jshtml`. -* Добавлена опция `--hogan` для поддержки [Hogan.js](http://twitter.github.io/hogan.js/). - -

      Пример

      - -Выполните следующую команду для создания приложения Express 4: - -
      -
      -$ express app4
      -
      -
      - -Обратив внимание на содержимое файла `app4/app.js`, вы заметите, что все функции -промежуточной обработки (кроме `express.static`), обязательные для приложения, загружаются -как независимые модули, а промежуточный обработчик `router` больше не загружается в приложение явным образом. - -Также вы заметите, что файл `app.js` теперь является модулем Node.js, а не самостоятельным приложением, которое генерировалось старой версией генератора. - -После установки зависимостей запустите приложение с помощью следующей команды: - -
      -
      -$ npm start
      -
      -
      - -Обратив внимание на сценарий запуска npm в файле `package.json`, -вы заметите, что, фактически, командой, запускающей приложение, является -`node ./bin/www`, которой в Express 3 соответствовала команда `node app.js`. - -Поскольку файл `app.js`, созданный генератором Express 4, теперь является модулем -Node.js, его уже нельзя запускать отдельно как приложение (если не изменить код). Модуль необходимо загрузить в файл Node.js и запустить через файл Node.js. В данном случае, файлом Node.js является `./bin/www`. - -Ни каталог `bin`, ни файл `www` без расширения -не являются обязательными для создания приложения Express или запуска такого приложения. Это всего лишь -рекомендованные генератором значения, которые можно менять в соответствии с вашими потребностями. - -Для того чтобы избавиться от каталога `www` и оставить все, "как было в Express 3", -удалите строку `module.exports = app;` в конце файла -`app.js`, а вместо нее вставьте следующий код: - -
      -
      -app.set('port', process.env.PORT || 3000);
      -
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      -
      - -Убедитесь в том, что вы загрузили модуль `debug` в начало файла `app.js` с помощью следующего кода: - -
      -
      -var debug = require('debug')('app4');
      -
      -
      - -Далее, замените `"start": "node ./bin/www"` в файле `package.json` на `"start": "node app.js"`. - -Итак, функциональность `./bin/www` была перемещена обратно в -`app.js`. Такое изменение не является рекомендованным, но цель данного упражнения заключалась в том, чтобы помочь вам разобраться в принципах работы файла `./bin/www` и понять, почему файл `app.js` теперь нельзя запускать как самостоятельный. diff --git a/ru/guide/migrating-5.md b/ru/guide/migrating-5.md deleted file mode 100755 index ad3e401700..0000000000 --- a/ru/guide/migrating-5.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -layout: page -title: Миграция до версии Express 5 -menu: guide -lang: ru ---- - -# Переход к Express 5 - -

      Обзор

      - -Express 5.0 пока выпущен как альфа-версия, но ниже кратко описаны изменения, которые будут внесены в этом выпуске, а также способы миграции приложения Express 4 до версии Express 5. - -Express 5 не слишком отличается от Express 4: Изменения в API не столь значительны, как в версии 4.0 по сравнению с версией 3.0. Хотя базовый API остается прежним, изменения, ломающие существующий код, все же присутствуют; другими словами, существующая программа версии Express 4, возможно, не будет работать после обновления до версии Express 5. - -Для того чтобы установить новейший альфа-выпуск и предварительно ознакомиться с Express 5, введите в корневом каталоге приложения следующую команду: - -
      -
      -$ npm install express@5.0.0-alpha.2 --save
      -
      -
      - -Затем можно провести автоматическое тестирование, выявить сбои и устранить неполадки в соответствии с перечисленными ниже изменениями. После устранения сбоев, выявленных путем тестирования, запустите приложение и обратите внимание на возникшие ошибки. Если приложением используются методы или свойства, поддержка которых приостановлена, вы заметите это немедленно. - -

      Изменения в Express 5

      - -Ниже приводится список изменений (внесенных в альфа-выпуске 2), являющихся значимыми для пользователей Express. -Список всех функций, включение которых планируется, приведен в [запросе на включение](https://github.com/expressjs/express/pull/2237). - -**Удаленные методы и свойства** - - - -**Измененные:** - - - -**Усовершенствованные:** - - - -

      Удаленные методы и свойства

      - -Если указанные ниже методы и свойства используются в вашем приложении, оно даст сбой. Поэтому, после обновления до версии 5 вам потребуется внести изменения в существующее приложение. - -

      app.del()

      - -В Express 5 больше не поддерживается функция `app.del()`. В случае использования этой функции выдается сообщение об ошибке. Для регистрации маршрутов HTTP DELETE воспользуйтесь функцией `app.delete()`. - -Первоначально, вместо `delete` использовался код `del`, так как `delete` является зарезервированным ключевым словом в JavaScript. Тем не менее, начиная с версии ECMAScript 6, `delete` и другие зарезервированные ключевые слова разрешается использовать в качестве имен свойств. Здесь можно ознакомиться с рассуждениями, в результате которых было принято решение о признании функции `app.del` устаревшей. - -

      app.param(fn)

      - -Сигнатура `app.param(fn)` использовалась для изменения особенностей функции `app.param(name, fn)`. Она помечена как устаревшая, начиная с версии 4.11.0, а в Express 5 ее поддержка окончательно приостановлена. - -

      Названия методов во множественном числе

      - -Перечисленные ниже названия методов преобразованы в форму множественного числа. В Express 4 при использовании старых методов выдавалось предупреждение об устаревании. В Express 5 они уже не поддерживаются: - -`req.acceptsCharset()` заменен на `req.acceptsCharsets()`. - -`req.acceptsEncoding()` заменен на `req.acceptsEncodings()`. - -`req.acceptsLanguage()` заменен на `req.acceptsLanguages()`. - -

      Двоеточие (:) перед аргументом name в app.param(name, fn)

      - -Символ двоеточия (:) перед аргументом name в функции `app.param(name, fn)` - это пережиток Express 3, и в целях совместимости с предыдущими версиями он поддерживался в Express 4, снабженный пометкой об устаревании. В Express 5 это полностью игнорируется, и параметр name будет использоваться без предшествующего двоеточия. - -Это не повлияет на существующий код, при условии следования документации Express 4 в отношении параметра [app.param](/{{ page.lang }}/4x/api.html#app.param), поскольку там нет упоминания о двоеточии перед аргументом. - -

      req.param(name)

      - -Этот потенциально неоднозначный и опасный метод извлечения данных форм был удален. Теперь следует специально обращать внимание на имя конкретного переданного параметра в объекте `req.params`, `req.body` и `req.query`. - -

      res.json(obj, status)

      - -В Express 5 больше не поддерживается сигнатура `res.json(obj, status)`. Вместо этого необходимо задать аргумент status и объединить его в цепочку с методом `res.json()` следующим образом: `res.status(status).json(obj)`. - -

      res.jsonp(obj, status)

      - -В Express 5 больше не поддерживается сигнатура `res.jsonp(obj, status)`. Вместо этого необходимо задать аргумент status и объединить его в цепочку с методом `res.jsonp()` следующим образом: `res.status(status).jsonp(obj)`. - -

      res.send(body, status)

      - -В Express 5 больше не поддерживается сигнатура `res.send(obj, status)`. Вместо этого необходимо задать аргумент status и объединить его в цепочку с методом `res.send()` следующим образом: `res.status(status).send(obj)`. - -

      res.send(status)

      - -В Express 5 больше не поддерживается сигнатура res.send(status), где *`status`* является числом. Вместо этого используйте функцию `res.sendStatus(statusCode)`, которая задает код состояния заголовка ответа HTTP и отправляет текстовую версию кода: "Not Found" ("Не найдено"), "Internal Server Error" ("Внутренняя ошибка сервера") и т.д. -Если необходимо передать число с помощью функции `res.send()`, заключите его в кавычки, чтобы преобразовать в строку. Таким образом, Express не будет интерпретировать передачу числа как попытку использования неподдерживаемой устаревшей сигнатуры. - -

      res.sendfile()

      - -В Express 5 функция `res.sendfile()` заменена вариантом, в котором вторая часть составной фразы написана с заглавной буквы: `res.sendFile()`. - -

      Измененные:

      - -

      app.router

      - -Объект `app.router`, удаленный в Express 4, возвращен в Express 5. В новой версии данный объект представляет собой лишь ссылку на базовый маршрутизатор Express, в отличие от Express 3, где приложение должно было загружать его явным образом. - -

      req.host

      - -В Express 4 функция `req.host` некорректно отсекала номер порта, если таковой был указан. В Express 5 указание номера порта сохраняется. - -

      req.query

      - -В Express 4.7, Express 5 и в последующих версиях опция анализатора запросов может принимать значение `false`, чтобы отключить синтаксический анализ строки запроса, если в логике анализа строки запроса вам необходимо использовать собственную функцию. - -

      Усовершенствования

      - -

      res.render()

      - -Этот метод принудительно задает асинхронное представление для всех средств просмотра, что позволяет избежать ошибок, возникавших из-за средств просмотра с синхронной реализацией, не соответствующих рекомендованному интерфейсу. diff --git a/ru/guide/routing.md b/ru/guide/routing.md deleted file mode 100755 index 50d19e2d33..0000000000 --- a/ru/guide/routing.md +++ /dev/null @@ -1,333 +0,0 @@ ---- -layout: page -title: Маршрутизация в Express -menu: guide -lang: ru ---- - -# Маршрутизация - -*Маршрутизация* определяет, как приложение отвечает на клиентский запрос к конкретному адресу (URI). -Вводную информацию о маршрутизации можно найти в разделе [Основы маршрутизации](/{{ page.lang }}/starter/basic-routing.html). - -Приведенный ниже код служит примером одного из самых простых маршрутов. - -
      -
      -var express = require('express');
      -var app = express();
      -
      -// respond with "hello world" when a GET request is made to the homepage
      -app.get('/', function(req, res) {
      -  res.send('hello world');
      -});
      -
      -
      - -

      Методы Route

      - -Метод route является производным от одного из методов HTTP и присоединяется к экземпляру класса `express`. - -Приведенный ниже код служит примером маршрутов, определенных для методов запросов GET и POST к корневому каталогу приложения. - -
      -
      -// GET method route
      -app.get('/', function (req, res) {
      -  res.send('GET request to the homepage');
      -});
      -
      -// POST method route
      -app.post('/', function (req, res) {
      -  res.send('POST request to the homepage');
      -});
      -
      -
      - -Express поддерживает перечисленные далее методы маршрутизации, соответствующие методам HTTP: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search` и `connect`. - -
      -Для методов route, преобразуемых в недействительные имена переменных JavaScript, используйте нотацию в квадратных скобках. Например, -`app['m-search']('/', function ...` -
      - -Существует особый метод маршрутизации, `app.all()`, не являющийся производным от какого-либо метода HTTP. Этот метод используется для загрузки функций промежуточной обработки в пути для всех методов запросов. - -В приведенном ниже примере обработчик будет запущен для запросов, адресованных "/secret", независимо от того, используется ли GET, POST, PUT, DELETE или какой-либо другой метод запроса HTTP, поддерживаемый в [модуле http](https://nodejs.org/api/http.html#http_http_methods). - -
      -
      -app.all('/secret', function (req, res, next) {
      -  console.log('Accessing the secret section ...');
      -  next(); // pass control to the next handler
      -});
      -
      -
      - -

      Пути маршрутов

      - -Пути маршрутов, в сочетании с методом запроса, определяют конкретные адреса (конечные точки), в которых могут быть созданы запросы. Пути маршрутов могут представлять собой строки, шаблоны строк или регулярные выражения. - -
      - В Express для сопоставления путей маршрутов используется [path-to-regexp](https://www.npmjs.com/package/path-to-regexp); в документации к path-to-regexp описаны все возможные варианты определения путей маршрутов. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) - удобный инструмент для тестирования простых маршрутов в Express, хотя и не поддерживает сопоставление шаблонов. -
      - -
      -Строки запросов не являются частью пути маршрута. -
      - -Ниже приводятся примеры путей маршрутов на основе строк. - -Данный путь маршрута сопоставляет запросы с корневым маршрутом, `/`. - -
      -
      -app.get('/', function (req, res) {
      -  res.send('root');
      -});
      -
      -
      - -Данный путь маршрута сопоставляет запросы с `/about`. - -
      -
      -app.get('/about', function (req, res) {
      -  res.send('about');
      -});
      -
      -
      - -Данный путь маршрута сопоставляет запросы с `/random.text`. - -
      -
      -app.get('/random.text', function (req, res) {
      -  res.send('random.text');
      -});
      -
      -
      - -Ниже приводятся примеры путей маршрутов на основе шаблонов строк. - -Приведенный ниже путь маршрута сопоставляет `acd` и `abcd`. - -
      -
      -app.get('/ab?cd', function(req, res) {
      -  res.send('ab?cd');
      -});
      -
      -
      - -Этот путь маршрута сопоставляет `abcd`, `abbcd`, `abbbcd` и т.д. - -
      -
      -app.get('/ab+cd', function(req, res) {
      -  res.send('ab+cd');
      -});
      -
      -
      - -Этот путь маршрута сопоставляет `abcd`, `abxcd`, `abRABDOMcd`, `ab123cd` и т.д. - -
      -
      -app.get('/ab*cd', function(req, res) {
      -  res.send('ab*cd');
      -});
      -
      -
      - -Данный путь маршрута сопоставляет `/abe` и `/abcde`. - -
      -
      -app.get('/ab(cd)?e', function(req, res) {
      - res.send('ab(cd)?e');
      -});
      -
      -
      - -
      -Символы ?, +, * и () представляют собой подмножества соответствующих им регулярных выражений. Дефис (-) и точка (.) интерпретируются буквально в путях на основе строк. -
      - -Примеры путей маршрутов на основе регулярных выражений: - -Данный путь маршрута сопоставляет любой элемент с "a" в имени маршрута. - -
      -
      -app.get(/a/, function(req, res) {
      -  res.send('/a/');
      -});
      -
      -
      - -Данный маршрут сопоставляет `butterfly` и `dragonfly`, но не `butterflyman`, `dragonfly man` и т.д. - -
      -
      -app.get(/.*fly$/, function(req, res) {
      -  res.send('/.*fly$/');
      -});
      -
      -
      - -

      Обработчики маршрутов

      - -Для обработки запроса можно указать несколько функций обратного вызова, подобных [middleware](/{{ page.lang }}/guide/using-middleware.html). Единственным исключением является то, что эти обратные вызовы могут инициировать `next('route')` для обхода остальных обратных вызовов маршрута. С помощью этого механизма можно включить в маршрут предварительные условия, а затем передать управление последующим маршрутам, если продолжать работу с текущим маршрутом не нужно. - -Обработчики маршрутов могут принимать форму функции, массива функций или их сочетания, как показано в примерах ниже. - -Одна функция обратного вызова может обрабатывать один маршрут. Например: - -
      -
      -app.get('/example/a', function (req, res) {
      -  res.send('Hello from A!');
      -});
      -
      -
      - -Один маршрут может обрабатываться несколькими функциями обратного вызова (обязательно укажите объект `next`). Например: - -
      -
      -app.get('/example/b', function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from B!');
      -});
      -
      -
      - -Массив функций обратного вызова может обрабатывать один маршрут. Например: - -
      -
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      -}
      -
      -var cb2 = function (req, res) {
      -  res.send('Hello from C!');
      -}
      -
      -app.get('/example/c', [cb0, cb1, cb2]);
      -
      -
      - -Маршрут может обрабатываться сочетанием независимых функций и массивов функций. Например: - -
      -
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      -}
      -
      -app.get('/example/d', [cb0, cb1], function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from D!');
      -});
      -
      -
      - -

      Методы ответа

      - -Методы в объекте ответа (`res`), перечисленные в таблице ниже, могут передавать ответ клиенту и завершать цикл "запрос-ответ". Если ни один из этих методов не будет вызван из обработчика маршрута, клиентский запрос зависнет. - -| Метод | Описание -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Приглашение загрузки файла. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Завершение процесса ответа. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Отправка ответа JSON. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Отправка ответа JSON с поддержкой JSONP. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Перенаправление ответа. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Вывод шаблона представления. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Отправка ответа различных типов. -| [res.sendFile](/{{ page.lang }}/4x/api.html#res.sendFile) | Отправка файла в виде потока октетов. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Установка кода состояния ответа и отправка представления в виде строки в качестве тела ответа. - -

      app.route()

      - -Метод `app.route()` позволяет создавать обработчики маршрутов, образующие цепочки, для пути маршрута. -Поскольку путь указан в одном расположении, удобно создавать модульные маршруты, чтобы минимизировать избыточность и количество опечаток. Дополнительная информация о маршрутах приводится в документации [Router()](/{{ page.lang }}/4x/api.html#router). - -Ниже приведен пример объединенных в цепочку обработчиков маршрутов, определенных с помощью функции `app.route()`. - -
      -
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      - -

      express.Router

      - -С помощью класса `express.Router` можно создавать модульные, монтируемые обработчики маршрутов. Экземпляр `Router` представляет собой комплексную систему промежуточных обработчиков и маршрутизации; по этой причине его часто называют "мини-приложением". - -В приведенном ниже примере создается маршрутизатор в виде модуля, в него загружается функция промежуточной обработки, определяется несколько маршрутов, и модуль маршрутизатора монтируется в путь в основном приложении. - -Создайте файл маршрутизатора с именем `birds.js` в каталоге приложения со следующим содержанием: - -
      -
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware that is specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      -
      -module.exports = router;
      -
      -
      - -Потом загрузите модуль маршрутизации в приложение: - -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      - -Данное приложение теперь сможет обрабатывать запросы, адресованные ресурсам `/birds` и -`/birds/about`, а также вызывать специальную функцию промежуточной обработки `timeLog` данного маршрута. diff --git a/ru/guide/using-middleware.md b/ru/guide/using-middleware.md deleted file mode 100755 index 6d35303569..0000000000 --- a/ru/guide/using-middleware.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -layout: page -title: Использование промежуточных обработчиков Express -menu: guide -lang: ru ---- - -# Использование промежуточных обработчиков - -Express - это веб-фреймворк маршрутизации и промежуточной обработки с минимальной собственной функциональностью: приложение Express, по сути, представляет собой серию вызовов функций промежуточной обработки. - -Функции *промежуточной обработки* (middleware) - это функции, имеющие доступ к [объекту запроса](/{{ page.lang }}/4x/api.html#req) (`req`), [объекту ответа](/{{ page.lang }}/4x/api.html#res) (`res`) и к следующей функции промежуточной обработки в цикле "запрос-ответ" приложения. Следующая функция промежуточной обработки, как правило, обозначается переменной `next`. - -Функции промежуточной обработки могут выполнять следующие задачи: - -* Выполнение любого кода. -* Внесение изменений в объекты запросов и ответов. -* Завершение цикла "запрос-ответ". -* Вызов следующей функции промежуточной обработки из стека. - -Если текущая функция промежуточной обработки не завершает цикл "запрос-ответ", она должна вызвать `next()` для передачи управления следующей функции промежуточной обработки. В противном случае запрос зависнет. - -Приложение Express может использовать следующие типы промежуточных обработчиков: - - - [Промежуточный обработчик уровня приложения](#middleware.application) - - [Промежуточный обработчик уровня маршрутизатора](#middleware.router) - - [Промежуточный обработчик для обработки ошибок](#middleware.error-handling) - - [Встроенные промежуточные обработчики](#middleware.built-in) - - [Промежуточные обработчики сторонних поставщиков ПО](#middleware.third-party) - -Промежуточные обработчики уровня приложения и уровня маршрутизатора можно загружать с помощью необязательного пути для монтирования. -Также можно загрузить последовательность функций промежуточной обработки одновременно, в результате чего создается вспомогательный стек системы промежуточных обработчиков в точке монтирования. - -

      Промежуточный обработчик уровня приложения

      - -Свяжите промежуточный обработчик уровня приложения с экземпляром [объекта приложения](/{{ page.lang }}/4x/api.html#app), воспользовавшись функциями `app.use()` и `app.METHOD()`, где `METHOD` - метод HTTP запроса, обрабатываемый функцией промежуточной обработки (например, GET, PUT или POST) в нижнем регистре. - -В данном примере представлена функция промежуточной обработки без пути монтирования. Эта функция выполняется при каждом получении запроса приложением. - -
      -
      -var app = express();
      -
      -app.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -
      - -В данном примере представлена функция промежуточной обработки, монтируемая в путь `/user/:id`. Эта функция выполняется для всех типов запросов -HTTP в пути `/user/:id`. - -
      -
      -app.use('/user/:id', function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -
      - -В данном примере представлен маршрут и функция его обработки (система промежуточных обработчиков). Эта функция обрабатывает запросы GET, адресованные ресурсам в пути `/user/:id`. - -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  res.send('USER');
      -});
      -
      -
      - -Ниже приводится пример загрузки последовательности функций промежуточной обработки в точку монтирования, с указанием пути монтирования. -Этот пример иллюстрирует создание вспомогательного стека промежуточных обработчиков, с выводом информации о запросе для всех типов запросов HTTP, адресованных ресурсам в пути `/user/:id`. - -
      -
      -app.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -
      - -Обработчики маршрутов позволяют определить несколько маршрутов для одного пути. В приведенном ниже примере определено два маршрута для запросов GET, адресованных ресурсам в пути `/user/:id`. Второй маршрут не создает никаких неудобств, но его вызов никогда не будет выполнен, поскольку первый маршрут завершает цикл "запрос-ответ". - -В данном примере представлен вспомогательный стек промежуточных обработчиков для обработки запросов GET, адресованных ресурсам в пути `/user/:id`. - -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -}, function (req, res, next) {
      -  res.send('User Info');
      -});
      -
      -// handler for the /user/:id path, which prints the user ID
      -app.get('/user/:id', function (req, res, next) {
      -  res.end(req.params.id);
      -});
      -
      -
      - -Для того чтобы пропустить остальные функции дополнительной обработки в стеке промежуточных обработчиков маршрутизатора, вызовите `next('route')` для передачи управления следующему маршруту. -**ПРИМЕЧАНИЕ**: `next('route')` работает только в функциях промежуточной обработки, загруженных с помощью функций `app.METHOD()` или `router.METHOD()`. - -В данном примере представлен вспомогательный стек промежуточных обработчиков для обработки запросов GET, адресованных ресурсам в пути `/user/:id`. - -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  // if the user ID is 0, skip to the next route
      -  if (req.params.id == 0) next('route');
      -  // otherwise pass the control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for the /user/:id path, which renders a special page
      -app.get('/user/:id', function (req, res, next) {
      -  res.render('special');
      -});
      -
      -
      - -

      Промежуточный обработчик уровня маршрутизатора

      - -Промежуточный обработчик уровня маршрутизатора работает так же, как и промежуточный обработчик уровня приложения, но он привязан к экземпляру `express.Router()`. - -
      -
      -var router = express.Router();
      -
      -
      -Загрузите промежуточный обработчик уровня маршрутизатора с помощью функций `router.use()` и `router.METHOD()`. - -В приведенном ниже примере с помощью промежуточного обработчика уровня маршрутизатора создается копия системы промежуточных обработчиков, представленной выше для обработчиков уровня приложения: - -
      -
      -var app = express();
      -var router = express.Router();
      -
      -// a middleware function with no mount path. This code is executed for every request to the router
      -router.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
      -router.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -// a middleware sub-stack that handles GET requests to the /user/:id path
      -router.get('/user/:id', function (req, res, next) {
      -  // if the user ID is 0, skip to the next router
      -  if (req.params.id == 0) next('route');
      -  // otherwise pass control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for the /user/:id path, which renders a special page
      -router.get('/user/:id', function (req, res, next) {
      -  console.log(req.params.id);
      -  res.render('special');
      -});
      -
      -// mount the router on the app
      -app.use('/', router);
      -
      -
      - -

      Промежуточный обработчик для обработки ошибок

      - -
      -Промежуточный обработчик ошибок всегда содержит *четыре* аргумента. Для определения данной функции как обработчика ошибок необходимо указать четыре аргумента. Даже если вам не нужно использовать объект `next`, необходимо указать его, чтобы сохранить сигнатуру. В противном случае, объект `next` будет интерпретирован как обычный промежуточный обработчик, который не будет обрабатывать ошибки. -
      - -Определите функции промежуточного обработчика для обработки ошибок так же, как другие функции промежуточной обработки, но с указанием не трех, а четырех аргументов в сигнатуре `(err, req, res, next)`): - -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      - -Подробная информация о промежуточном обработчике ошибок приведена в разделе [Обработка ошибок](/{{ page.lang }}/guide/error-handling.html). - -

      Встроенные промежуточные обработчики

      - -Начиная с версии 4.x, Express не является зависимым от [Connect](https://github.com/senchalabs/connect). За исключением `express.static`, все функции промежуточной обработки, ранее включенные в Express, находятся в отдельных модулях. Ознакомьтесь со [списком функций промежуточной обработки](https://github.com/senchalabs/connect#middleware). - -

      express.static(root, [options])

      - -Единственной встроенной функцией промежуточной обработки в Express является `express.static`. Эта функция основана на [serve-static](https://github.com/expressjs/serve-static) и отвечает за предоставление статических ресурсов приложения Express. - -Аргумент `root` указывает на корневой каталог, из которого предоставляются статические ресурсы. - -Необязательный объект `options` может содержать следующие свойства: - -| Свойство | Описание | Тип | По умолчанию | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | Опция для предоставления файлов с точкой. Возможные значения - "allow", "deny", "ignore" | Строка | "ignore" | -| `etag` | Включение или отключение генерации etag | Булевский | `true` | -| `extensions` | Установка альтернативных вариантов расширений файлов. | Массив | `[]` | -| `index` | Отправка файла индекса каталога. Установите значение `false`, чтобы отключить индексацию каталога. | Смешанный | "index.html" | - `lastModified` | Установка в заголовке `Last-Modified` даты последнего изменения файла в ОС. Возможные значения: `true` или `false`. | Булевский | `true` | -| `maxAge` | Установка значения свойства max-age в заголовке Cache-Control, в миллисекундах, или в виде строки в [формате ms](https://www.npmjs.org/package/ms) | Число | 0 | -| `redirect` | Перенаправление к заключительному символу "/", если имя пути - это каталог. | Булевский | `true` | -| `setHeaders` | Функция для установки заголовков HTTP, предоставляемых с файлом. | Функция | | - -Ниже приводится пример использования функции промежуточной обработки `express.static` с объектом дополнительных опций: - -
      -
      -var options = {
      -  dotfiles: 'ignore',
      -  etag: false,
      -  extensions: ['htm', 'html'],
      -  index: false,
      -  maxAge: '1d',
      -  redirect: false,
      -  setHeaders: function (res, path, stat) {
      -    res.set('x-timestamp', Date.now());
      -  }
      -}
      -
      -app.use(express.static('public', options));
      -
      -
      - -Для каждого приложения допускается наличие нескольких статических каталогов: - -
      -
      -app.use(express.static('public'));
      -app.use(express.static('uploads'));
      -app.use(express.static('files'));
      -
      -
      - -Дополнительную информацию о функции `serve-static` и ее опциях можно найти в документации по [serve-static](https://github.com/expressjs/serve-static). - -

      Промежуточные обработчики сторонних поставщиков ПО

      - -Для расширения функциональности приложений Express используются промежуточные обработчики сторонних поставщиков ПО. - -Установите модуль Node.js для соответствующей функциональной возможности, затем загрузите его в приложение на уровне приложения или на уровне маршрутизатора. - -В приведенном ниже примере показана установка и загрузка функции промежуточной обработки для синтаксического анализа cookie `cookie-parser`. - -
      -
      -$ npm install cookie-parser
      -
      -
      - -
      -
      -var express = require('express');
      -var app = express();
      -var cookieParser = require('cookie-parser');
      -
      -// load the cookie-parsing middleware
      -app.use(cookieParser());
      -
      -
      - -Список функций промежуточных обработчиков, предоставляемых сторонними поставщиками ПО и часто используемых в Express, приведен в разделе [Промежуточные обработчики сторонних поставщиков ПО](../resources/middleware.html). diff --git a/ru/guide/using-template-engines.md b/ru/guide/using-template-engines.md deleted file mode 100755 index aebfeb22bb..0000000000 --- a/ru/guide/using-template-engines.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -layout: page -title: Использование шаблонизаторов в Express -menu: guide -lang: ru ---- - -# Использование шаблонизаторов в Express - -Для того чтобы отображать в Express файлы шаблонов, необходимо задать следующие параметры приложения: - -* `views`, каталог, в котором находятся файлы шаблонов. Например: `app.set('views', './views')` -* `view engine`, используемый шаблонизатор. Например: `app.set('view engine', 'pug')` - -Затем установите соответствующий пакет npm шаблонизатора: - -
      -
      -$ npm install pug --save
      -
      -
      - -
      -Шаблонизаторы, совместимые с Express, например, Pug, экспортируют функцию `__express(filePath, options, callback)`, вызываемую с помощью функции `res.render()` для вывода кода шаблона. - -Это правило действует не для всех шаблонизаторов. Библиотека [Consolidate.js](https://www.npmjs.org/package/consolidate) соблюдает его путем преобразования всех популярных шаблонизаторов Node.js, благодаря чему работает в Express без проблем. -
      - -После указания механизма визуализации (view engine) не нужно указывать его или загружать модуль шаблонизатора в приложение; Express загружает модуль внутренними средствами, как показано далее (для примера, приведенного выше). - -
      -
      -app.set('view engine', 'pug');
      -
      -
      - -Создайте файл шаблона Pug с именем `index.pug` в каталоге `views` со следующим содержанием: - -
      -
      -html
      -  head
      -    title= title
      -  body
      -    h1= message
      -
      -
      - -Затем создайте маршрут для вывода файла `index.pug`. Если свойство `view engine` не задано, необходимо указать расширение файла `view`. В противном случае, можно не указывать расширение. - -
      -
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -
      - -При выполнении запроса к домашней странице файл `index.pug` будет отображаться как HTML. - -Для получения дополнительной информации о работе шаблонизаторов в Express обратитесь к разделу ["Разработка шаблонизаторов для Express"](/{{ page.lang }}/advanced/developing-template-engines.html). diff --git a/ru/guide/writing-middleware.md b/ru/guide/writing-middleware.md deleted file mode 100755 index 2b8a89986c..0000000000 --- a/ru/guide/writing-middleware.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -layout: page -title: Написание кода промежуточных обработчиков для использования в приложениях Express -menu: guide -lang: ru ---- - -# Написание кода промежуточных обработчиков для использования в приложениях Express - -

      Обзор

      - -Функции *промежуточной обработки* (middleware) - это функции, имеющие доступ к [объекту запроса](/{{ page.lang }}/4x/api.html#req) (`req`), [объекту ответа](/{{ page.lang }}/4x/api.html#res) (`res`) и к следующей функции промежуточной обработки в цикле "запрос-ответ" приложения. Следующая функция промежуточной обработки, как правило, обозначается переменной `next`. - -Функции промежуточной обработки могут выполнять следующие задачи: - -* Выполнение любого кода. -* Внесение изменений в объекты запросов и ответов. -* Завершение цикла "запрос-ответ". -* Вызов следующего промежуточного обработчика из стека. - -Если текущая функция промежуточной обработки не завершает цикл "запрос-ответ", она должна вызвать `next()` для передачи управления следующей функции промежуточной обработки. В противном случае запрос зависнет. - -Ниже представлены элементы вызова функции промежуточного обработчика: - - - - -
      - - -
      Метод HTTP, к которому применяется данный промежуточный обработчик.
      - -
      Путь (маршрут), к которому применяется данный промежуточный обработчик.
      - -
      Функция промежуточного обработчика.
      - -
      Аргумент обратного вызова для функции промежуточного обработчика, именуемый "next" согласно стандарту.
      - -
      Аргумент ответа HTTP, именуемый "res" согласно стандарту.
      - -
      Аргумент запроса HTTP, именуемый "req" согласно стандарту.
      -
      - -Далее приводится пример простого приложения Ниже Express "Hello World", для которого будут определены две функции промежуточных обработчиков: - -
      -
      -var express = require('express');
      -var app = express();
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -app.listen(3000);
      -
      -
      - -

      Разработка

      - -Ниже приводится простой пример промежуточного обработчика "myLogger". Эта функция печатает слово "LOGGED" при прохождении запроса, адресованного приложению, через приложение. Данная функция промежуточного обработчика присвоена переменной с именем `myLogger`. - -
      -
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      -
      -
      - -
      -Обратите внимание на вызов `next()` выше. Вызов этой функции активирует следующую функцию промежуточной обработки в приложении. -Функция `next()` не является частью Node.js или Express API, но представляет собой третий аргумент, передаваемый в функцию промежуточного обработчика. Функция `next()` могла бы иметь любое имя, но, согласно стандарту, она всегда называется "next". Во избежание путаницы, рекомендуется всегда придерживаться данного стандарта. -
      - -Для того чтобы загрузить функцию промежуточного обработчика вызовите `app.use()` с указанием соответствующей функции. -Например, приведенный ниже код загружает функцию промежуточного обработчика `myLogger` перед маршрутом к корневому расположению (/). - -
      -
      -var express = require('express');
      -var app = express();
      -
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      -
      -app.use(myLogger);
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -app.listen(3000);
      -
      -
      - -Каждый раз при получении запроса приложение выводит на терминал сообщение "LOGGED". - -Порядок загрузки промежуточных обработчиков очень важен: функции промежуточных обработчиков, загруженные первыми, выполняются в первую очередь. - -Если `myLogger` загружается после маршрута к корневому расположению, запрос никогда не достигает его, и приложением не выводится сообщение "LOGGED", поскольку обработчик маршрута корневого пути завершает цикл "запрос-ответ". - -Промежуточный обработчик `myLogger` всего лишь выводит сообщение, затем передает запрос далее, следующему промежуточному обработчику в стеке, путем вызова функции `next()`. - -В следующем примере выполняется добавление свойства `requestTime` в объект запроса. Назовем эту функцию промежуточного обработчика "requestTime". - -
      -
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      -
      -
      - -Теперь приложением используется функция промежуточного обработчика `requestTime`. Кроме того, функция обратного вызова маршрута корневого расположения (пути) использует свойство, добавленную функций промежуточного обработчика в `req` (объект запроса). - -
      -
      -var express = require('express');
      -var app = express();
      -
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      -
      -app.use(requestTime);
      -
      -app.get('/', function (req, res) {
      -  var responseText = 'Hello World!
      '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); - -app.listen(3000); -
      -
      - -Если запрос адресован корневому каталогу приложения, приложение выводит на экран системное время запроса в браузере. - -Благодаря наличию доступа к объекту запроса, объекту ответа, следующей функции промежуточного обработчика в стеке и к API Node.js в целом, возможности, связанные с промежуточными обработчиками, являются бесконечными. - -Дополнительная информация о промежуточных обработчиках Express содержится в разделе [Использование промежуточных обработчиков Express](/{{ page.lang }}/guide/using-middleware.html). diff --git a/ru/index.md b/ru/index.md deleted file mode 100644 index b1da3048ff..0000000000 --- a/ru/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -layout: home -title: Express - фреймворк веб-приложений Node.js -menu: home -lang: ru ---- -
      - {% include header/header-{{ page.lang }}.html %} -
      -
      -
      - - Быстрый, гибкий, минималистичный веб-фреймворк для приложений Node.js -
      -
      $ npm install express --save
      -
      -
      - -
      -
      - - - -
      - -
      -
      -

      Веб-приложения

      Express - это минималистичный и гибкий веб-фреймворк для приложений Node.js, предоставляющий обширный набор функций для мобильных и веб-приложений. -
      - -
      -

      API

      Имея в своем распоряжении множество служебных методов HTTP и промежуточных обработчиков, создать надежный API можно быстро и легко. -
      - -
      -

      Производительность

      Express предоставляет тонкий слой фундаментальных функций веб-приложений, которые не мешают вам работать с давно знакомыми и любимыми вами функциями Node.js. -
      - - -
      - -
      - - diff --git a/ru/resources/applications.md b/ru/resources/applications.md deleted file mode 100755 index 0ea0db3d4b..0000000000 --- a/ru/resources/applications.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -layout: page -title: Express applications -menu: resources -lang: ru ---- - -# Applications - -##MySpace - -No introduction required! Everyone knows MySpace, -and the upcoming https://new.myspace.com is powered by Express. - -[![](/images/apps/screenshots/myspace.png)](https://new.myspace.com/) - -Visit [MySpace](https://new.myspace.com/) - -##LearnBoost - -LearnBoost provides a free, easy to use online -education suite including gradebook, -lesson plans, attendance, reporting, and calendars -among other tools. - -[![](/images/apps/screenshots/learnboost.png)](https://www.learnboost.com/) - -Visit [LearnBoost](https://www.learnboost.com/) - -##Storify - -Create stories using social media. Turn what people post -on social media into compelling stories. Collect the best photos, video, -tweets and more to publish. - -[![](/images/apps/screenshots/storify.png)](http://storify.com/) - -Visit [Storify](http://storify.com/) - -##Geekli.st - -A place for geeks to share what they've done, who they did it with and -connect with great companies and communities. - -[![](/images/apps/screenshots/geeklist.png)](http://geekli.st) - -Visit [Geekli.st](http://geekli.st) - -##Klout - -Klout is the Standard for Influence. Join Klout to discover your -influence and compare with others you may know. - -[![](/images/apps/screenshots/klout.png)](http://klout.com) - -Visit [Klout](http://klout.com) - -##Prismatic - -Prismatic learns from how you interact on social networks so that we -can show you the most interesting content and conversation from your friends. - -[![](/images/apps/screenshots/prismatic.png)](http://getprismatic.com/) - -Visit [Prismatic](http://getprismatic.com/) - -##StudyNotes - -At StudyNotes, we are building beautiful and simple -learning tools to empower students to accelerate their -learning – i.e. to learn more effectively, in a shorter -time, and with better long-term recall. - -[![](/images/apps/screenshots/studynotes.png)](http://www.apstudynotes.org/) - -Visit [StudyNotes](http://www.apstudynotes.org/) - -##Persona - -Persona, or "BrowserID" is Mozilla's answer -to a better identification system for your browser, -this promising tool is definitely worth checking out. - -[![](/images/apps/screenshots/browserid.png)](https://login.persona.org/) - -Visit [Persona](https://login.persona.org/) - -##Countly - -Extensive real-time mobile analytics as a service. - -[![](/images/apps/screenshots/countly.png)](https://count.ly/) - -Visit [Countly](https://count.ly/) - -## Segment.io - -No more littering your app with tons of different analytics providers. -Instead, instrument your app once cleanly and then send your data to any analytics service you want. - -[![](/images/apps/screenshots/segment.png)](http://segment.io/) - -Visit [Segment.io](http://segment.io/) - -##Yummly - -Yummly is the world's largest and most powerful recipe search site. -Bringing together recipes from all over the web - making your life easier. - -[![](/images/apps/screenshots/yummly.png)](http://yummly.com/) - -Visit [Yummly](http://yummly.com/) - -##Koding - -Real-time software development in the browser with integrated -editor, collaboration, terminals and more. - -[![](/images/apps/screenshots/koding.png)](http://koding.com/) - -Visit [Koding](http://koding.com/) - -##Apiary.io - -REST API documentation reimagined. - -[![](/images/apps/screenshots/apiary.png)](http://apiary.io/) - -Visit [Apiary](http://apiary.io/) - -##Cozy - -Cozy is the personal cloud that allows you to put your web apps and your -data on your hardware: calendars, contacts, feeds, notes. With Cozy, you can build and use your own Express app and use the data stored by the other applications. - -[![](/images/apps/screenshots/cozy.png)](http://cozy.io/) - -Visit [Cozy](http://cozy.io/) - -##FlyLatex - -Real-time Collaborative environment for LaTex. - -[![](/images/apps/screenshots/flylatex.png)](http://github.com/alabid/flylatex) - -Visit [FlyLatex](http://github.com/alabid/flylatex) - -##SimpleSet - -Advanced exercise prescription software for physical therapists and other health professionals. - -[![](/images/apps/screenshots/simpleset.png)](http://www.simpleset.net) - -Visit [SimpleSet](http://www.simpleset.net) - -##Ghost - -Just a blogging platform. - -[![](/images/apps/screenshots/ghost.png)](https://ghost.org) - -Visit [Ghost](https://ghost.org) - -##LogHuman - -LogHuman is an application insights platform which enables developers to record information such as billing events, feature usage, or system hiccups, as well as flexible metadata to give these events context. - -[![](/images/apps/screenshots/loghuman.png)](https://loghuman.com) - -Visit [LogHuman](https://loghuman.com) - -##VogueVerve - -VogueVerve is a minimalist fashion social platform. Follow, like and buy. - -[![](/images/apps/screenshots/vogueverve.png)](http://vogueverve.com) - -Visit [VogueVerve](http://vogueverve.com) - -##Glip - -Real-time team collaboration with integrated task management, video conferencing, shared calendars and more. - -[![](/images/apps/screenshots/glip.png)](https://glip.com) - -Visit [Glip](https://glip.com) - -##Gugamarket - -Gugamarket is a fullstack REST API framework licensed under GPLv3. It supports giaya.com social login. -Gugamarket is listed as one of the top Node/Express REST API's at http://nodeframework.com/. - -[![](/images/apps/screenshots/gugamarket.png)](http://www.gugamarket.com) - -Visit [Gugamarket](http://www.gugamarket.com) - -##Add your app or site - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/applications.md), -add a link to your app, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/ru/resources/community.md b/ru/resources/community.md deleted file mode 100755 index 2acc7a463b..0000000000 --- a/ru/resources/community.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -layout: page -title: Сообщество Express -menu: resources -lang: ru ---- - -# Сообщество - -## Список рассылки - -Присоединяйтесь к 2000 пользователей Express или ознакомьтесь с более чем 5000 -обсуждений в [Группе Google](https://groups.google.com/group/express-js). - -## Gitter - -[Раздел чата по expressjs/express](https://gitter.im/expressjs/express) идеален для разработчиков, активно интересующихся ежедневными обсуждениями тем, касающихся Express. - -## Канал IRC - -Сотни разработчиков ежедневно общаются на канале #express в сети freenode. -Если у вас возникнут вопросы по данному фреймворку, присоединяйтесь - и вы быстро получите ответы на них. - -## Примеры - -Просмотр десятков [примеров](https://github.com/expressjs/express/tree/master/examples) приложений Express в хранилище, охватывающем разнообразные направления - от проектирования API и аутентификации до интеграции шаблонизаторов. - -## Размещение заявок - -Если вы обнаружили возможную ошибку или хотите запросить необходимую функцию, создайте зарегистрированный электронный запрос в [очереди заявок](https://github.com/expressjs/express/issues). - -## Сторонние участники - -Энергичными участниками нашего сообщества создано множество разнообразных расширений, [модулей промежуточной обработки](/{{ page.lang }}/resources/middleware.html) и фреймворков высшего уровня. Ознакомиться с ними можно в [вики](https://github.com/expressjs/express/wiki). - diff --git a/ru/resources/glossary.md b/ru/resources/glossary.md deleted file mode 100755 index a19b3eb229..0000000000 --- a/ru/resources/glossary.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -layout: page -title: Глоссарий по Express -menu: resources -lang: ru ---- - -# Глоссарий - -### application (приложение) - -В общем смысле, одна или несколько программ, предназначенных для выполнения операций с определенной целью. В контексте Express - программа, использующая API Express, запущенный на платформе Node.js. Также называется [объектом приложения](/{{ page.lang }}/api.html#express). - -### API - -Интерфейс программирования приложений. Рекомендуется расшифровывать данную аббревиатуру при первом упоминании. - -### Express - -Быстрый, гибкий, минималистичный веб-фреймворк для приложений Node.js. В целом, название "Express" является более предпочтительным, чем"Express.js", хотя последнее тоже допускается. - -### libuv - -Библиотека мультиплатформной поддержки, ориентированная на асинхронный ввод/вывод, в основном разработанный для использования Node.js. - -### middleware (промежуточные обработчики) - -Функция, вызываемая уровнем маршрутизации Express перед обработчиком финального запроса, то есть, находящаяся между необработанным запросом и окончательным заданным маршрутом. Вот некоторые выдержки из терминологии, связанной с промежуточными обработчиками: - - * `var foo = require('middleware')` называется *затребованием* или *использованием* модуля Node.js. Затем оператор `var mw = foo()`, как правило, возвращает промежуточный обработчик. - * `app.use(mw)` называется *добавлением промежуточного обработчика в глобальный стек обработки*. - * `app.get('/foo', mw, function (req, res) { ... })` называется *добавлением промежуточного обработчика в стек обработки "GET /foo"*. - -### Node.js - -Платформа программного обеспечения, используемая для разработки масштабируемых сетевых приложений. Node.js использует JavaScript в качестве языка создания сценариев и обеспечивает высокую пропускную способность благодаря неблокирующему вводу/выводу и однопотоковому циклу событий. См. [nodejs.org](http://nodejs.org/). **Особенность употребления термина**: При первом упоминании - "Node.js", в дальнейшем - "Node". - -### open-source, open source (открытый исходный код, с открытым исходным кодом) - -В английском языке прилагательное open-source пишется через дефис; например: "This is open-source software" ("Это программное обеспечение с открытым исходным кодом"). См. статью [Открытое программное обеспечение](http://en.wikipedia.org/wiki/Open-source_software) в Википедии. Примечание: Хотя широко распространено употребление данного термина без дефиса, мы следуем стандартным правилам английского языка, согласно которым составные прилагательные пишутся через дефис. - -### request (запрос) - -Запрос HTTP. Клиент передает на сервер сообщение-запрос по протоколу HTTP, а сервер возвращает ответ. В запросе должен использоваться один из нескольких [методов запроса](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods), например, GET, POST и т.д. - -### response (ответ) - -Ответ HTTP. Сервер возвращает клиенту сообщение-ответ по протоколу HTTP. Ответ содержит информацию о состоянии выполнения запроса, а также в теле сообщения может быть включено запрашиваемое содержимое. - -### route (маршрут) - -Часть URL, идентифицирующая ресурс. Например, в `http://foo.com/products/id`, "/products/id" является маршрутом. - -### router (маршрутизатор) - -См. раздел [маршрутизатор](/{{ page.lang }}/4x/api.html#router) в справочнике API. diff --git a/ru/resources/learning.md b/ru/resources/learning.md deleted file mode 100755 index 492c55546f..0000000000 --- a/ru/resources/learning.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: Дополнительное обучение -menu: resources -lang: ru ---- - -# Дополнительное обучение - -
      Disclaimer: Unendorsed community content.
      - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/ru/resources/middleware.md b/ru/resources/middleware.md deleted file mode 100755 index 50e8eed62b..0000000000 --- a/ru/resources/middleware.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -layout: page -title: Промежуточные обработчики в Express -menu: resources -lang: ru ---- - -# Промежуточные обработчики сторонних поставщиков ПО - -Ниже представлен список некоторых модулей Express: - - - [body-parser](https://github.com/expressjs/body-parser): ранее `express.bodyParser`, `json` и `urlencoded`. - См. также: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): ранее `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): Модули промежуточных обработчиков Connect/Express для оптимального предоставления файлов изображений. Преобразует изображения в `.webp` или `.jxr`, если это возможно. - - [connect-timeout](https://github.com/expressjs/timeout): ранее `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): ранее `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): ранее `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): ранее `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): ранее `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): простой инструмент разработки, предназначенный для добавления вкладки с информацией о переменных шаблона (локалях), текущем сеансе, полезных данных запроса и т.д. для приложения. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): Модуль промежуточного обработчика Express для отфильтровывания частей ответов JSON на основе строки запроса `fields`; используется Частичный ответ API Google. - - [express-session](https://github.com/expressjs/session): ранее `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): Модуль промежуточного обработчика Express для использования CDN для статических ресурсов, с поддержкой нескольких хостов (например: cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): Модуль промежуточного обработчика Express для тех пользователей, которые строго следят за символами наклонной косой черты в конце строки. - - [express-stormpath](https://github.com/stormpath/stormpath-express): Модуль промежуточного обработчика Express для хранения имен пользователей, аутентификации, авторизации, SSO и защиты данных. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): Модуль промежуточного обработчика для перенаправления запросов HTTP, содержащих символы в верхнем регистре, в традиционный формат нижнего регистра. - - [helmet](https://github.com/helmetjs/helmet): Модуль для обеспечения защиты приложений путем настройки различных заголовков HTTP. - - [join-io](https://github.com/coderaiser/join-io "join-io"): Модуль для оперативного объединения файлов с целью сокращения числа запросов. - - [method-override](https://github.com/expressjs/method-override): ранее `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): ранее `logger` - - [passport](https://github.com/jaredhanson/passport): Модуль промежуточного обработчика Express для аутентификации. - - [response-time](https://github.com/expressjs/response-time): ранее `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): ранее `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): ранее `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): Модуль для предоставления статического содержимого. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): URL с идентификационными метками или заголовки кеширования для статических ресурсов, включая поддержку одного или нескольких внешних доменов. - - [vhost](https://github.com/expressjs/vhost): ранее `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): Модуль промежуточного обработчика Express, предоставляющий общие вспомогательные методы для представлений. - - [sriracha-admin](https://github.com/hdngr/siracha): Модуль промежуточного обработчика Express, в динамическом режиме генерирующий административный сайт для Mongoose. - -Некоторые модули промежуточных обработчиков, ранее входившие в состав Connect, больше не поддерживаются командой разработчиков Connect/Express. Эти модули заменяются альтернативными, либо вместо них предоставляются усовершенствованные модули. Воспользуйтесь одним из перечисленных ниже альтернативных вариантов: - - - express.cookieParser - - [cookies](https://github.com/jed/cookies) и [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) - -Другие модули промежуточных обработчиков описаны в разделах: - - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) diff --git a/ru/starter/basic-routing.md b/ru/starter/basic-routing.md deleted file mode 100755 index 412e220456..0000000000 --- a/ru/starter/basic-routing.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -layout: page -title: Основы маршрутизации в Express -menu: starter -lang: ru ---- - -# Основы маршрутизации - -*Маршрутизация* определяет, как приложение отвечает на клиентский запрос к конкретному адресу (конечной точке), которым является URI (или путь), и определенному методу запроса HTTP (GET, POST и т.д.). - -Каждый маршрут может иметь одну или несколько функций обработки, которые выполняются при сопоставлении маршрута. - -Определение маршрута имеет следующую структуру: -
      -
      -app.METHOD(PATH, HANDLER)
      -
      -
      - -Где: - -- `app` - это экземпляр `express`. -- `METHOD` - [метод запроса HTTP](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol). -- `PATH` - путь на сервере. -- `HANDLER` - функция, выполняемая при сопоставлении маршрута. - -
      -В этом учебнике мы исходим из предположения о том, что экземпляр `express` с именем `app` уже создан, и сервер работает. Если вы не знакомы со способами создания и запуска приложения, обратитесь к разделу [Пример "Hello world"](/{{ page.lang }}/starter/hello-world.html). -
      - -Приведенные ниже элементарные примеры иллюстрируют способ определения простых маршрутов. - -Ответ `Hello World!` на домашней странице: - -
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -
      - -Ответ на запрос POST в корневом маршруте (`/`), на домашней странице приложения: - -
      -
      -app.post('/', function (req, res) {
      -  res.send('Got a POST request');
      -});
      -
      -
      - -Ответ на запрос PUT, адресованный маршруту `/user`: - -
      -
      -app.put('/user', function (req, res) {
      -  res.send('Got a PUT request at /user');
      -});
      -
      -
      - -Ответ на запрос DELETE, адресованный маршруту `/user`: - -
      -
      -app.delete('/user', function (req, res) {
      -  res.send('Got a DELETE request at /user');
      -});
      -
      -
      - -Дополнительная информация о маршрутизации приведена в [руководстве по маршрутизации](/{{ page.lang }}/guide/routing.html). diff --git a/ru/starter/faq.md b/ru/starter/faq.md deleted file mode 100755 index e60572725b..0000000000 --- a/ru/starter/faq.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -layout: page -title: Часто задаваемые вопросы (FAQ) по Express -menu: starter -lang: ru ---- - -# Часто задаваемые вопросы (FAQ) - -## Какую структуру мне следует использовать для своего приложения? - -Нет единого ответа на данный вопрос. Все зависит от размеров приложения и участвующей в разработке команды. В целях обеспечения максимальной гибкости, в Express не предусмотрены какие бы то ни было предпосылки в отношении структуры. - -Маршруты и другая логика приложений могут размещаться в любом количестве файлов, на ваше усмотрение, и в любой структуре каталогов, которую вы предпочтете. В качестве источника вдохновения, ознакомьтесь со следующими примерами: - -* [Объявления маршрутов](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Карта маршрутов](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [Контроллеры в MVC стиле](https://github.com/expressjs/express/tree/master/examples/mvc) - -Также существуют сторонние расширения для Express, упрощающие некоторые из этих шаблонов: - -* [Ресурсная маршрутизация](https://github.com/expressjs/express-resource) - -## Как определить модели? - -В Express нет средств для работы с базой данных. Их предоставляют исключительно -сторонние модули Node, что позволяет вам взаимодействовать практически с любой базой данных. - -Фреймворк на базе Express, ориентированный на работу с моделями, описан в разделе [LoopBack](http://loopback.io). - -## Как идентифицировать пользователей? - -Аутентификация - это еще одна своеобразная область, которую Express не охватывает. Можно использовать любую схему аутентификации, по вашему желанию. -Простая схема "имя пользователя / пароль" представлена в [следующем примере](https://github.com/expressjs/express/tree/master/examples/auth). - - -## Какие шаблонизаторы поддерживает Express? - -Express поддерживает все шаблонизаторы, согласующиеся с сигнатурой `(path, locals, callback)`. -Дополнительную информацию о нормализации интерфейсов шаблонизации и кеширования можно найти в проекте -[consolidate.js](https://github.com/visionmedia/consolidate.js). Не представленные в списке шаблонизаторы также могут поддерживать сигнатуру Express. - -## Как обрабатывать ошибки 404? - -В Express код 404 не является результатом ошибки. Обработчик ошибок -не фиксирует их, потому что код ответа 404 указывает лишь на факт отсутствия дополнительной работы. Другими словами, Express выполнил все функции промежуточной обработки и маршруты и обнаружил, что ни один из них не отвечает. Все, что вам нужно сделать, - добавить промежуточный обработчик в конец стека (после всех остальных функций) для обработки кода 404: - -
      -
      -app.use(function(req, res, next) {
      -  res.status(404).send('Sorry cant find that!');
      -});
      -
      -
      - -## Как определяется обработчик ошибок? - -Функции промежуточного обработчика для обработки ошибок определяются так же, как и другие промежуточные обработчики, но с указанием не трех, а четырех аргументов в сигнатуре `(err, req, res, next)`). - -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      - -Дополнительная информация содержится в разделе [Обработка ошибок](/{{ page.lang }}/guide/error-handling.html). - -## Как отобразить простой HTML-файл? - -Вам не нужно этого делать! Нет необходимости отображать HTML с помощью функции `res.render()`. -Если у вас есть отдельный файл, воспользуйтесь функцией `res.sendFile()`. -В случае предоставления нескольких ресурсов из каталога воспользуйтесь промежуточным обработчиком `express.static()`. diff --git a/ru/starter/generator.md b/ru/starter/generator.md deleted file mode 100755 index 5882b152d4..0000000000 --- a/ru/starter/generator.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -layout: page -title: Генератор приложений Express -menu: starter -lang: ru ---- - -# Генератор приложений Express - -Для быстрого создания "скелета" приложения используется инструмент для генерации приложений `express`. - -Установите `express` с помощью следующей команды: - -
      -
      -$ npm install express-generator -g
      -
      -
      - -Для просмотра опций команды воспользуйтесь опцией `-h`: - -
      -
      -$ express -h
      -
      -  Usage: express [options][dir]
      -
      -  Options:
      -
      -    -h, --help          output usage information
      -        --version       output the version number
      -    -e, --ejs           add ejs engine support
      -        --hbs           add handlebars engine support
      -        --pug           add pug engine support
      -    -H, --hogan         add hogan.js engine support
      -        --no-view       generate without view engine
      -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
      -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
      -        --git           add .gitignore
      -    -f, --force         force on non-empty directory
      -
      -
      - -Например, следующая команда создает приложение Express с именем _myapp_ в текущем рабочем каталоге: - -
      -
      -$ express --view=pug myapp
      -
      -   create : myapp
      -   create : myapp/package.json
      -   create : myapp/app.js
      -   create : myapp/public
      -   create : myapp/public/javascripts
      -   create : myapp/public/images
      -   create : myapp/routes
      -   create : myapp/routes/index.js
      -   create : myapp/routes/users.js
      -   create : myapp/public/stylesheets
      -   create : myapp/public/stylesheets/style.css
      -   create : myapp/views
      -   create : myapp/views/index.pug
      -   create : myapp/views/layout.pug
      -   create : myapp/views/error.pug
      -   create : myapp/bin
      -   create : myapp/bin/www
      -
      -
      - -Затем установите зависимости: - -
      -
      -$ cd myapp
      -$ npm install
      -
      -
      - -В MacOS или Linux запустите приложение с помощью следующей команды: - -
      -
      -$ DEBUG=myapp:* npm start
      -
      -
      - -В Windows используется следующая команда: - -
      -
      -> set DEBUG=myapp:* & npm start
      -
      -
      - -Затем откройте страницу http://localhost:3000/ в браузере для доступа к приложению. - -Структура каталогов сгенерированного приложения выглядит следующим образом: - -
      -
      -.
      -├── app.js
      -├── bin
      -│   └── www
      -├── package.json
      -├── public
      -│   ├── images
      -│   ├── javascripts
      -│   └── stylesheets
      -│       └── style.css
      -├── routes
      -│   ├── index.js
      -│   └── users.js
      -└── views
      -    ├── error.pug
      -    ├── index.pug
      -    └── layout.pug
      -
      -7 directories, 9 files
      -
      -
      - -
      -Структура приложения, сгенерированная с помощью генератора, является всего лишь одним из множества способов организации структуры приложений Express. Вы можете использовать данную структуру или изменять ее в соответствии со своими потребностями. -
      diff --git a/ru/starter/hello-world.md b/ru/starter/hello-world.md deleted file mode 100755 index e178b7829d..0000000000 --- a/ru/starter/hello-world.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -layout: page -title: Пример "Hello World" в Express -menu: starter -lang: ru ---- - -# Пример "Hello world" - -
      -Ниже приведен пример самого простого приложения, которое можно создать с помощью Express. Оно состоит из одного файла, *в отличие* от приложений, генерируемых с помощью [генератора приложений Express](/{{ page.lang }}/starter/generator.html), который обеспечивает создание основы для полноценного приложения с многочисленными файлами на JavaScript, шаблонами Jade и вложенными каталогами различного предназначения. -
      - -Вначале создайте каталог с именем `myapp`, перейдите в него и запустите команду `npm init`. Затем установите `express` как зависимость, следуя указаниям, приведенным в [руководстве по установке](/{{ page.lang }}/starter/installing.html). - -В каталоге `myapp` создайте файл с именем `app.js` и добавьте следующий код: - -
      -
      -const express = require('express')
      -const app = express()
      -const port = 3000
      -
      -app.get('/', (req, res) => {
      -  res.send('Hello World!')
      -})
      -
      -app.listen(port, () => {
      -  console.log(`Example app listening at http://localhost:${port}`)
      -})
      -
      -
      - -Приложение запускает сервер и слушает соединения на порте 3000. Приложение выдает ответ "Hello World!" на запросы, адресованные корневому URL (`/`) или *маршруту*. Для всех остальных путей ответом будет **404 Not Found**. - -
      -`req` (запрос) и `res` (ответ) являются теми же объектами, которые предоставляет Node, поэтому можно вызвать `req.pipe()`, `req.on('data', callback)` и выполнить любые другие действия, не требующие участия Express. -
      - -Запустите приложение с помощью следующей команды: - -
      -
      -$ node app.js
      -
      -
      - -После этого откройте в браузере страницу [http://localhost:3000/](http://localhost:3000/), чтобы просмотреть результат. - diff --git a/ru/starter/installing.md b/ru/starter/installing.md deleted file mode 100755 index 087c03d339..0000000000 --- a/ru/starter/installing.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -layout: page -title: Установка Express -menu: starter -lang: ru ---- - -# Установка - -Предположим, вы уже установили [Node.js](https://nodejs.org/). Создайте каталог для своего приложения и сделайте его своим рабочим каталогом. - -
      -
      -$ mkdir myapp
      -$ cd myapp
      -
      -
      - -С помощью команды `npm init` создайте файл `package.json` для своего приложения. -Дополнительную информацию о работе `package.json` можно найти в разделе [Специфика работы с npm package.json](https://docs.npmjs.com/files/package.json). - -
      -
      -$ npm init
      -
      -
      - -Эта команда выдает целый ряд приглашений, например, приглашение указать имя и версию вашего приложения. -На данный момент, достаточно просто нажать клавишу ВВОД, чтобы принять предлагаемые значения по умолчанию для большинства пунктов, кроме следующего: - -
      -
      -entry point: (index.js)
      -
      -
      - -Введите `app.js` или любое другое имя главного файла по своему желанию. Если вас устраивает `index.js`, нажмите клавишу ВВОД, чтобы принять предложенное имя файла по умолчанию. - -Теперь установите Express в каталоге `myapp` и сохраните его в списке зависимостей. Например: - -
      -
      -$ npm install express --save
      -
      -
      - -Для временной установки Express, без добавления его в список зависимостей, не указывайте опцию `--save`: - -
      -
      -$ npm install express
      -
      -
      - -
      -Модули Node, установленные с опцией `--save`, добавляются в список `dependencies` в файле `package.json`. -В дальнейшем, при запуске `npm install` в каталоге `app` установка модулей из списка зависимостей будет выполняться автоматически. -
      diff --git a/ru/starter/static-files.md b/ru/starter/static-files.md deleted file mode 100755 index fabbe60a01..0000000000 --- a/ru/starter/static-files.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -layout: page -title: Предоставление статических файлов в Express -menu: starter -lang: ru ---- - -# Предоставление статических файлов в Express - -Для предоставления статических файлов, например, изображений, файлов CSS и JavaScript в Express используется функция промежуточной обработки `express.static`. - -Для того чтобы начать непосредственное предоставление файлов, необходимо передать имя каталога, в котором находятся статические ресурсы, в функцию промежуточной обработки `express.static`. Например, воспользуйтесь приведенным ниже кодом для предоставления изображений, файлов CSS и JavaScript, расположенных в каталоге `public`: - -
      -
      -app.use(express.static('public'));
      -
      -
      - -Теперь можно загрузить файлы, находящиеся в каталоге `public` directory: - -
      -
      -http://localhost:3000/images/kitten.jpg
      -http://localhost:3000/css/style.css
      -http://localhost:3000/js/app.js
      -http://localhost:3000/images/bg.png
      -http://localhost:3000/hello.html
      -
      -
      - -
      -Express выполняет поиск файлов относительно статического каталога, поэтому имя статического каталога не является частью URL. -
      - -Для использования нескольких каталогов, содержащих статические ресурсы, необходимо вызвать функцию промежуточной обработки `express.static` несколько раз: - -
      -
      -app.use(express.static('public'));
      -app.use(express.static('files'));
      -
      -
      - -Express выполняет поиск файлов в том порядке, в котором указаны статические каталоги в функции промежуточной обработки `express.static`. - -Для того чтобы создать префикс виртуального пути (то есть, пути, фактически не существующего в файловой системе) для файлов, предоставляемых с помощью функции `express.static`, необходимо [указать путь монтирования](/{{ page.lang }}/4x/api.html#app.use) для статического каталога, как показано ниже: - -
      -
      -app.use('/static', express.static('public'));
      -
      -
      - -Теперь можно загрузить файлы, находящиеся в каталоге `public`, указанного в префиксе пути `/static`. - -
      -
      -http://localhost:3000/static/images/kitten.jpg
      -http://localhost:3000/static/css/style.css
      -http://localhost:3000/static/js/app.js
      -http://localhost:3000/static/images/bg.png
      -http://localhost:3000/static/hello.html
      -
      -
      - -Тем не менее, путь, переданный в функцию `express.static`, указан относительно каталога, из которого запускается процесс `node`. В случае запуска приложения Express из другого каталога, безопаснее использовать абсолютный путь к каталогу для предоставления файлов: - -
      -
      -app.use('/static', express.static(__dirname + '/public'));
      -
      -
      diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000000..8a12ff9062 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,65 @@ +--- +layout: null +sitemap: false +--- + + +{% for lang in site.data.languages %} + + {% if lang.code == 'en' %} + {{site.url}} + {% else %} + {{site.url}}/{{ lang.code }}/ + {% endif %} + + {% for alt_lang in site.data.languages %} + {% if alt_lang.code == 'en' %} + + {% else %} + + {% endif %} + {% endfor %} + +{% endfor %} +{% for page in site.html_pages %} + {% assign clean_url = page.url | split: '/' | slice: 2, page.url.size | join: '/' %} + {% if clean_url.size > 0 %} + {% if page.layout != 404 and page.sitemap != false %} + + {{site.url}}{{ page.url}} + + {% for lang in site.data.languages %} + + {% endfor %} + + {% endif %} + {% endif %} +{% endfor %} + + https://expressjs.com/en/changelog/ + +{% for post in site.posts %} + + {{site.url}}{{post.url}} + {{ post.date | date_to_xmlschema }} + +{% endfor %} + + https://nodejs.org/en/ + + + https://openjsf.org/ + + + https://terms-of-use.openjsf.org/ + + + https://privacy-policy.openjsf.org/ + + + https://github.com/expressjs/express/blob/master/Code-Of-Conduct.md + + + https://trademark-policy.openjsf.org/ + + \ No newline at end of file diff --git a/sk/3x/api.md b/sk/3x/api.md deleted file mode 100644 index 08fb8534e0..0000000000 --- a/sk/3x/api.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: 3x-api -title: Express 3.x - API -menu: api -lang: sk ---- -
      - -
      - **Express 3.x už nieje ďalej maintainovaný** - - Známe i neznáme security a performance problémy vo verziách 3.x neboli upravované od posledného update (1 August, 2015). Je vysoko doporučované používať poslednú verziu Express. -
      - -

      3.x API

      - - - {% include api/en/3x/express.md %} - - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} - - - {% include api/en/3x/res.md %} - - - {% include api/en/3x/middleware.md %} - -
      diff --git a/sk/4x/api.md b/sk/4x/api.md deleted file mode 100644 index 8fdfcd1455..0000000000 --- a/sk/4x/api.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API -menu: api -lang: sk ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/sk/advanced/best-practice-performance.md b/sk/advanced/best-practice-performance.md deleted file mode 100644 index a3e84088c8..0000000000 --- a/sk/advanced/best-practice-performance.md +++ /dev/null @@ -1,463 +0,0 @@ ---- -layout: page -title: Osvedčené postupy pre Express v produkcii - výkonnosť a spoľahlivosť -menu: advanced -lang: sk ---- - - -# Osvedčené postupy pre Express v produkcii: výkonnosť a spoľahlivosť - -## Prehľad - -Tento článok popisuje niektoré osvedčené postupy z pohľadu výkonnosti a spoľahlivosti Express aplikácií v produkcii. - -Táto časť jasne spadá do tzv. "devops" sveta, dotýkajúca sa tradičného vývoja a prevádzky. Podľa toho sú tieto informácie rozdelené do dvoch častí: - -* [Kroky, ktoré je potrebné vykonať vo vašom kóde](#code) (časť vývoja). -* [Kroky, ktoré je potrebné vykonať na vašom prostredí](#env) (časť prevádzky). - - - -## Kroky, ktoré je potrebné vykonať vo vašom kóde - -Dodržiavanie nasledujúcich postupov vo vašom kóde môže viesť k zlepšeniu výkonnosti vašej aplikácie: - -* Používajte gzip kompresiu -* Nepoužívajte synchrónne funkcie -* Pre servovanie statických súborov používajte middleware -* Správne logujte -* Správne odchytávajte a spracovávajte výnimky - -### Používajte gzip kompresiu - -Použitie gzip kompresie môže veľmi znížiť veľkosť response body a tým zvýšíť rýchlosť webovej aplikácie. Pre zapnutie gzip kompresie vo vašej Express aplikácii používajte [compression](https://www.npmjs.com/package/compression) middleware. Napr.: - -```js -var compression = require('compression') -var express = require('express') -var app = express() -app.use(compression()) -``` - -Pre stránky s vysokou návštevnosťou sa odporúča implementovať kompresiu na úrovni reverse proxy (pozrite sa na [Použitie reverse proxy](#proxy)). V takom prípade nemusíte použiť compression middleware. Pre viac detailov ohľadom zapnutia gzip kompresie na Nginx serveri sa pozrite na [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html) v Nginx dokumentácii. - -### Nepoužívajte synchrónne funkcie - -Synchrónne funkcie a metódy "držia" proces vykonania až do kým nebudú spracované. Jedno volanie synchrónnej funkcie môže trvať pár mikrosekúnd, či milisekúnd, avšak v prípade stránok s vysokou návštevnosťou, takéto volania znižujú výkonnosť aplikácie. Preto sa ich používaniu v produkcii vyhnite. - -Hoci samotný Node i mnohé jeho moduly poskytujú synchrónne a asynchrónne verzie ich funkcií, v produkcii vždy používajte ich asynchrónne verzie. Jediná situácia, kedy by malo použitie synchrónnej funkcie opodstatnenie, je pri prvotnom spustení aplikácie. - -Ak používate Node.js 4.0+ alebo io.js 2.1.0+, môžete použiť prepínač `--trace-sync-io`, ktorý vypíše warning a stack trace vždy, keď vaša aplikácia použije synchrónne API. V produkcii to samozrejme nepoužívajte, ale už pri developmente sa uistite, že vaša aplikácia je pripravená na produkciu. Pre viac informácií sa pozrite na [Weekly update for io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0). - -### Pre servovanie statických súborov používajte middleware - -V developmente môžete pre servovanie statických súborov používať [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile). V produkcii to však nepoužívajte, pretože táto funkcia musí pri každom requeste čítať dáta z file systému, čo má za následok značné oneskorenie a celkovo nepriaznivo ovlyvňuje výkonnosť aplikácie. `res.sendFile()` funkcia _nie_ je implementovaná pomocou [sendfile](http://linux.die.net/man/2/sendfile) systémového volania, ktoré by ju robilo oveľa efektívnejšou. - -Namiesto toho používajte [serve-static](https://www.npmjs.com/package/serve-static) middleware (prípadne podobný ekvivalent), ktorý je optimalizovaný pre servovanie statických súborov v Express aplikáciách. - -Ešte lepšou možnosťou pre servovanie statických súborov je použitie reverse proxy; pre viac informácií sa pozrite na [Použitie reverse proxy](#proxy). - -### Správne logujte - -Vo všeobecnosti existujú dva dôvody k logovaniu vo vašej aplkácii a to debugovanie a logovanie aktivít vašej aplikácie. Použitie `console.log()` príp. `console.err()` k vypísaniu log správy je bežnou praxou počas developmentu. Avšak pozor, [tieto funkcie sú synchrónne](https://nodejs.org/api/console.html#console_console_1) v prípade, ak je výstupom terminál príp. súbor, takže nie sú vhodné pre produkčné prostredie, pokiaľ výstup nepresmerujete do iného programu. - -#### Logovanie z dôvodu debugovania - -Ak používate na debugovanie logovanie pomocou `console.log()`, používajte radšej špeciálny modul na debugovanie, ako napr. [debug](https://www.npmjs.com/package/debug). Tento modul vám umožňuje použivať environment premennú DEBUG, pomocou ktorej dokážete kontrolovať, ktoré debug výpisy budú vypísané pomocou `console.err()`, príp. žiadne. Ak chcete, aby vaša aplikácia bola čisto asynchrónna, budete stále potrebovať presmerovať výstup `console.err()` do iného programu. Ale v skutočnosti asi nechcete debugovať v produkcii, však? - -#### Logovanie aktivít aplikácie - -Ak používate logovanie na sledovanie aktivít aplikácie (napr. sledovanie traffic-u, príp. API volaní), používajte namiesto `console.log()` logovacie knižnice, ako sú napr. [Winston](https://www.npmjs.com/package/winston) či [Bunyan](https://www.npmjs.com/package/bunyan). Ak vás zaujíma detailnejšie porovnanie týchto dvoch knižníc, prečítajte si tento blog post: [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - - - -### Správne odchytávajte a spracovávajte výnimky - -V prípade neodchytenia výnimky Node.js aplikácia spadne. Tzn, že v prípade nespracovania výnimky a nevykonania správnej akcie vaša Express aplikácia spadne. Ak budete pokračovať podľa rád v časti [Zabežpečte, aby sa vaša aplikácia automaticky reštartovala](#restart), tak sa vaša aplikácia z pádu zotaví. Express aplikácie potrebujú naštastie len krátky čas k naštartovaniu. Bez ohľadu nato, by ste sa mali pádom aplikácie v prvom rade vyhnúť a k tomu potrebujete správne odchytávať výnimky. - -K uisteniu sa, že spracovávate všetky výnimky, používajte tieto techniky: - -* [Používajte try-catch](#try-catch) -* [Používajte promises](#promises) - -Predtým, ako sa hlbšie pustíme do týchto tém, mali by ste mať základné znalosti Node/Express error handlingu, akými sú používanie error-first callback-ov a šírenie errorov middlewarmi. Node používa pre návrat errorov z asynchrónnych funkcií konvenciu "error-first callbackov", kde prvým argumentom callback funkcie je error objekt, nasledovaný ostatnými návratovými hodnotami úspešného spracovanie funkcie. Ak nenastal žiaden error zabezpečte, aby prvým parametrom bol null. Definícia callback funkcie musí korešpondovať s error-first callback konvenciou a musí zmysluplne spracovať error. V Express aplikáciách je pre šírenie erroru middlewarmi osvedčenou a odporúčanou technikou použitie next() funkcie. - -Pre viac informácií ohľadom základov error handlingu sa pozrite na: - -* [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop blog) - -#### Čo nerobiť - -Jedna z vecí, ktorú by ste robiť _nemali_ je počúvať na `uncaughtException` event, ktorý je emitovaný v okamihu kedy výnimka "bublá" celou cestu späť do event loop-u. Pridanie event listenera `uncaughtException` zmení defaultné chovanie procesu, ktorý narazil na výnimku; proces bude pokračovať napriek výnimke. Toto sa môže zdať ako dobrým riešením, ako predísť pádu vašej aplikácie, avšak pokračovanie behu vašej aplikácie, v prípade neodchytenej výnimky je nebezpečnou praktikou a nepodporúča sa, pretože sa tým stav procesu stáva nespoľahlivým a nepredpovedateľným. - -Navyše, použitie `uncaughtException` je oficiálne uznané ako [hrubé](https://nodejs.org/api/process.html#process_event_uncaughtexception) a existuje [návrh](https://github.com/nodejs/node-v0.x-archive/issues/2582) na jeho odstránenie z jadra. Takže počúvanie na `uncaughtException` nie je dobrým nápadom. To je dôvod, prečo odporúčame veci ako viacero procesov a supervisorov: pád a reštartovanie je často najspolalivejším spôsobom zotavenia sa z erorru. - -Taktiež neodporúčame používať [domain](https://nodejs.org/api/domain.html) modul. Všeobecne nerieši žiaden problém a je označený ako deprecated modul. - - - -#### Používajte try-catch - -Try-catch je klasická konštrukcia v jazyku JavaScript, pomocou ktorej dokážete odchytiť výnimky v synchrónnom kóde. Použite try-catch, napr. na spracovanie chýb pri JSON parsingu, ako na ukážke nižšie. - -Používajte nástroje [JSHint](http://jshint.com/) príp. [JSLint](http://www.jslint.com/), ktoré vám pomôžu nájsť implicitné výnimky, ako napr. [reference errors on undefined variables](http://www.jshint.com/docs/options/#undef). - -Tu je príklad použitia try-catch k odchyteniu potenciálnej výnimky zapríčiňujúcej pád procesu. -Táto middleware funkcia príjma query parameter nazvaný "params" ktorý je JSON objekt. - -```js -app.get('/search', (req, res) => { - // Simulating async operation - setImmediate(() => { - var jsonStr = req.query.params - try { - var jsonObj = JSON.parse(jsonStr) - res.send('Success') - } catch (e) { - res.status(400).send('Invalid JSON string') - } - }) -}) -``` - -Pozor, try-catch funguje len pre synchrónny kód. Vzhľadom nato, že Node platforma je primárne asynchrónna (obzvlášť v produkčnom prostredí), veľa výnimiek try-catch neodchytí. - - - -#### Používajte promises - -Promises dokážu spracovať všetky typy výnimiek (explicitné aj implicitné) v asynchrónnych blokoch kódu používajuce `then()`, pridaním `.catch(next)` na koniec promise reťazca. Napr.: - -```js -app.get('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) -}) - -app.use((err, req, res, next) => { - // handle error -}) -``` - -Takto sa všetky asynchrónne i synchrónne errory prešíria do error middleware-u. - -Avšak, dve upozornenia: - -1. Všetky vaše asynchrónne kódy musia vracať promises (okrem emitorov). Ak niektorá z knižníc nevracia promises, konvertnite základný objekt použitím funkcie ako napr. [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Event emitory (ako sú streams) môžu spôsobiť neodchytené výnimky. Preto sa uistite, že správne spracovávate error eventy. -Napr.: - -```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) - -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) -``` - -Pre viac informácií ohľadom error handling-u použitím promises si prečítajte: - -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) - - - -## Kroky, ktoré je potrebné vykonať na vašom prostredí - -Tu je niekoľko krokov, ktoré môžete vykonať na vašom environment-e pre zlepšenie výkonnosti vašej aplikácie: - -* Nastavte NODE_ENV premennú na "production" -* Zabezpečte automatický reštart vašej aplikácie -* Zabezpečte, aby vaša aplikácia bežala v clusteri -* Cachujte request resulty -* Používajte load balancer -* Používajte reverse proxy - -### Nastavte NODE_ENV premennú na "production" - -NODE_ENV environment premenná špecifikuje, v ktorom environmente vaša aplikácia beží, zvyčajne (development alebo production). Jedna z najjednoduchších vecí, ktorú môžete vykonať k zlepšeniu výkonnosti vašej aplikácie je nastavenie premennej NODE_ENV na "production". - -Nastavenie NODE_ENV na "production" zabezpečí, aby Express: - -* Cachoval view templates. -* Cachoval CSS súbory generované z CSS extenzií. -* Generoval "menej ukecané" error messages. - -[Testy ukazujú](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/), že tym dokážete zlepšiť výkonnosť aplikácie až trojnásobne! - -Ak potrebujete písať kód, ktorý je environment-specific, môžete hodnotu NODE_ENV premennej zistiť pomocou `process.env.NODE_ENV`. Pamätajte však nato, že zisťovanie hodnoty akejkoľvek environment premennej má čiastočný dopad na výkonnosť, preto by ste to mali robiť skôr sporadicky. - -Počas vývoja nastavujete environment premenné zvyčajne pomocou shellu, napr. použitím `export` vo vašom `.bash_profile` súbore. Toto by ste však nemali robiť na produkčnom serveri; namiesto toho, použite init systém vášho operačného systému (systemd alebo Upstart). Nasledujúca sekcia poskytuje viac detailov ohľadom použitia init systému, pričom nastavenie NODE_ENV premennej je veľmi dôležité z pohľadu výkonnosti (a zároveň veľmi jednoduché), ako je načrtnuté tu: - -Pomocou Upstart, použite kľúčové slovo `env` vo vašom job súbore. Napr.: - -
      -
      -# /etc/init/env.conf
      - env NODE_ENV=production
      -
      -
      - -Pre viac informácií si prečítajte [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). - -Pomocou systemd, použite direktívu `Environment` vo vašom unit súbore. Napr.: - -
      -
      -# /etc/systemd/system/myservice.service
      -Environment=NODE_ENV=production
      -
      -
      - -Pre viac informácií si prečítajte [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). - -Ak používate StrongLoop Process Manager, môžete [nastaviť environment premennú taktiež keď nainštalujete StrongLoop PM ako službu](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). - -### Zabežpečte, aby sa vaša aplikácia automaticky reštartovala - -V produkcii zvyčajne nechcete, aby vaša aplikácia bola offline, nikdy. To znamená, že musíte zabezpečiť, aby sa reštartovala v obidvoch prípadoch, či už je to pád aplikácie, alebo servera samotného. Hoci si určite želáte, aby sa ani jedna z týchto vecí nestala, musíte s tým počítať pomocou: - -* Použitím správcu procesov k reštartovaniu aplikácie (a Node procesu) v prípade pádu. -* Použitím init systému poskytovaného vašim OS na reštartovanie správcu procesov v prípade pádu OS. Taktiež je možné použiť init systém bez správcu procesov. - -Node aplikácie zhavarujú v prípade výskytu neodchytenej výnimky. Ako prvé by ste sa mali uistiť, že vaša aplikácia je dostatočne otestovaná a spracováva všetky výnimky (pre viac detailov si pozrite časť [Správne odchytávajte a spracovávajte výnimky](#exceptions)). Ako záchranu vytvorte/nastavte mechanizmus automatického reštartu. - -#### Používajte správcu procesov - -Počas vývoja štartujete vašu aplikáciu jednoducho z príkazového riadka pomocou `node server.js`, príp. niečoho podobného. Tento spôsob je však v prípade produkcie cesta do pekla. Ak vaša aplikácia spadne, bude offline až dokým ju nereštartujete. Aby ste sa uistili, že sa vaša aplikácia v prípade pádu reštartuje, používajte správcu procesov. Správca procesov je "kontainer" pre aplikácie, ktorý vám pomáha pri deploymente, poskytuje vysokú dostupnosť a umožňuje správu aplikácie v runtime. - -Správca procesov umožňuje okrem automatického reštartu vašej aplikácie taktiež: - -* Získať pohľad o výkonnosti runtime a spotrebe resourcov. -* Dynamicky upravovať nastavenia pre zlepšenie výkonnosti. -* Kontrolu clusteringu (StrongLoop PM a pm2). - -Spomedzi správcov procesov pre Node sú najpopulárnejši: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -Pre detailnejšie porovnanie vlastností si pozrite [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Pre detailnejšie intro si pozrite [Process managers for Express apps](/{{ page.lang }}/advanced/pm.html). - -Použitím hociktorého z týchto správcov procesov zabezpečíte, aby vaša aplikácia zostala "hore" i v prípade občasného pádu. - -Avšak, StrongLoop PM má veľa ďalších features špeciálne určené pre produkčné prostredie. Môžete ich použiť na: - -* Vytvorenie buildu vašej aplikácie lokálne a následný bezpečný deployment do produkcie. -* Automatický reštart vašej aplikácie v prípade pádu. -* Vzdialenú správu vášho clustera. -* Zobrazenie CPU profilov a heap snapshotov k optimalizácii výkonnosti a diagnostike memory leakov. -* Zabrazenie performance metrík vašej aplikácie. -* Jednoduchú škálovateľnosť na viacero hostov s intergrovanou kontrolou pre Nginx load balancer. - -Ako je vysvetlené nižšie, pri inštalácii StrongLoop PM pomocou init systému, ako služby operačného systému, sa služba automaticky reštartuje po reštartovaní systému. Takto bude vaša aplikácia a cluster bežať navždy. - -#### Používajte init systém - -Ďalšiou vrstvou spoľahlivosti je zabezpečenie, aby sa vaša aplikácia reštartovala pri reštartovaní servera. Systémy môžu spadnúť z rôznych dôvodov. Aby bolo zaistené, aby sa vaša aplikácie reštartovala v prípade, ak dôjde k chybe servera, použite init systém zabudovaný do vášho operačného systému. Dva hlavné init systémy používané v súčasnosti sú [systemd](https://wiki.debian.org/systemd) a [Upstart](http://upstart.ubuntu.com/). - -Existujú dva spôsoby použitia init systémov s vašou Express aplikáciou: - -* Spustite vašu aplikáciu v správcovi procesov a nainštalujte správcu procesov ako službu s init systémom. Správca procesov zabezpečí reštart aplikácie pri jej páde a init systém reštartuje správcu procesov v prípade reštartu OS. Jedná sa o odporúčaný postup. -* Spustite vašu aplikáciu (a Node) priamo s init systémom. Tento postup je trocha jednoduchší, ale prídete tým o ďalšie výhody plynúce z použitia správcu procesov. - -##### Systemd - -Systemd je správca služieb používaný niektorými distribúciami Linuxu. Väčšina hlavných linuxových distribúcií prijala systemd ako svoj defaultný init systém. - -Konfiguračný súbor pre systemd sa nazýva _unit file_, ktorého názov má príponu .service. Tu je príklad súboru pre priamu správu Node aplikácie (nahradte tučný text s hodnotami vášho systéme a aplikácie): - -
      -
      -[Unit]
      -Description=Awesome Express App
      -
      -[Service]
      -Type=simple
      -ExecStart=/usr/local/bin/node /projects/myapp/index.js
      -WorkingDirectory=/projects/myapp
      -
      -User=nobody
      -Group=nogroup
      -
      -# Environment variables:
      -Environment=NODE_ENV=production
      -
      -# Allow many incoming connections
      -LimitNOFILE=infinity
      -
      -# Allow core dumps for debugging
      -LimitCORE=infinity
      -
      -StandardInput=null
      -StandardOutput=syslog
      -StandardError=syslog
      -Restart=always
      -
      -[Install]
      -WantedBy=multi-user.target
      -
      -
      -Pre viac informácií ohľadom systemd si prečítajte [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM ako systemd služba - -StrongLoop PM možete jednoducho nainštalovať ako systemd službu. Následne, v prípade že nastane reštart servera, systemd automaticky reštartuje i StrongLoop PM, ktorý následne reštartuje i aplikácie ktoré spravuje. - -Pre inštaláciu StrongLoop PM ako systemd služby spustite: - -
      -
      -$ sudo sl-pm-install --systemd
      -
      -
      - -Potom spustite službu pomocou: - -
      -
      -$ sudo /usr/bin/systemctl start strong-pm
      -
      -
      - -Pre viac informácií si prečítajte [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart je systémový nástroj dostupný v mnohých linuxových distribúciách slúžiaci na spúšťanie taskov a služieb počas štartu systému, ich zastavenie počas vypnutia a dohľadu nad nimi. Vašu Express aplikáciu, alebo správcu procesov môžete nakonfigurovať ako službu a potom Upstart zabezpečí jej reštart v prípade pádu. - -Upstart služba je definovaná v konfiguračnom súbore (tiež nazývaný "job") s názvom súboru končiacim `.conf`. Nasledujúci príklad ukazuje, ako vytvoriť job súbor s názvom "myapp" pre aplikáciu s názvom "myapp" s hlavným súbor umiestneným v `/projects/myapp/index.js`. - -Vytvorte súbor s názvom `myapp.conf` umiestnený v `/etc/init /` s nasledujúcim obsahom (nahraďte tučný text s hodnotami pre váš systém a aplikáciu): - -
      -
      -# When to start the process
      -start on runlevel [2345]
      -
      -# When to stop the process
      -stop on runlevel [016]
      -
      -# Increase file descriptor limit to be able to handle more requests
      -limit nofile 50000 50000
      -
      -# Use production mode
      -env NODE_ENV=production
      -
      -# Run as www-data
      -setuid www-data
      -setgid www-data
      -
      -# Run from inside the app dir
      -chdir /projects/myapp
      -
      -# The process to start
      -exec /usr/local/bin/node /projects/myapp/index.js
      -
      -# Restart the process if it is down
      -respawn
      -
      -# Limit restart attempt to 10 times within 10 seconds
      -respawn limit 10 10
      -
      -
      - -Pozn.: Tento skript vyžaduje Upstart 1.4 príp. novší, podporovaný na Ubuntu 12.04-14.10. - -Potom, ako je job nakonfigurovaný k spusteniu po štarte systému, bude vaša aplikácia spustená spolu s operačným systémom a automaticky reštartovaná v prípade pádu aplikácie alebo reštartu samotného systému. - -Okrem automatického reštartovania aplikácie, Upstart umožňuje použíť tieto príkazy: - -* `start myapp` – Start the app -* `restart myapp` – Restart the app -* `stop myapp` – Stop the app. - -Pre viac informácií ohľadom Upstart si prečítajte tu: [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM ako Upstart služba - -StrongLoop PM možete jednoducho nainštalovať ako Upstart službu. Následne, v prípade že nastane reštart servra, Upstart automaticky reštartuje i StrongLoop PM, ktorý následne reštartuje aj aplikácie ktoré spravuje. - -Pre inštaláciu StrongLoop PM ako Upstart 1.4 služby: - -
      -
      -$ sudo sl-pm-install
      -
      -
      - -Pre spustenie služby: - -
      -
      -$ sudo /sbin/initctl start strong-pm
      -
      -
      - -Pozn.: Pre systémy bez podpory Upstart 1.4 sú príkazy mierne odlišné. Pre viac informácií sa pozrite na [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10). - -### Zabezpečte aby vaša aplikácia bežala v clusteri - -V prípade multi-core systémov môžete zvýšiť výkonnosť Node aplikácie niekoľko násobne jej spustením clusterom procesov. V clusteri beží niekoľko inštancií aplikácie, ideálne jedna pre každé CPU jadro, čím sa rozloží záťaž a úlohy medzi jednotlívé inštancie. - -![Balancovanie medzi inštanciami aplikácie použitím cluster API](/images/clustering.png) - -Dôležité: Od momentu kedy inštancia aplikácie beží ako samostatný proces, nezdieľajú spoločnu pamäť. Tzn. objekty sú lokálne pre každú inštanciu aplikácie. Preto nedokážete spravovať stav v kóde aplikácie. Namiesto toho môžete k ukladaniu dát týkajúcich sa session a stavu použiť tzv. in-memory datastore ako [Redis](http://redis.io/). Toto varovanie platí v podstate pre všetky formy horizontálneho škálovania, či už clustering s viacerými procesmi alebo viacero fyzických servrov. - -V clusterovaných aplikáciách, worker procesy môžu spadnúť individuálne bez toho, aby ovplyvnili zvyšok procesov. Okrem výhody z pohľadu výkonnosti, izolovanie chybovosti je ďalším dôvodom pre beh clustra procesov aplikácie. V prípade, že worker proces spadne zabezpečte, že vždy sa zalogujte event a vytvorí nový process (spawn) pomocou cluster.fork(). - -#### Použite Node cluster modulu - -Clustering je možný pomocou Node [cluster modulu](https://nodejs.org/dist/latest-v4.x/docs/api/cluster.html). Ten dovoľuje master procesu vyrobiť (spawn) worker procesy a rozdistribuovať prichádzajúce spojenia medzi workerov. Avšak, lepšie než priame použitie tohto modulu je použiť jeden z mnohých existujúcich toolov, ktoré to robia automaticky, napr. [node-pm](https://www.npmjs.com/package/node-pm) alebo [cluster-service](https://www.npmjs.com/package/cluster-service). - -#### Použitie StrongLoop PM - -V prípade, že deploynete vašu aplikáciu do StrongLoop Process Manager (PM), získate tým výhody clusteringu _bez_ modifikácie kódu vašej aplikácie. - -Keď StrongLoop Process Manager (PM) spúšta aplikáciu, aplikácia je spustená automaticky v clusteri s takým množstvom workerov, aý je počet jadier CPU systéme. Počet worker procesov v clustri môžete manuálne zmeniť použitím slc nástroja bez nutnosti stopnutia aplikácie. - -Napr., predpokladajúc, že ste deployli vašu aplikáciu na prod.foo.com a StrongLoop PM počúva na porte 8701 (defaultný), tak nastavenie veľkosti clustera na osem vykonáte pomocou slc takto: - -
      -
      -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
      -
      -
      - -Pre viac informácií ohľadom clusteringu pomocou StrongLoop PM sa pozrite na časť [Clustering](https://docs.strongloop.com/display/SLC/Clustering) v StrongLoop dokumentácii. - -### Cache-ovanie odpovedí requestov - -Ďalšou stratégiou pre zlepšenie výkonosti v produkcii je cachovanie odpovedí na prichádzajúce requesty, čím zabezpečíte, že vaša aplikácia nemusí opakovane vykonávat tie isté operácie pre obslúženie rovnakých requestov. - -Použitie caching servra, ako [Varnish] (https://www.varnish-cache.org/) alebo [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (pozrite si tiež [Nginx Caching](https://serversforhackers.com/nginx-caching/)) výrazne zvýši rýchlosť a výkon vášej aplikácie. - -### Použitie load balancera - -Bez ohľadu na to, ako je optimalizovaná aplikácia, jedna inštancia môže spracovať iba obmedzené množstvo záťaže a requestov. Jedným spôsobom škálovania aplikácie je spustenei jej viacerých inštancií a distribuovať zaťaženie pomocou load balancera. Zapojenie load balancera môže zlepšiť výkon a rýchlosť vašej aplikácie a umožní jej vačšie škálovanie, než by bolo možné v prípade jedinej inštancie. - -Load balancer je zvyčajne reverzné proxy, ktoré organizuje prevádzku medzi viacerými inštanciami aplikácie a serverov. Load balancer môžete pre vašu aplikáciu setupnúť jednoducho použítím [Nginx](http://nginx.org/en/docs/http/load_balancing.html), alebo [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). - -Load balancer zabezpečí správne spárovanie requestov súvisiacich s konkrétnym session ID a procesom, ktorý túto session spravuje. Tento prístup sa nazýva _session affinity_, alebo _sticky sessions_ a môže byť riešený návrhom popísaným vyššie, teda použitím dátového úložiska ako je Redis (v závislosti od aplikácie). Prečítajte si nasledujúcu diskusiu [Using multiple nodes](http://socket.io/docs/using-multiple-nodes/). - -#### Použitie StrongLoop PM spolu s Nginx load balancerom - -[StrongLoop Process Manager](http://strong-pm.io/) je integrovaný s Nginx Controller-om, čo uľahčuje konfiguráciu multi-host produkčného prostredia. Pre viac informácií sa pozrite na [Scaling to multiple servers](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (StrongLoop dokumentácia). - - -### Použitie reverzného proxy - -Reverzné proxy je umiestnené pred webovou aplikáciou a vykonáva podporné operácie k requestom smerovaných na aplikáciu. Medzi inným, dokáže handlovať stránky s errormi, kompresiu, caching, servovanie súborov a load balancing. - -Odovzdanie úloh, ktoré nevyžadujú znalosť stavu aplikácie reverznému proxy, odbremení Express aplikáciu a umožní jej vykonávať špecializované úlohy. Z tohto dôvodu sa v produkcii odporúča fungovanie Express za reverzným proxy ako je [Nginx](https://www.nginx.com/) či [HAProxy](http://www.haproxy.org/). diff --git a/sk/advanced/best-practice-security.md b/sk/advanced/best-practice-security.md deleted file mode 100644 index c4a4edf44f..0000000000 --- a/sk/advanced/best-practice-security.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -layout: page -title: Osvedčené postupy pre Express v produkcii - Security -menu: advanced -lang: sk ---- - - -# Osvedčené postupy pre Express v produkcii - Security - -## Prehľad - -Termín _"production"_ znamená stav životného cyklu softvéru, kedy je aplikácia, alebo jej API, všeobecne prístupná koncovým používateľom. Naopak, termín _"development"_ znamená, že sa kód aktívne vyvíja, testuje a aplikácia nie je verejne prístupná. K tomu korešpondujúce systémové prostredia sa nazývajú _production_ resp. _development_ prostredie. - -Development a production prostredia sú zvyčajne nakonfigurované odlišne a majú často diametrálne odlišné požiadavky. Čo je povolené v developmente nemusí byť akceptovateľné v produkcii. Napr., v development prostredí môžete chcieť logovať maximum errorov pre debugovanie, ale takéto správanie sa systému môže byť považované za security problém v prípade production prostredia. V prípade developmentu sa často nemusíte starať o veci ako sú škálovateľnosť, spoľahlivosť a výkonnosť, kým v produkcii sa tieto veci považujú za kritické. - -Tento článok popisuje niektoré osvedčené postupy z pohľadu bezpečnosti Express aplikácií v produkcii. - -**POZN.**: Ak si myslíte, že ste objavili security vulnerabilitu Express-u, prosím pozrite si -[Security Policies and Procedures](https://github.com/expressjs/express/blob/master/Security.md). - -## Nepoužívajte deprecated a vulnerable verzie Express-u - -Express 2.x a 3.x už nie sú viacej udržované. Security a performance problémy v týchto verziách už nik neopravuje. Preto ich nepoužívajte! Ak ste vaše Express aplikácie ešte nezmigrovali na verziu 4, postupujte podľa príručky [Prechod na Express 4](/{{ page.lang }}/guide/migrating-4.html). - -Taktiež sa uistite, že nepoužívate žiadnu z vulnerable Express verzií nachádzajúcu sa na stránke [Security - aktualizácie](/{{ page.lang }}/advanced/security-updates.html). Ak áno, updatnite vašu aplikáciu na niektorú zo stabilných verzií, ideálne na najnovšiu. - -## Používajte TLS - -Ak vaša aplikácia pracuje, alebo prenáša citlivé dáta, použivajte [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) pre zabepečenie spojenia a dát. Táto technológia šifruje dáta pred ich odoslaním z klienta na server, čím predchádza niektorým bežným (a jednoduchým) útokom. Hoci Ajax a POST requesty nemusia byť viditeľné a zdajú sa skryté v prehliadači, ich network traffic je zraniteľný na [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) a [man-in-the-middle útoky](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). - -Možno ste sa už stretli so Secure Socket Layer (SSL) šifrovaním. [TLS je ďalšou modifikáciou SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). Inými slovami, ak ste predtým používali SSL, zvážte upgrade na TLS. Vo všeobecnosti odporúčame pre handlovanie TLS používať Nginx. Ako dobrú referenciu ako nakonfigurovať TLS na Ngix-e (a ďalších serveroch) uvádzame [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). - -Taktiež sa vám môže hodiť nástroj [Let's Encrypt](https://letsencrypt.org/about/), pomocou ktorého môžete získať TLS certifikát zdarma. Je voľnou, automatizovanou a otvorenou certifikačnou autoritou (CA) prevádzkovanou [Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/). - -## Používajte Helmet - -[Helmet](https://www.npmjs.com/package/helmet) môže pomôcť ochrániť vašu aplikáciu voči niektorým, všeobecne známym zraniteľnostiam, pomocou správneho nastavenia HTTP hlavičiek. - -Helmet je v skutočnosti len kolekcia deviatich menších middleware funkcií nastavujúcich HTTP hlavičky týkajúce sa bezpečnosti: - -* [csp](https://github.com/helmetjs/csp) nastavuje `Content-Security-Policy` hlavičku, čím pomáha predchádzať cross-site scripting útokom a ďalším cross-site zraniteľnostiam. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) odstraňuje `X-Powered-By` hlavičku. -* [hsts](https://github.com/helmetjs/hsts) nastavuje `Strict-Transport-Security` hlavičku čím si vynúti zabezpečené (HTTP over SSL/TLS) spojenie so serverom. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) nastavuje hlavičku `X-Download-Options` pre IE8+. -* [noCache](https://github.com/helmetjs/nocache) nastavuje hlavičky `Cache-Control` a Pragma pre zakázanie client-side caching-u. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) nastavuje `X-Content-Type-Options` hlavičku, čím zabraňuje prehliadačom MIME-sniffing odpovede od deklaroveného content-type-u. -* [frameguard](https://github.com/helmetjs/frameguard) nastavuje `X-Frame-Options` hlavičku čim poskytuje ochranu pred [clickjacking](https://www.owasp.org/index.php/Clickjacking). -* [xssFilter](https://github.com/helmetjs/x-xss-protection) nastavuje `X-XSS-Protection` hlavičku, čim povolí Cross-site scripting (XSS) filter vo väčšine najnovších prehliadačov. - -Helmet nainštalujete rovnako, ako akýkoľvek iný modul: - -
      -
      -$ npm install --save helmet
      -
      -
      - -Potom ho môžete použiť vo vašom kóde takto: - -
      -
      -...
      -var helmet = require('helmet');
      -app.use(helmet());
      -...
      -
      -
      - -### Určite aspoň zakážte X-Powered-By hlavičku - -Ak nechcete použiť Helmet, potom určite aspoň zakážte `X-Powered-By` hlavičku. Útočník dokáže zneužiť túto hlavičku (ktorá je defaultne povolená) k detekcii Express aplikácií a následne vykonať špecifické typy útokov. - -Preto sa odporúča, vypnúť túto hlavičku pomocou `app.disable()` metódy: - -
      -
      -app.disable('x-powered-by');
      -
      -
      - -V prípade, že použijete modul `helmet.js`, ten sa o to postará. - -## Používajte cookies bezpečným spôsobom - -Aby ste sa uistili, že cookies nepredstavujú zraniteľnosť vašej aplikácie, nepoužívajte pre session cookie defaultný názov a nastavte správne security parametre. - -Pre prácu s cookie existujú dva hlavné middleware moduly: - -* [express-session](https://www.npmjs.com/package/express-session), ktorý nahrádza `express.session` middleware vstavaný v Express 3.x. -* [cookie-session](https://www.npmjs.com/package/cookie-session), ktorý nahrádza `express.cookieSession` middleware vstavaný v Express 3.x. - -Hlavným rozdielom medzi týmito modulmi je spôsob ukladania cookie session dát. [express-session](https://www.npmjs.com/package/express-session) middleware ukladá session dáta na servery; v samotnej cookie sa ukladá len session ID, nie session dáta. Defaultne je použité ako úložisko pamäť, čo je nevhodné pre použitie v production prostredí. Tam budete musieť nastaviť škálovateľné session úložisko; pozrite sa na [compatible session stores](https://github.com/expressjs/session#compatible-session-stores). - -[cookie-session](https://www.npmjs.com/package/cookie-session) middleware implementuje vlastné cookie-backed úložisko: serializuje celú session do cookie a nie len jej session ID. Použitie tejto implementácie sa odporúča v prípade, že sú session dáta relatívne malé a ľahko šifrovateĺné, ako primitívne hodnoty (skôr než objekty). Hoci by prehliadače mali podporovať veľkosť cookie aspoň 4096 bytes, aby ste sa uistili, že nepresiahnete limit, neprekračujte veľkosť 4093 bytes pre doménu. Taktiež si musíte uvedomiť, že cookie dáta budú na klientovi viditeľné, takže ak existuje dôvod, prečo by ste ich chceli uchovávať radšej zabezpečené a utajené, potom je lepšie použiť express-session modul. - -### Nepoužívajte defaultný session cookie názov - -Používaním defaultného názvu session cookie vystavujete aplikáciu možným útokom. Táto zraniteľnosť je podobná tej `X-Powered-By`: útočník dokáže zneužiť túto informáciu a vykonať cielené útoky. - -Aby ste sa vyhli tomuto problému, použite generické názvy cookie; napr použitím [express-session](https://www.npmjs.com/package/express-session) middlewaru: - -
      -
      -var session = require('express-session');
      -app.set('trust proxy', 1); // trust first proxy
      -app.use( session({
      -   secret : 's3Cur3',
      -   name : 'sessionId',
      -  })
      -);
      -
      -
      - -### Nastavte cookie security parametre - -Pre zlepšenie bezpečnosti nastavte nasledujúce cookie parametre: - -* `secure` - zabezpečí, že prehliadač zašle cookie iba cez HTTPS. -* `httpOnly` - zabezpečí, že cookie bude poslaná iba cez HTTP(S), nie prostredníctvom JavaScript-u na klientovi, čím pomáha chrániť voči cross-site scripting útokom. -* `domain` - udáva doménu cookie; použite to k porovnaniu domény servera, na ktorom bola URL zavolaná. Ak sú zhodné, potom porovnajte ešte path atribút. -* `path` - udáva path pre cookie; použite to k porovnaniu path-u request-u. Ak sa spolu s domain parametrom zhodujú, tak cookie v requeste pošlite. -* `expires` - sa používa na nastavenie dátumu expirácie trvalých cookies. - -Tu je príklad použitia [cookie-session](https://www.npmjs.com/package/cookie-session) middleware modulu: - -
      -
      -var session = require('cookie-session');
      -var express = require('express');
      -var app = express();
      -
      -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
      -app.use(session({
      -  name: 'session',
      -  keys: ['key1', 'key2'],
      -  cookie: { secure: true,
      -            httpOnly: true,
      -            domain: 'example.com',
      -            path: 'foo/bar',
      -            expires: expiryDate
      -          }
      -  })
      -);
      -
      -
      - -## Ďalšie odporúčania - -Tu sú ďalšie odporúčania zo skvelého [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/) zoznamu. Pre viac detailov ohľadom jednotlivých odporúčaní si prečítajte samotný blog post: - -* Implementujte tzv. rate-limiting pre vyhnutie sa brute-force útokom voči autentifikácii. Jednou z možností ako to dosiahnuť je použitie [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) k vynúteniu rate-limiting policy. Ako alternatívu môžete použiť middleware, ako napr. [express-limiter](https://www.npmjs.com/package/express-limiter), avšak to si už vyžaduje mierny zásah do kódu vašej aplikácie. -* Používajte [csurf](https://www.npmjs.com/package/csurf) middleware k ochrane voči útokom typu cross-site request forgery (CSRF). -* Vždy filtrujte a overte vstup od používateľa, aby ste vašu aplikáciu ochránili voči útokom typu cross-site scripting (XSS) a command injection. -* Bránte sa voči útokom typu SQL injection použitím parametrizovaych queries, príp. prepared statements. -* Používajte open source tool [sqlmap](http://sqlmap.org/) k detekcii SQL injection vulnerabilities vo vašej aplikácii. -* Používajte tooly [nmap](https://nmap.org/) a [sslyze](https://github.com/nabla-c0d3/sslyze) k otestovaniu konfigurácie vašich SSL šifier, kľúčov, renegotiation ako aj platnosti vašich certifikátov. -* Používajte [safe-regex](https://www.npmjs.com/package/safe-regex) k uisteniu sa, že vaše regulárne výrazy nie sú náchylné na [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) útoky. - -## Vyhnite sa ďalším známym zraniteľnostiam - -Sledujte [Node Security Project](https://npmjs.com/advisories) odporučania, ktoré môžu ovplyvňovať Express, príp. ostatné moduly vašej aplikácie. Vo všeobecnosti je Node Security Project skvelým zdrojom znalostí a toolov ohľadom bezpečnosti Node.js. - -Na záver dodajme, že Express aplikácie - ako akékoľvek iné webové aplikácie - môžu byť náchylné na mnohé typy útokov. Zoznámte sa so zoznamom známych [web vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-Top_10) a prijmite opatrenia, aby ste sa im vyhli. diff --git a/sk/advanced/developing-template-engines.md b/sk/advanced/developing-template-engines.md deleted file mode 100644 index 1ee2dbe48d..0000000000 --- a/sk/advanced/developing-template-engines.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -layout: page -title: Vývoj template enginov pre Express -menu: advanced -lang: sk ---- - - -# Vývoj template enginov pre Express - -Pre vytvorenie vlastného template enginu použite metódu `app.engine(ext, callback)`. Parameter `ext` špecifikuje príponu súborov a `callback` je samotná funkcia template enginu, ktorá príjma nasledujúce prvky ako parametre: cesta k súboru, options objekt a callback funkciu. - -Nasledujúci kód je príkladom implementácie veľmi jednoduchého template enginu pre rendrovanie `.ntl` súborov. - -
      -
      -var fs = require('fs'); // this engine requires the fs module
      -app.engine('ntl', function (filePath, options, callback) { // define the template engine
      -  fs.readFile(filePath, function (err, content) {
      -    if (err) return callback(new Error(err));
      -    // this is an extremely simple template engine
      -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
      -    .replace('#message#', '

      '+ options.message +'

      '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
      -
      - -Odteraz bude vaša aplikácia schopná rendrovať `.ntl` súbory. Vytvorte súbor s názvom `index.ntl` a `views` priečinok s nasledujúcim obsahom. - -
      -
      -#title#
      -#message#
      -
      -
      -Potom vo vašej aplikácii vytvorte takýto route: - -
      -
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -
      -Keď vykonáte request na home page, `index.ntl` bude vyrendrované ako HTML. diff --git a/sk/advanced/pm.md b/sk/advanced/pm.md deleted file mode 100644 index d682fe0a10..0000000000 --- a/sk/advanced/pm.md +++ /dev/null @@ -1,287 +0,0 @@ ---- -layout: page -title: Použitie správcov procesov pre Express aplikácie -menu: advanced -lang: sk ---- - - -# Použitie správcov procesov pre Express aplikácie - -Ak vaša Express aplikácia pobeží v produkcii, môže byť k dosiahnutiu nasledujúcich úloh vhodné použiť _správcu processov (process manager)_: - -- Reštart aplikácie v prípade pádu. -- Získanie prehľadu o spotrebe zdrojov a výkonnosti aplikácie. -- Dynamická zmena nastavení k zlepšeniu výkonnosti. -- Kontrola nad clustering-om. - -Správca procesov je čiastočne akoby aplikačný server: je to "kontainer" pre aplikácie uľahčujúci ich deployment, -poskytujúci vysokú dostupnosť a umožňujúci správu aplikácie v runtime. - -Najpopulárnejšie s pomedzi správcov procesov pre Express i ostatné Node.js aplikácie patria: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -Použitie ktoréhokoľvek z hore spomenutých nástrojov môže byť veľmi nápomocné, avšak StrongLoop Process Manager je jediným nástrojom poskytujúcim obsiahle runtime a deployment riešenie adresujúce celý životný cyklus Node.js aplikácie pomocou nástrojov pre každý krok pred a po nasadení do produkcie a to v jednotnom rozhraní. - -Tu je jednoduchý náhľad na každý z týchto nástrojov. Pre detailnejšie porovnanie sa pozrite na [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) je produkčný správca procesov pre Node.js aplikácie. StrongLoop PM má vstavaný load balancing, monitoring, multi-host deployment a grafickú konzolu. -StrongLoop PM môžete využiť na tieto úlohy: - -- Build, package, a deploy vašej Node.js aplikácie na lokálny alebo remote systém. -- Zobrazenie CPU profilov and heap snapshotov pre optimalizáciu výkonnosti a diagnostiku memory leakov. -- Udržovanie procesov a clusterov vždy nažive. -- Zobrazenie výkonnostných metrík vašej aplikácie. -- Jednoduchá správa multi-host deploymentov s Nginx integráciou. -- Unifikácia viacerých StrongLoop PM do distribuovaného runtime-u mikro servisov spravovateľných pomocou Arc. - -So StrongLoop PM dokážete pracovať pomocou výkonného command-line interface nástroja nazývaného `slc`, prípadne grafického nástroja nazývaného Arc. Arc je open source s profesonálnou podporou od StrongLoop-u. - -Pre viac informácií si pozrite [http://strong-pm.io/](http://strong-pm.io/). - -Celá dokumentácia: - -- [Operating Node apps (StrongLoop documentation)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Inštalácia -
      -
      -$ [sudo] npm install -g strongloop
      -
      -
      - -### Základné použitie -
      -
      -$ cd my-app
      -$ slc start
      -
      -
      - -Zobrazenie stavu správcu procesov a všetkých deploynutých aplikácií: - -
      -
      -$ slc ctl
      -Service ID: 1
      -Service Name: my-app
      -Environment variables:
      -  No environment variables defined
      -Instances:
      -    Version  Agent version  Cluster size
      -     4.1.13      1.5.14           4
      -Processes:
      -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
      -    1.1.57692  57692   0
      -    1.1.57693  57693   1     0.0.0.0:3001
      -    1.1.57694  57694   2     0.0.0.0:3001
      -    1.1.57695  57695   3     0.0.0.0:3001
      -    1.1.57696  57696   4     0.0.0.0:3001
      -
      -
      - -Vypísanie zoznamu všetkých aplikácií (servisov) pod správou: - -
      -
      -$ slc ctl ls
      -Id          Name         Scale
      - 1          my-app       1
      -
      -
      - -Stopnutie aplikácie: - -
      -
      -$ slc ctl stop my-app
      -
      -
      - -Reštart aplikácie: - -
      -
      -$ slc ctl restart my-app
      -
      -
      - -Môžete taktiež vykonať "mäkký reštart", ktorý dá worker procesom dostatok času na uzatvorenie existujúcich pripojení a následne reštartuje aplikáciu: - -
      -
      -$ slc ctl soft-restart my-app
      -
      -
      - -Odstránenie aplikácie zo správy: - -
      -
      -$ slc ctl remove my-app
      -
      -
      - -## PM2 - -PM2 je produkčný správca procesov pre Node.js aplikácie so vstavaným load balancerom. PM2 dokáže udržať aplikáciu nažive a vykonať jej prípadný reload bez výpadku a umožní vykonávať bežné system admin úlohy. PM2 taktiež umožňuje spravovať logovanie, monitoring a clustering aplikácií. - -Pre viac informácií sa pozrite na [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Inštalácia - -
      -
      -$ [sudo] npm install pm2 -g
      -
      -
      - -### Základné použitie - -Pre naštartovanie aplikácie pomocou `pm2` príkazu musíte špecifikovať cestu k aplikácii. Avšak pre stop, reštart, alebo odstránenie aplikácie zo správy, postačuje špecifikovať len jej názov alebo ID. - -
      -
      -$ pm2 start npm --name my-app -- start
      -[PM2] restartProcessId process id 0
      -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
      -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
      -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
      -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
      -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
      - Use the `pm2 show ` command to get more details about an app.
      -
      -
      - -Po naštartovaní aplikácie pomocou `pm2` príkazu sa aplikácia automaticky spustí na backgrounde (pozadí). Background aplikáciu môžete ovládať z príkazového riadka pomocou rozličných `pm2` príkazov. - -Potom, ako je aplikácia naštartovaná pomocou `pm2` príkazu, je zaregistrovaná do zoznamu PM2 procesov pod konkrétnym ID. Preto dokážete spravovať aplikácie s rovnakým názvom z rôznych priečinkov, použitím ich ID. - -Pozn., ak Vám beží viac ako jedna aplikácia s rovnakým názvom, vykonanie `pm2` príkazu ich ovplyvní všetky. Preto pre správu konkrétnej aplikácie používajte namiesto názvu radšej jej ID. - -Vypísanie zoznamu všetkých bežiacich procesov: - -
      -
      -$ pm2 list
      -
      -
      - -Stopnutie aplikácie: - -
      -
      -$ pm2 stop 0
      -
      -
      - -Reštart aplikácie: - -
      -
      -$ pm2 restart 0
      -
      -
      - -Pre zobrazenie detailných informácií o aplikácii: - -
      -
      -$ pm2 show 0
      -
      -
      - -Odstránenie aplikácie z PM2 registra: - -
      -
      -$ pm2 delete 0
      -
      -
      - - -## Forever - -Forever je jednoduchý command-line nástroj slúžiaci na udržanie vášho skriptu nažive. Jednoduché rozhranie nástroja Forever ho robí ideálnym pre správu menších deploymentov Node.js aplikácií a skriptov. - -Pre viac informácií sa pozrite na [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Inštalácia - -
      -
      -$ [sudo] npm install forever -g
      -
      -
      - -### Základné použitie - -Pre naštartovanie použite príkaz `forever start` a špecifikujte cestu k skriptu: - -
      -
      -$ forever start script.js
      -
      -
      - -Tento príkaz spustí skript v tzv. daemon móde (na pozadí). - -Pre priame spistenie skriptu v termináli vynechajte `start`: - -
      -
      -$ forever script.js
      -
      -
      - -Je dobrým zvykom logovať výstup z nástroja Forever a skriptu pomocou prepínača `-l`, `-o` a `-e`, ako je uvedené v príklade nižšie: - -
      -
      -$ forever start -l forever.log -o out.log -e err.log script.js
      -
      -
      - -Pre zobrazenie zoznamu skriptov, ktoré boli naštartované pomocou Forever použite: - -
      -
      -$ forever list
      -
      -
      - -Pre stopnutie skriptu naštartovaného pomocou Forever použite príkaz `forever stop` a špecifikujte index procesu (podľa výpisu z `forever list` príkazu). - -
      -
      -$ forever stop 1
      -
      -
      - -Taktiež to môžete vykonať pomocou špecifikovania cesty k skriptu: - -
      -
      -$ forever stop script.js
      -
      -
      - -Pre stopnutie všetkých skriptov, ktoré boli naštartované pomocou Forever príkazu použite: - -
      -
      -$ forever stopall
      -
      -
      - -Nástroj Forever má veľa možností a taktiež poskytuje programové API. diff --git a/sk/advanced/security-updates.md b/sk/advanced/security-updates.md deleted file mode 100644 index e4a9e2b7e5..0000000000 --- a/sk/advanced/security-updates.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -layout: page -title: Express security aktualizácie -menu: advanced -lang: sk ---- - - -# Security aktualizácie - -
      -Vulnereabilita (zraniteĺnosť) Node.js priamo ovplyvňuje Express. Preto [sledujte vulnereabilitu Node.js](http://blog.nodejs.org/vulnerability/) a uistite sa, že používate poslednú stable verziu Node.js. -
      - -Zoznam nižšie obsahuje objavené a opravené vulnereability Express-u v špecifických verziách updatov. - -**POZN.**: Ak si myslíte, že ste objavili security vulnerabilitu Express-u, prosím pozrite si -[Security Policies and Procedures](https://github.com/expressjs/express/blob/master/Security.md). - -## 4.x - - * 4.11.1 - * Opravená vulnereabilita sprístupnenia root path-u v `express.static`, `res.sendfile` a `res.sendFile` - * 4.10.7 - * Opravená open redirect vulnereabilita v `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 4.8.8 - * Opravená directory traversal vulnerabilita v `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 obsahuje leak `file descriptorov` čo v určitých situáciách ovplyvňuje `express.static` a `res.sendfile`. Malicious (škodlivé) requesty môžu spôsobiť leakovanie `file descriptorov` a môžu eventuálne viesť k `EMFILE` errorom a neresponzívnosti servera. - * 4.8.0 - * Sparse polia s extrémne vysokými indexami v query stringoch môžu spôsobiť, že pre realizáciu procesu nie je dostatok pamäte a následne crash servera. - * Extrémne vnorené query string objekty môžu spôsobiť zablokovanie procesu a dočasnú neresponzívnosť servera. - -## 3.x - -
      - **Express 3.x UŽ NIE JE VIAC UDRŽIAVANÝ** - - Známe aj neznáme security problémy v 3.x už neboli viac riešené od poslednej aktualizácie (1 August, 2015). Používanie verzie 3.x by nemalo byť považované za bezpečné. -
      - - * 3.19.1 - * Opravená vulnereabilita sprístupnenia root path-u v `express.static`, `res.sendfile`, and `res.sendFile` - * 3.19.0 - * Opravená open redirect vulnereabilita v `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Opravená directory traversal vulnerabilita v `express.static`. - * 3.16.6 - * Node.js 0.10 obsahuje leak `file descriptorov` čo v určitých situáciách ovplyvňuje `express.static` a `res.sendfile`. Malicious (škodlivé) requesty môžu spôsobiť leakovanie `file descriptorov` a môžu eventuálne viesť k `EMFILE` errorom a neresponzívnosti servera. - * 3.16.0 - * Sparse polia s extrémne vysokými indexami v query stringoch môžu spôsobiť, že pre realizáciu procesu nie je dostatok pamäte a následne crash servera. - * Extrémne vnorené query string objekty môžu spôsobiť zablokovanie procesu a dočasnú neresponzívnosť servera. - * 3.3.0 - * Odpoveď 404-ka na pokus o nepodporovaný method override bola náchylná na cross-site scripting útok. diff --git a/sk/api.md b/sk/api.md deleted file mode 100644 index 199d1c04fd..0000000000 --- a/sk/api.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API -lang: sk ---- - -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/sk/guide/behind-proxies.md b/sk/guide/behind-proxies.md deleted file mode 100644 index 5f7b496d56..0000000000 --- a/sk/guide/behind-proxies.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -layout: page -title: Express za proxy -menu: guide -lang: sk ---- - - -# Express za proxy - -Ak chcete, aby vaša Express aplikácia bežala za proxy, nastavte (pomocou [app.set()](/{{ page.lang }}/4x/api.html#app.set)) aplikačnú premennú `trust proxy` na jednu z hodnôt z nasledujúcej tabuľky. - -
      -Aplikácia bude bežať i v prípade, ak aplikačná premenná `trust proxy` nie je nastavená. Aplikácia však nesprávne zaregistruje IP adresu proxy, ako klientskú IP adresu dokým `trust proxy` nebude nastavené. -
      - - - - - - - - - - - - - - - - - - - - - -
      TypHodnota
      Boolean -Ak je `true`, IP addresa klienta bude chápaná ako left-most entry v `X-Forwarded-*` hlavičke. - -Ak je `false`, aplikácia sa chápe, ako priamo vystavená na Internet a klientská IP adresa je odvodená z `req.connection.remoteAddress`. Toto je defaultné nastavenie. -
      IP addresses -IP adresa, subnet, alebo pole IP adries a subnet-ov (podsietí), ktorým má aplikácia dôverovať. Nasledujúci zoznam zobrazuje predkonfigurované názvy subnet-ov: - -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` - -IP adresy môžete nastaviť ktorýmkoľvek z nasledujúcich spôsobov: - -
      -app.set('trust proxy', 'loopback'); // specify a single subnet
      -app.set('trust proxy', 'loopback, 123.123.123.123'); // specify a subnet and an address
      -app.set('trust proxy', 'loopback, linklocal, uniquelocal'); // specify multiple subnets as CSV
      -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); // specify multiple subnets as an array
      -
      - -Pri zadaní IP adresy alebo subnet-ov, sú tieto vylúčené z procesu vyhodnocovania a nedôveryhodná IP adresa najbližsie k aplikačnému serveru je vyhodnotená ako IP adresa klienta. -
      Number -Doveruj n-tému hop-u od front-facing proxy servera ako klient. -
      Function -Vlastná implementácia dôveryhodnosti. Použite to iba v prípade, ak viete čo robíte. -
      -app.set('trust proxy', function (ip) {
      -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
      -  else return false;
      -});
      -
      -
      - -Nastavením inej ako `false` hodnoty `trust proxy` implikuje tieto tri dôležité zmeny: - -
        -
      • Hodnota [req.hostname](/{{ page.lang }}/api.html#req.hostname) je odvodená od hodnoty nastavenej v `X-Forwarded-Host` hlavičke, ktorá môže byť nastavená klientom alebo proxy. -
      • -
      • Hlavička `X-Forwarded-Proto` môže byť nastavená z reverse proxy aby oznámila aplikácii, či je `https` alebo `http` prípadne nevalidná hodnota. Táto hodnota reflektuje [req.protocol](/{{ page.lang }}/api.html#req.protocol). -
      • -
      • Hodnoty [req.ip](/{{ page.lang }}/api.html#req.ip) a [req.ips](/{{ page.lang }}/api.html#req.ips) sú naplnené zoznamom adries z `X-Forwarded-For`. -
      • -
      - -Nastavenie `trust proxy` je implementované pomocou [proxy-addr](https://www.npmjs.com/package/proxy-addr) modulu. Pre viac informácií si pozrite jeho dokumentáciu. diff --git a/sk/guide/database-integration.md b/sk/guide/database-integration.md deleted file mode 100644 index 5f5e3346d0..0000000000 --- a/sk/guide/database-integration.md +++ /dev/null @@ -1,374 +0,0 @@ ---- -layout: page -title: Integrácia Express s databázou -menu: guide -lang: sk ---- - - -# Integrácia s databázou - -Pridanie schopnosti pripojenia Express aplikácie na databázu je len otázkou načítania správneho Node.js drivera. Tento dokument v stručnosti popisuje možnosti pridania a použitia niektorých z obľúbených Node.js modulov pre pripojenie sa vašej Express aplikácie na databázu: - -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) - -
      -Tieto databázové drivery predstavujú len časť z mnoha ďalších, ktoré sú dostupné. Nájdete ich na [npm](https://www.npmjs.com/) stránke. -
      - - - -## Cassandra - -**Modul**: [cassandra-driver](https://github.com/datastax/nodejs-driver) -**Inštalácia** - -
      -
      -$ npm install cassandra-driver
      -
      -
      - -**Príklad** - -
      -
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      -
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      -
      - - - -## CouchDB - -**Modul**: [nano](https://github.com/dscape/nano) -**Inštalácia** - -
      -
      -$ npm install nano
      -
      -
      - -**Príklad** - -
      -
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      -
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      -  }
      -});
      -
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      -
      - - - -## LevelDB - -**Modul**: [levelup](https://github.com/rvagg/node-levelup) -**Inštalácia** - -
      -
      -$ npm install level levelup leveldown
      -
      -
      - -**Príklad** - -
      -
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      -
      -db.put('name', 'LevelUP', function (err) {
      -
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      -
      -});
      -
      -
      - - - -## MySQL - -**Modul**: [mysql](https://github.com/felixge/node-mysql/) -**Inštalácia** - -
      -
      -$ npm install mysql
      -
      -
      - -**Príklad** - -
      -
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      -
      -connection.connect();
      -
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      -
      -connection.end();
      -
      -
      - - - -## MongoDB - -**Modul**: [mongodb](https://github.com/mongodb/node-mongodb-native) -**Inštalácia** - -
      -
      -$ npm install mongodb
      -
      -
      - -**Príklad** - -
      -
      -var MongoClient = require('mongodb').MongoClient;
      -
      -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
      -  if (err) {
      -    throw err;
      -  }
      -  db.collection('mammals').find().toArray(function(err, result) {
      -    if (err) {
      -      throw err;
      -    }
      -    console.log(result);
      -  });
      -});
      -
      -
      - -If you want an object model driver for MongoDB, look at [Mongoose](https://github.com/LearnBoost/mongoose). - - - -## Neo4j - -**Modul**: [apoc](https://github.com/hacksparrow/apoc) -**Inštalácia** - -
      -
      -$ npm install apoc
      -
      -
      - -**Príklad** - -
      -
      -var apoc = require('apoc');
      -
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      -  }
      -);
      -
      -
      - - - -## PostgreSQL - -**Modul**: [pg-promise](https://github.com/vitaly-t/pg-promise) -**Inštalácia** - -
      -
      -$ npm install pg-promise
      -
      -
      - -**Príklad** - -
      -
      -var pgp = require("pg-promise")(/*options*/);
      -var db = pgp("postgres://username:password@host:port/database");
      -
      -db.one("SELECT $1 AS value", 123)
      -    .then(function (data) {
      -        console.log("DATA:", data.value);
      -    })
      -    .catch(function (error) {
      -        console.log("ERROR:", error);
      -    });
      -
      -
      - - - -## Redis - -**Modul**: [redis](https://github.com/mranney/node_redis) -**Inštalácia** - -
      -
      -$ npm install redis
      -
      -
      - -**Príklad** - -
      -
      -var client = require('redis').createClient();
      -
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      -
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      -
      -client.hkeys('hash key', function (err, replies) {
      -
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      -
      -  client.quit();
      -
      -});
      -
      -
      - - - -## SQLite - -**Modul**: [sqlite3](https://github.com/mapbox/node-sqlite3) -**Inštalácia** - -
      -
      -$ npm install sqlite3
      -
      -
      - -**Príklad** - -
      -
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      -
      -db.serialize(function() {
      -
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      -
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      -  }
      -
      -  stmt.finalize();
      -
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      -
      -db.close();
      -
      -
      - - - -## ElasticSearch - -**Modul**: [elasticsearch](https://github.com/elastic/elasticsearch-js) -**Inštalácia** - -
      -
      -$ npm install elasticsearch
      -
      -
      - -**Príklad** - -
      -
      -var elasticsearch = require('elasticsearch');
      -var client = elasticsearch.Client({
      -  host: 'localhost:9200'
      -});
      -
      -client.search({
      -  index: 'books',
      -  type: 'book',
      -  body: {
      -    query: {
      -      multi_match: {
      -        query: 'express js',
      -        fields: ['title', 'description']
      -      }
      -    }
      -  }
      -}).then(function(response) {
      -  var hits = response.hits.hits;
      -}, function(error) {
      -  console.trace(error.message);
      -});
      -
      -
      diff --git a/sk/guide/debugging.md b/sk/guide/debugging.md deleted file mode 100644 index 01bd584673..0000000000 --- a/sk/guide/debugging.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -layout: page -title: Debuggovanie Express -menu: guide -lang: sk ---- - - -# Debuggovanie Express - -Express interne používa k logovaniu informácií ohľadom route matchingu, použitých middleware funkciách, aplikačného módu a toku request response cyklu modul [debug](https://www.npmjs.com/package/debug). - -
      -`debug` je ako rozšírena verzia `console.log`, ale narozdiel od `console.log`, nemusíte zakomentovávať volania `debug` v produkčnom kóde. Logovanie je vypnuté defaultne a je možné ho zapnúť použitím `DEBUG` environment premennej. -
      - -Ak chcete vidieť všetky interné logy Express-u, nastavte pri spúštaní vašej aplikácie environment premennú `DEBUG` na hodnotu -`express:*`. - -
      -
      -$ DEBUG=express:* node index.js
      -
      -
      - -Na Windows-e použite nasledujúci príkaz. - -
      -
      -> set DEBUG=express:* & node index.js
      -
      -
      - -Spustením tohto príkazu v prípade defaultnej aplikácie vygenerovanej pomocou [express generátora](/{{ page.lang }}/starter/generator.html) vypíše nasledujúci výstup: - -
      -
      -$ 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 / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -
      -
      - -Následne, keď aplikácia odchytí request, uvidíte nasledujúce logy špecifikované v Express kóde: - -
      -
      -  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
      -
      -
      - -Ak chcete vidieť iba logy z router implementácie, nastavte hodnotu premennej `DEBUG` na `express:router`. Podobne, ak chcete vidieť iba logy z implementácie aplikácie, nastavte hodnotu premennej `DEBUG` na `express:application` atď. - -## Aplikácie vygenerované príkazom `express` - -Aplikácia vygenerovaná príkazom `express` taktiež používa modul `debug` a jej debug namespace je dostupný pod názvom aplikácie. - -Pomocou nasledujúceho príkazu, dokážete povoliť debug výpisy pre aplikáciu vygenerovanú pomocou `$ express sample-app` takto: - -
      -
      -$ DEBUG=sample-app:* node ./bin/www
      -
      -
      - -Pomocou čiarkou oddeleného zoznamu názvov môžete špecifikovať viac ako jeden debug namespace: - -
      -
      -$ DEBUG=http,mail,express:* node index.js
      -
      -
      - -Pre viac informácií ohľadom `debug` modulu si pozrite [debug](https://www.npmjs.com/package/debug). diff --git a/sk/guide/error-handling.md b/sk/guide/error-handling.md deleted file mode 100644 index cade1eb4d3..0000000000 --- a/sk/guide/error-handling.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -layout: page -title: Error handling v Express-e -menu: guide -lang: sk ---- - - -# Error handling - -Middleware funkcie pre error-handling sa definujú rovnako, ako ostatné middleware funkcie s jediným rozdielom a to, že majú štyri argumenty namiesto troch: -`(err, req, res, next)`. Napr.: - -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      - -Error-handling middleware zadefinujte ako posledný, za ostatnými `app.use()` a route definíciami, napr.: - -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      -  // logic
      -});
      -
      -
      - -Návratové hodnoty predávané medzi jednotlivými middleware funkciami môžu byť v ľubovoľnom formáte, ako napr. stránka s HTML errorom, jednoduchá message, či JSON string. - -Z dôvodu lepšej organizácie kódu je možné zadefinovať niekoľko error-handling middleware funkcií, podobne ako je tomu so štandardnými middleware funkciami. -Napr., ak chcete zadefinovať error-handling pre `XHR` volania a pre tie ostatné, môžete použiť nasledujúci príklad: - -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      -
      - -V nasledujúcom príklade `logErrors` sú všetky errory vypísané na `stderr`, napr.: - -
      -
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      -
      - -V nasledujúcom príklade je `clientErrorHandler` zadefinovaný tak, aby XHR errory boli explicitne odchytené; tie ostatné sa nespracovávajú a ich spracovanie je ponechané nasledujúcej middleware funkcii v poradí: - -
      -
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      -  } else {
      -    next(err);
      -  }
      -}
      -
      -
      - -Finálna "catch-all" `errorHandler` funkcia môže byť implementovaná takto: - -
      -
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      - -Ak do funkcie `next()` predáte čokoľvek (okrem stringu `'route'`), Express bude považovať toto volanie ako error a automaticky preskočí všetky zostávajúce non-error middleware funkcie. Ak potrebujete tento error spracovať špeciálne, budete musieť vytvoriť error-handling route, ako je popísane v ďalšej sekcii. - -Ak váš route handler obsahuje viacero callback funkcií, môžete k preskočeniu na ďalší route handler v poradí použiť parameter `route`. Napr.: - -
      -
      -app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      -
      -      // continue handling this request
      -      next('route');
      -    }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      -
      - -V tomto príklade bude `getPaidContent` handler preskočený, ale ďalšie zostávajúce `app` handlery pre `/a_route_behind_paywall` budú vykonané. - -
      -Volania `next()` a `next(err)` hovoria, že aktuálny handler dokončil svoju úlohu príp. v akom stave. Volanie `next(err)` zabezpeči preskočenie všetkých zostávajúcich handlerov v poradí okrem tých, ktoré slúžia na spracovanie errorov, ako je popísané vyššie. -
      - -## Defaultný Error Handler - -Express obsahuje vstavaný error handler, ktorý sa stará o všetky errory, aké sa môžu v aplikácii vyskytnúť. Táto defaultná error-handling middleware funkcia je pridaná na koniec stacku middleware funkcií. - -Ak funkcii `next()` predáte error a nespracujete ho vlatným error handlerom, error bude spracovaný vstavaným error handlerom, pričom error a jeho stack trace bude vrátený klientovi. Stack trace nie je vrátený v prípade produkčného módu. - -
      -Ak chcete aplikáciu spustiť v produkčnom móde, nastavte environment premennú `NODE_ENV` na `production`. -
      - -V prípade, ak zavoláte `next()` spolu s errorom potom, ako ste už začali vypisovať response (napr. ak nastane error počas streamovania dát klientovi), vstavaný error handler ukončí spojenie s klientom a request spadne. - -V prípade, ak máte zadefinovaný vlastný erorr handler a budete chcieť delegovať defaultný error handling mechanizmus na Express, v prípade ak už nejaké dáta boli odoslané klientovi, môžete vykonať nasledovné: - -
      -
      -function errorHandler(err, req, res, next) {
      -  if (res.headersSent) {
      -    return next(err);
      -  }
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      diff --git a/sk/guide/migrating-4.md b/sk/guide/migrating-4.md deleted file mode 100644 index 985b9ed6b4..0000000000 --- a/sk/guide/migrating-4.md +++ /dev/null @@ -1,596 +0,0 @@ ---- -layout: page -title: Prechod na Express 4 -menu: guide -lang: sk ---- - - -# Prechod na Express 4 - -

      Overview

      - -Express 4 prináša zlomové zmeny oproti Express 3. To znamená, že existujúce Express 3 aplikácie nebudú fungovať po update verzie Express a jej dependencií. - -Tento článok pokrýva: - - - -

      Zmeny v Express 4

      - -Express 4 prináša niekoĺko podstatných zmien: - - - -Pozrite sa taktiež na: - -* [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) - -

      -Zmeny Express jadra a middleware systému -

      - -Express 4 už nie je závislý na Connect a z jeho jadra boli odstránené všetky vstavané middleware funkcie, okrem `express.static` funkcie. To znamená, že Express je teraz nezávislým routing a middleware webovým frameworkom a taktiež verzionovanie Express a jeho releasy nie sú ovplyvnené updatami middlewarov. - -Terazm bez vstavaných middlewarov, musíte explicitne pridať všetky middleware funkcie, ktoré vaša aplikácia potrebuje k svojmu fungovaniu. Jednoducho pokračujte podľa nasledujúcich krokov: - -1. Nainštalujte požadovaný modul: `npm install --save ` -2. Pridajte vo vašej aplikácii require na daný modul: `require('module-name')` -3. Použite modul podľa jeho dokumentácie: `app.use( ... )` - -Nasledujúca tabuľka obsahuje zoznam Express 3 middlewarov a ich varianty v Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Express 3Express 4
      express.bodyParserbody-parser + -multer
      express.compresscompression
      express.cookieSessioncookie-session
      express.cookieParsercookie-parser
      express.loggermorgan
      express.sessionexpress-session
      express.faviconserve-favicon
      express.responseTimeresponse-time
      express.errorHandlererrorhandler
      express.methodOverridemethod-override
      express.timeoutconnect-timeout
      express.vhostvhost
      express.csrfcsurf
      express.directoryserve-index
      express.staticserve-static
      - -Tu je [kompletný zoznam](https://github.com/senchalabs/connect#middleware) Express 4 middlewarov. - -Vo väčšine prípadov môžete jednoducho nahradiť starý Express 3 middleware jeho Express 4 variantou. Pre viac informácií si pozrite dokumentáciu daného modulu na Github-e. - -

      app.use príjma parameter

      - -Vo verzii 4 môžete použiť voliteľný parameter k definovaniu path-u, kedy sa má middleware funkcia načítať a následne prečítať hodnotu parametra z route handlera. -Napr.: - -
      -
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -});
      -
      -
      -

      -Routing systém -

      - -Aplikácia odteraz explicitne načíta routing middleware, takže už sa viac nemusíte starať o to, v akom poradí bude ktorý middleware načítaný s ohľadom na `router` middleware. - -Spôsob, akým definujete route sa nezmenil, ale samotný routing systém má dve nové features k jeho lepšej organizácii: - -{: .doclist } -* Nová metóda, `app.route()` slúži na vytvorenie zreťaziteľných route handlerov pre daný route path (cestu). -* Nová trieda, `express.Router`, slúži na vytvorenie modulárnych, pripojiteľných route handlerov. - -

      app.route() metóda

      - -Nová metóda `app.route()` vám umožňuje vytvárať zreťaziteľné route handlery pre daný route path (cestu). Pretože je path (cesta) špecifikovaný na jednom mieste, tvorba takýchto modulárnych routes je užitočná, kedže znižuje redundanciu a možné preklepy. Pre viac informácií ohľadom route sa pozrite na [`Router()` dokumentáciu](/{{ page.lang }}/4x/api.html#router). - -Tu je príklad zreťazených route handlerov definovaných pomocou `app.route()` funkcie. - -
      -
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      - -

      express.Router trieda

      - -Ďalšou novou feature, ktorá napomáha k lepšej organizácii routes, je nová trieda `express.Router`, ktorú môžete použiť k tvorbe modulárnych, pripojiteľných route handlerov. `Router` inštancia je kompletný middleware routing systém; z tohto dôvodu je často označovaná aj ako "mini-app". - -Nasledujúci príklad vytvára router ako modul, načítava v ňom middleware, definuje niekoľko routes a pripája tento router na path v hlavnej aplikácii. - -Napr., vytvorte v priečinku vašej aplikácie router súbor s názvom `birds.js` s takýmto obsahom: - -
      -
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      -
      -module.exports = router;
      -
      -
      - -Potom tento router načítajte vo vašej aplikácii: - -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      - -Aplikácia bude odteraz schopná obslúžiť requesty na path-och `/birds` a -`/birds/about` a zavolá `timeLog` middleware, ktorý je špecifický pre tento route. - -

      -Ostatné zmeny -

      - -Nasledujúca tabuľka obsahuje zoznam drobných, ale dôležitých zmien v Express 4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ObjektPopis
      Node.jsExpress 4 si vyžaduje Node.js 0.10.x a vyšší a už nepodporuje Node.js 0.8.x.
      -`http.createServer()` - -`http` modul už nie je potrebný, pokiaľ s ním nepotrebujete priamo pracovať (socket.io/SPDY/HTTPS). Aplikáciu dokážete naštartovať pomocou `app.listen()` funkcie. -
      -`app.configure()` - -Funkcia `app.configure()` bola odstránená. Pre detekciu environment nastavení a nastavenia aplikácie použite `process.env.NODE_ENV` alebo funkciu -`app.get('env')`. -
      -`json spaces` - -Aplikačná property `json spaces` je defaultne v Express 4 vypnutá. -
      -`req.accepted()` - -Používajte `req.accepts()`, `req.acceptsEncodings()`, -`req.acceptsCharsets()` a `req.acceptsLanguages()`. -
      -`res.location()` - -Už viac nevyhodnocuje relatívne URLky. -
      -`req.params` - -Bolo pôvodne pole, teraz je objektom. -
      -`res.locals` - -Bola pôvodne funkcia, teraz je objekt. -
      -`res.headerSent` - -Zmenená na `res.headersSent`. -
      -`app.route` - -Teraz dostupná ako `app.mountpath`. -
      -`res.on('header')` - -Zmazané. -
      -`res.charset` - -Zmazané. -
      -`res.setHeader('Set-Cookie', val)` - -Funkcionalita je odteraz obmedzená na nastavenie základnej hodnoty cookie. Pre pridanú funkcionalitu používajte `res.cookie()`. -
      - -

      Príklad migrácie aplikácie

      - -Tu je príklad migrácie Express 3 aplikácie na Express 4. -Súbory, ktoré vás môžu zaujímať sú `app.js` a `package.json`. - -

      -Applikácia vo verzii 3 -

      - -

      app.js

      - -Majme takúto Express v.3 aplikáciu s takýmto `app.js` súborom: - -
      -
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -// development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      -}
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      - -

      package.json

      - -Sprievodný `package.json` pre verziu 3 by vyzeral nejak takto: - -
      -
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "express": "3.12.0",
      -    "pug": "*"
      -  }
      -}
      -
      -
      - -

      -Proces -

      - -Proces migrácie začnite nainštalovaním všetkých potrebných middlewarov pre vašu Express 4 aplikáciu a updatom Express a Pug na ich prislúchajúce najnovšie verzie nasledujúcim príkazom: - -
      -
      -$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      -
      - -V `app.js` vykonajte tieto zmeny: - -1. Vstavané Express middleware funkcie `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` a - `express.errorHandler` už nie sú dostupné na - `express` objekte. Musíte nainštalovať a načítať ich prislúchajúce alternatívy v aplikácii manuálne. - -2. Už viac nepotrebujete načítať `app.router` funkciu. - Nieje validným Express 4 app objektom, preto zmažte nasledujúci kód - `app.use(app.router);`. - -3. Uistite sa, že middleware funkcie sú načítané v správnom poradí - načítajte `errorHandler` až po načítaní app routes. - -

      Aplikácia vo verzii 4

      - -

      package.json

      - -Spustením kódu vyššie, `npm` príkaz updatne `package.json` nasledovne: - -
      -
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "body-parser": "^1.5.2",
      -    "errorhandler": "^1.1.1",
      -    "express": "^4.8.0",
      -    "express-session": "^1.7.2",
      -    "pug": "^2.0.0-beta6",
      -    "method-override": "^2.1.2",
      -    "morgan": "^1.2.2",
      -    "multer": "^0.1.3",
      -    "serve-favicon": "^2.0.1"
      -  }
      -}
      -
      -
      - -

      app.js

      - -Potom zmažte nesprávny kód, načítajte potrebné middlewary a vykonajte ďalšie potrebné zmeny. Súbor `app.js` bude potom vyzerať takto: - -
      -
      -var http = require('http');
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      -
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -// error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      -}
      -
      -var server = http.createServer(app);
      -server.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      - -
      -Pokiaľ nepotrebujete priamo pracovať s `http` modulom (socket.io/SPDY/HTTPS), nie je nutné ho načítať a aplikáciu môžete jednoducho naštartovať týmto spôsobom: -
      -app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      - -

      Spustite aplikáciu

      - -Proces migrácie je kompletný a aplikácia je teraz Express 4 aplikáciou. Pre overenie spustite aplikáciu pomocou nasledujúceho príkazu: - -
      -
      -$ node .
      -
      -
      - -Načítajte v prehliadači [http://localhost:3000](http://localhost:3000) - a pozrite si domovskú stránku aplikácie vyrendrovanú pomocou Express 4. - -

      Prechod na Express 4 app generátor

      - -Tento command-line tool slúžiaci na generovanie Express aplikácie je stále - `express`, ale k tomu, aby ste vykonali upgrade na novú verziu musíte najprv pôvodný Express 3 app generátor odinštalovať a potom nainštalovať nový `express-generator`. - -

      Inštalácia

      - -Ak už máte Express 3 app generátor na vašom systéme nainštalovaný, musíte ho najskôr odinštalovať: - -
      -
      -$ npm uninstall -g express
      -
      -
      -V závislosti od toho, ako sú nakonfigurované vaše oprávnenia k súborom a priečinkom, -môže byť potrebné spustiť tento príkaz pomocou `sudo`. - -Teraz nainštalujte nový generátor: - -
      -
      -$ npm install -g express-generator
      -
      -
      - -V závislosti od toho, ako sú nakonfigurované vaše oprávnenia k súborom a priečinkom, -môže byť potrebné spustiť tento príkaz pomocou `sudo`. - -Teraz je príkaz `express` aktualizovaný na vašom systéme na -Express 4 generátor. - -

      Zmeny app generátora

      - -Prepínače a použitia príkazu zostali prevažne rovnaké, okrem nasledujúcich výnimiek: - -{: .doclist } -* Odstránený prepínač `--sessions`. -* Odstránený prepínač `--jshtml`. -* Pridaný prepínač `--hogan` pre podporu [Hogan.js](http://twitter.github.io/hogan.js/). - -

      Príklad

      - -K vytvoreniu Express 4 aplikácie spustite nasledujúci príkaz: - -
      -
      -$ express app4
      -
      -
      - -Ak sa pozriete na obsah `app4/app.js` súboru, všimnete si, že všetky middleware funkcie (okrem `express.static`), ktoré sú potrebné pre aplikáciu, sú načítané ako samostatné, nezávislé moduly a `router` middleware už nie je v aplikácii explicitne načítaný. - -Taktiež si všimnite, že súbor `app.js` je odteraz Node.js modulom, v porovnaní so standalone aplikáciou vygenerovanou starým generátorom. - -Po nainštalovaní závislostí spustite aplikáciu pomocou nasledujúceho príkazu: - -
      -
      -$ npm start
      -
      -
      - -Ak sa pozriete na npm start skript v `package.json` súbore, -všimnete si, že aktuálny príkaz pre spustenie aplikácie je -`node ./bin/www`, ktorý bol v Express 3 pôvodne `node app.js`. - -Pretože súbor `app.js`, ktorý bol vygenerovaný Express 4 generátorom je odteraz Node.js modul, -už nemôže byť viacej spustený nezávisle ako aplikácia (pokiaľ nezmeníte kód). -Modul musí byť načítaný a spustený ako Node.js súbor. Node.js súbor je v tomto prípade`./bin/www`. - -Priečinok `bin` ani bezpríponový súbor `www` nie sú povinné k vytvoreniu ani spusteniu aplikácie. -Sú len návrhom vyrobeným generátorom, takže ich môzete zmeniť podľa vašich potrieb. - -Ak sa chcete zbaviť `www` priečinka a ponechať to v starom "Express 3 formáte", -zmažte riadok `module.exports = app;` na konci `app.js` súboru a namiesto neho vložte nasledujúci kód: - -
      -
      -app.set('port', process.env.PORT || 3000);
      -
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      -
      - -Uistite sa, že ste načítali `debug` modul, v hornej časti vášho `app.js` súboru, použitím nasledujúceho kódu: - -
      -
      -var debug = require('debug')('app4');
      -
      -
      - -Ďalej zmeňte v súbore `package.json` riadok `"start": "node ./bin/www"` na `"start": "node app.js"`. - -Týmto ste presunuli funkcionalitu `./bin/www` späť do `app.js`. Táto zmena sa neodporúča, ale toto cvičenie vám pomôže porozumieť ako `./bin/www` súbor pracuje a prečo `app.js` už viac nie je možné samostatne spustiť. diff --git a/sk/guide/migrating-5.md b/sk/guide/migrating-5.md deleted file mode 100644 index 5c79d8caae..0000000000 --- a/sk/guide/migrating-5.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -layout: page -title: Prechod na Express 5 -menu: guide -lang: sk ---- - - -# Prechod na Express 5 - -

      Overview

      - -Hoci je Express 5.0 ešte len v alpha release verzii, tu je náhľad zmien, ktoré budú v tomto release a návod ako zmigrovať vašu aplikáciu z verzie Express 4 na Express 5. - -Express 5 sa od Express 4 veľmi nelíši: Zmeny v API nie sú tak veľké, ako v pŕipade prechodu z verzie 3.0 na 4.0. Hoci základné API zostáva rovnaké, sú tam niektoré podstatné zmeny; inými slovami, existujúca Express 4 aplikácia nemusí po upgrade na Express 5 fungovať. - -Pre nainštalovanie poslednej alpha verzie Express 5, spustite v hlavnom priečinku vašej aplikácie nasledujúci príkaz: - -
      -
      -$ npm install express@5.0.0-alpha.2 --save
      -
      -
      - -Potom môžete spustiť vaše automatizované testy, aby ste videli čo padá a opravili tieto problémy podľa informácií nižšie. Potom, ako identifikujete padajúce testy, spustite aplikáciu, aby ste videli aké errory nastávajú. Okamžite zistíte, či aplikácia používa niektorú z metód, alebo properties, ktoré nie sú podporované. - -

      Zmeny v Express 5

      - -Tu je zoznam zmien (týkajúcich sa verzie alpha 2 release), ktoré vás, ako používateľa Express aplikácie, môžu ovplyvniť. -Pozrite sa na zoznam [pull request-ov](https://github.com/expressjs/express/pull/2237) všetkých plánovaných zmien. - -**Odstránené metódy a properties** - - - -**Zmenené** - - - -**Vylepšenia** - - - -

      Odstránené metódy a properties

      - -Ak používate niektorú z nasledujúcich metód, alebo properties vo vašej aplikácii, aplikácia bude padať. Preto budete musieť vykonať zmeny vo vašej aplikácii, aby fungovala aj po update na veziu 5. - -

      app.del()

      - -Express 5 už viac nepodporuje `app.del()` funkciu. V prípade použitia tejto metódy nastane error. Namiesto nej použite pre zaregistrovanie HTTP DELETE route-ov funkciu `app.delete()`. - -Pôvodne bola funkcia `del` používaná namiesto `delete`, pretože `delete` je v JavaScript-e rezervované kľúčové slovo. Avšak od ECMAScript 6, `delete` a ďalšie rezervované klúčové slová môžu byť bezpečne použité ako názov property. - -

      app.param(fn)

      - -Zápis `app.param(fn)` bol používaný pre modifikovanie správania `app.param(name, fn)` funkcie. Tento zápis bol označený ako deprecated už od v4.11.0 a Express 5 ho už nepodporuje vôbec. - -

      Pluralizované názvy metód

      - -Nasledujúce názvy metód boli pluralizované. Používanie pôvodných názvov v Express 4 viedlo k deprecation warning-om. Express 5 ich už nepodporuje vôbec: - -`req.acceptsCharset()` bola nahradená za `req.acceptsCharsets()`. - -`req.acceptsEncoding()` bola nahradená za `req.acceptsEncodings()`. - -`req.acceptsLanguage()` bola nahradená za `req.acceptsLanguages()`. - -

      Dvojbodka (:) na začiatku v name argumente volania app.param(name, fn)

      - -Dvojbodka (:) na začiatku v name argumente volania `app.param(name, fn)` funkcie je pozostatkom z Express 3 a v záujme spätnej kompatibility ju Express 4 podporoval s deprecation warning-om. Express 5 ju bude ticho ignorovať a používa name parameter bez prefixu počiatočnej dvojbodky. - -Táto zmena by nemala ovplyvniť váš kód v prípade, ak postupujete podľa dokumentácie k Express 4 [app.param](/{{ page.lang }}/4x/api.html#app.param), kde sa žiadna počiatočná dvojbodka už nespomína. - -

      req.param(name)

      - -Táto potenciálne mätúca a nebezpečná metóda získania dát z formulára bola odstránená. Odteraz budete musieť pozrieť na konkrétny názov parametra v `req.params`, `req.body`, alebo `req.query` objektu. - -

      res.json(obj, status)

      - -Express 5 už viac nepodporuje zápis `res.json(obj, status)`. Namiesto toho nastavte status a zreťazte ho s `res.json()` volaním, takto `res.status(status).json(obj)`. - -

      res.jsonp(obj, status)

      - -Express 5 už viac nepodporuje zápis `res.jsonp(obj, status)`. Namiesto toho nastavte status a zreťazte ho s `res.jsonp()` volaním, takto: `res.status(status).jsonp(obj)`. - -

      res.send(body, status)

      - -Express 5 už viac nepodporuje zápis `res.send(obj, status)`. Namiesto toho nastavte status a zreťazte ho s `res.send()` volaním, takto: `res.status(status).send(obj)`. - -

      res.send(status)

      - -Express 5 už viac nepodporuje zápis res.send(status), kde _`status`_ je číslo. Namiesto toho použite funkciu `res.sendStatus(statusCode)`, ktorá nastavuje status kód HTTP response hlavičky a odošle jej textovú verziu spolu s: "Not Found", "Internal Server Error", a podobne. -Ak potrebujete poslať pomocou funkcie `res.send()` číslo, uveďte ho v úvodzovkách, aby ste ho pretypovali na string, takže to Express nevyhodnotí ako pokus o nepodporovaný zápis. - -

      res.sendfile()

      - -Funkcia `res.sendfile()` bola v Express 5 nahradená camel-cased verziou `res.sendFile()`. - -

      Zmenené

      - -

      app.router

      - -Objekt `app.router`, ktorý bol v Express 4 odstránený, bol v Express 5 vrátený späť. V novej verzii je tento objekt len referenciou na základný Express router, kým v Express 3 ho bolo nutné explicitne načítať. - -

      req.host

      - -Funkcia `req.host` v Express 4 nekorektne odstraňovala číslo portu, ak bol definovaný. V Express 5 je číslo portu ponechané. - -

      req.query

      - -V Express 4.7 a od Express 5, query parser parameter akceptuje hodnotu `false` pre zakázanie parsovania query stringu v prípade, ak chcete použiť vlastnú funkciu na parsovanie. - -

      Improvements

      - -

      res.render()

      - -Táto metóda si odteraz vynucuje asynchrónne správanie všetkých view engine-ov, čím predchádza chybám spôsobenými view engine-ami, ktorých implementácia je synchrónna a porušuje doporučený interface. diff --git a/sk/guide/routing.md b/sk/guide/routing.md deleted file mode 100644 index d3726b7f6f..0000000000 --- a/sk/guide/routing.md +++ /dev/null @@ -1,335 +0,0 @@ ---- -layout: page -title: Express routing -menu: guide -lang: sk ---- - -# Routing - -_Routing_ definuje tzv. koncové body aplikácie (URI) a spôsob, akým odpovedajú na requesty klientov. -Základné informácie o routing-u sa dozviete v sekcii [Základný routing](/{{ page.lang }}/starter/basic-routing.html). - -Tu je príklad, ako zadefinovať základný routing. - -
      -
      -var express = require('express');
      -var app = express();
      -
      -// respond with "hello world" when a GET request is made to the homepage
      -app.get('/', function(req, res) {
      -  res.send('hello world');
      -});
      -
      -
      - -

      Route metódy

      - -Route metóda je odvodená z niektorej HTTP metódy a pripojená k inštancii `express` triedy. - -Nasledujúci kód je ukážkou definície routing-u pre GET a POST metódy hlavnej stránky aplikácie. - -
      -
      -// GET method route
      -app.get('/', function (req, res) {
      -  res.send('GET request to the homepage');
      -});
      -
      -// POST method route
      -app.post('/', function (req, res) {
      -  res.send('POST request to the homepage');
      -});
      -
      -
      - -Express podporuje tieto routing metódy korešpondujúce k HTTP metódam: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search` a `connect`. - -
      -Tie routing metódy, ktorých názov nie je validným názvom pre JavaScript premennú, zapisujte pomocou zátvorkovej notácie. Napr.: -`app['m-search']('/', function ...` -
      - -Existuje špeciálna routing metóda `app.all()`, ktorá nie je odvodená zo žiadnej HTTP metódy. Táto metóda sa používa ako middleware funkcia pre konkrétny koncový bod a všetky jej request metódy. - -Na nasledujúcom príklade je ukážka handler funkcie, ktorá bude vykonaná pri requeste na "/secret" bez ohľadu nato, či bude použitá GET, POST, PUT, DELETE, alebo akákoľvek iná HTTP request metóda podporovaná [http modulom](https://nodejs.org/api/http.html#http_http_methods). - -
      -
      -app.all('/secret', function (req, res, next) {
      -  console.log('Accessing the secret section ...');
      -  next(); // pass control to the next handler
      -});
      -
      -
      - -

      Route cesty

      - -Route cesty (route paths) definujú v kombinácii s request metódami koncové body, voči ktorým je možné vykonať request. Route cesty je možné definovať ako stringy, stringové patterny, alebo ako regulárne výrazy. - -
      - Express používa pre spárovanie (matching) route cesty npm modul [path-to-regexp](https://www.npmjs.com/package/path-to-regexp); pre všetky možnosti definície route ciest si pozrite dokumentáciu k path-to-regexp modulu. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) je užitočný nástroj pre testovanie základných Express route ciest, hoci nepodporuje pattern matching. -
      - -
      -Query stringy nie sú súčasťou route ciest. -
      - -Tu je niekoľko príkladov route ciest na základe stringov. - -Táto route cesta sa spáruje s requestom na hlavný route, `/`. - -
      -
      -app.get('/', function (req, res) {
      -  res.send('root');
      -});
      -
      -
      - -Táto route cesta sa spáruje s requestom na `/about`. - -
      -
      -app.get('/about', function (req, res) {
      -  res.send('about');
      -});
      -
      -
      - -Táto route cesta sa spáruje s requestom na `/random.text`. - -
      -
      -app.get('/random.text', function (req, res) {
      -  res.send('random.text');
      -});
      -
      -
      - -Tu je niekoľko príkladov route ciest na základe stringových patternov. - -Táto route cesta sa spáruje s requestom `acd` a `abcd`. - -
      -
      -app.get('/ab?cd', function(req, res) {
      -  res.send('ab?cd');
      -});
      -
      -
      - -Táto route cesta sa spáruje s requestom `abcd`, `abbcd`, `abbbcd`, atď. - -
      -
      -app.get('/ab+cd', function(req, res) {
      -  res.send('ab+cd');
      -});
      -
      -
      - -Táto route cesta sa spáruje s requestom `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, atď. - -
      -
      -app.get('/ab*cd', function(req, res) {
      -  res.send('ab*cd');
      -});
      -
      -
      - -Táto route cesta sa spáruje s requestom `/abe` a `/abcde`. - -
      -
      -app.get('/ab(cd)?e', function(req, res) {
      - res.send('ab(cd)?e');
      -});
      -
      -
      - -
      -Znaky ?, +, *, a () sú podmnožinami ich regulárnych výrazov. Pomlčka (-) a bodka (.) sa reprezentujú ako text. -
      - -Príklady definícií route ciest s využitím regulárnych výrazov: - -Táto route cesta bude spárovaná s každým requestom obsahujúcim "a". - -
      -
      -app.get(/a/, function(req, res) {
      -  res.send('/a/');
      -});
      -
      -
      - -Táto route cesta sa spáruje s requestom `butterfly` a `dragonfly`, ale nie `butterflyman`, `dragonfly man`, atď. - -
      -
      -app.get(/.*fly$/, function(req, res) {
      -  res.send('/.*fly$/');
      -});
      -
      -
      - -

      Route handler

      - -Pre spracovanie requestu je možné zadefinovať viacero callback funkcií správajúcich sa ako [middleware](/{{ page.lang }}/guide/using-middleware.html). Jedinou výnimkou je, že tieto callback-y môžu samé vyvolať `next('route')` a tak vynechať zostávajúce definície callback-ov. Tento mechanizmus môžete použiť k stanoveniu podmienok spracovania a následne potom "odovzdať" riadenie ďalším route definíciám v prípade, že nie je dôvod ho ďalej spracovávať v aktuálnej route definícii. - -Route handler môže byť definovaný ako funkcia, pole funkcií či kombinácia oboch, ako na nasledujúcich príkladoch. - -Jedna callback funkcia pre obsluhu spracovania: - -
      -
      -app.get('/example/a', function (req, res) {
      -  res.send('Hello from A!');
      -});
      -
      -
      - -Môžete použiť aj viac ako jednu callback funkciu (nezabudnite špecifikovať `next` objekt). Napríklad: - -
      -
      -app.get('/example/b', function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from B!');
      -});
      -
      -
      - -Môžete použiť aj pole callback funkcií. Napr.: - -
      -
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      -}
      -
      -var cb2 = function (req, res) {
      -  res.send('Hello from C!');
      -}
      -
      -app.get('/example/c', [cb0, cb1, cb2]);
      -
      -
      - -Tu je ukážka kombinácia nezávislých funkcií a poľa funkcií: - -
      -
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      -}
      -
      -app.get('/example/d', [cb0, cb1], function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from D!');
      -});
      -
      -
      - -

      Response metódy

      - -Metódy response objektu (`res`) v nasledujúcej tabuľke dokážu odoslať odpoveť klientovi a ukončiť request-response cyklus. Ak žiadna z týchto metód nebude zavolaná z route handler-a, request klienta zostane "visieť" nespracovaný. - -| Method | Description -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Ponúkne súbor na stianutie. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Ukončí proces odpovede. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Odošle odpoveď ako JSON. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Odošle JSON odpoveď s podporou JSONP. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Presmeruje request. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Vyrendruje view template. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Odošle odpoveď rôzneho typu. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Odošle súbor ako octet stream. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Nastaví status kód odpovede a odošle jej textovú reprezentáciu ako telo odpovede. - -

      app.route()

      - -Pomocou `app.route()` dokážete vytvoriť zreťaziteľné route handlery pre konkrétnu route cestu. -Pretože je route cesta špecifikovaná na jednom mieste, tvorba takýchto routes je užitočná a znižuje redundanciu a preklepy. Pre viac informácií o použití route pozrite: [Router() dokumentáciu](/{{ page.lang }}/4x/api.html#router). - -Tu je príklad zreťazenia route handlerov definovaných pomocou `app.route()`. - -
      -
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      - -

      express.Router

      - -Ak chcete vytvoriť modulárne a zreťazitelné route handlery použite `express.Router` triedu. `Router` inštancia je kompletný middleware a routing systém; z tohto dôvodu sa často označuje ako "mini-app". - -Nasledujúci príklad demonštruje vytvorenie router modulu, načítanie middleware funkcie, špecifikuje niekoľko route definícií a ukazuje pripojenie router modulu na cestu (path) v hlavnej aplikácii. - -V priečinku aplikácie vytvorte router súbor nazvaný `birds.js` s takýmto obsahom: - -
      -
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware that is specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      -
      -module.exports = router;
      -
      -
      - -Následne načítajte tento router modul do aplikácie: - -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      - -Aplikácia bude teraz schopná obslúžiť prichádzajúce požiadavky na ceste `/birds` a `/birds/about`, a taktiež vyvolať `timeLog` middleware funkciu, ktorá je špecifická pre tento route. diff --git a/sk/guide/using-middleware.md b/sk/guide/using-middleware.md deleted file mode 100644 index b24dc13ab9..0000000000 --- a/sk/guide/using-middleware.md +++ /dev/null @@ -1,283 +0,0 @@ ---- -layout: page -title: Použitie Express middleware -menu: guide -lang: sk ---- - - -# Použitie middleware - -Express je webový framework s minimálnou vlastnou funkcionalitou: Express aplikácia je v podstate séria volaní middleware funkcií. - -_Middleware_ funkcie sú funkcie, ktoré majú prístup k [request objektu](/4x/api.html#req) (`req`), [response objektu](/4x/api.html#res) (`res`) a nasledujúcej middleware funkcii v request-response cykle aplikácie. Nasledujúca middleware funkcia v poradí je bežne označovaná premennou `next`. - -Middleware funkcie dokážu vykonávať nasledujúce úlohy: - -* Vykonať akýkoľvek kód. -* Vykonať zmeny na request a response objektoch. -* Ukončiť request-response cyklus. -* Zavolať nasledujúcu middleware funkciu v poradí. - -Ak aktuálna middleware funkcia neukončuje request-response cyklus, musí posunúť obsluhu nasledujúcej middleware funkcii vyvolaním `next()`. V opačnom prípade zostane request 'visieť'. - -Express aplikácia môže použiť nasledovné typy middleware funkcií: - - - [Application-level middleware](#middleware.application) - - [Router-level middleware](#middleware.router) - - [Error-handling middleware](#middleware.error-handling) - - [Built-in middleware](#middleware.built-in) - - [Third-party middleware](#middleware.third-party) - -Application-level a router-level middleware môžete načítať s voliteľnou cestou (path-om). -Môžete taktiež načítať skupinu middleware funkcií dohromady, čím vytvoríte sub-stack middleware systém na danej ceste. - -

      Application-level middleware

      - -Pripojte application-level middleware k inštancii [app objektu](/{{ page.lang }}/4x/api.html#app) použitím `app.use()` a `app.METHOD()` funkcií, kde `METHOD` je typicky HTTP metóda requestu, ktorý mddleware funkcia handluje (ako napr. GET, PUT, či POST) zapísaná v lowercase formáte. - -Nasledujúci príklad ukazuje middleware funkciu, ktorá nie je pripojená na žiaden path. Funkcia bude vykonaná vždy, keď aplikácia obdrží request. - -
      -
      -var app = express();
      -
      -app.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -
      - -Nasledujúci príklad ukazuje middleware funkciu pripojenú na ceste `/user/:id`. Funkcia bude vykonaná vždy, keď aplikácia održí request na `/user/:id` a to bez ohľadu na typ použitej HTTP metódy. - -
      -
      -app.use('/user/:id', function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -
      - -Nasledujúci príklad ukazuje route a jej handler funkciu (middleware systém). Táto funkcia handluje GET requesty na ceste `/user/:id`. - -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  res.send('USER');
      -});
      -
      -
      - -Tu je príklad načítania skupiny middleware funkcií pripojených na konkrétnu cesty. Príklad ilustruje sub-stack middleware, ktorý vypíše info o requeste pre všetky typy HTTP requestov vykonaných na `/user/:id`. - -
      -
      -app.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -
      - -Route handlery dovoľujú definovať viacero route-ov pre jednu cestu. Nasledujúci príklad definuje dva routy pre GET requesty na ceste `/user/:id`. Definovanie druhého route nespôsobí žiadne problémy, ale ani sa nikdy nezavolá, pretože prvý route ukončí request-response cyklus. - -Tento príklad zobrazuje middleware sub-stack ktorý handluje GET requesty na ceste `/user/:id`. - -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -}, function (req, res, next) {
      -  res.send('User Info');
      -});
      -
      -// handler for the /user/:id path, which prints the user ID
      -app.get('/user/:id', function (req, res, next) {
      -  res.end(req.params.id);
      -});
      -
      -
      - -Ak chcete preskočiť zostávajúce middleware funkcie z router middleware stack-u, zavolajte `next('route')` čím posuniete obsluhu ďalšiemu route. -**POZNÁMKA**: `next('route')` zafunguje iba v takých middleware funkciách, ktoré boli načítané pomocou `app.METHOD()` alebo `router.METHOD()` funkcií. - -Tento príklad zobrazuje middleware sub-stack, ktorý handluje GET requesty na ceste `/user/:id`. - -
      -
      -app.get('/user/:id', function (req, res, next) {
      -  // if the user ID is 0, skip to the next route
      -  if (req.params.id == 0) next('route');
      -  // otherwise pass the control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for the /user/:id path, which renders a special page
      -app.get('/user/:id', function (req, res, next) {
      -  res.render('special');
      -});
      -
      -
      - -

      Router-level middleware

      - -Router-level middleware funguje rovnakým spôsobom ako application-level middleware, avšak je pripojený k `express.Router()` inštancii. - -
      -
      -var router = express.Router();
      -
      -
      -Router-level middleware načítate pomocou `router.use()` a `router.METHOD()` funkcií. - -Nasledujúci príklad replikuje vyššie zobrazený application-level middleware použitím router-level middlewaru: - -
      -
      -var app = express();
      -var router = express.Router();
      -
      -// a middleware function with no mount path. This code is executed for every request to the router
      -router.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
      -router.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -// a middleware sub-stack that handles GET requests to the /user/:id path
      -router.get('/user/:id', function (req, res, next) {
      -  // if the user ID is 0, skip to the next router
      -  if (req.params.id == 0) next('route');
      -  // otherwise pass control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for the /user/:id path, which renders a special page
      -router.get('/user/:id', function (req, res, next) {
      -  console.log(req.params.id);
      -  res.render('special');
      -});
      -
      -// mount the router on the app
      -app.use('/', router);
      -
      -
      - -

      Error-handling middleware

      - -
      -Error-handling middleware príjma vždy _štyri_ argumenty. Aby bolo možné identifikovať error-handling middleware funkciu, musíte jej definovať vždy štyri argumenty. Musíte ho definovať aj v situácii, kedy nepotrebujete použiť `next` objekt, aby ste dodržali dohodnutú signatúru. V opačnom prípade bude `next` objekt interpretovaný ako bežný middleware, ktorý nedokáže handlovať errory. -
      - -Error-handling middleware funkcie sa definujú rovnako ako ostatné middleware funkcie, len majú štyri argumenty namiesto troch, špecificky podľa signatúry `(err, req, res, next)`: - -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      - -Pre viac informácií ohľadom error-handling middlewarov si pozrite sekciu: [Error handling](/{{ page.lang }}/guide/error-handling.html). - -

      Built-in middleware

      - -Express počnúc od verzie 4.x nie je závislý na [Connect](https://github.com/senchalabs/connect) module. Okrem výnimky `express.static`, všetky predošlé middleware funkcie pôvodne obsiahnuté v Express sú teraz samostatné moduly. Zoznam middleware funkcií [si pozrite tu](https://github.com/senchalabs/connect#middleware). - -Jediným vstavaným middlewarom v Express je `express.static` funkcia. Tento middleware je založený na [serve-static](https://github.com/expressjs/serve-static) module a je zodpovedný za servovanie statických assetov ako HTML súbory, obráky atď. - -Signatúra tejto funkcie je: - -
      -
      -express.static(root, [options])
      -
      -
      - -Parameter `root` špecifikuje hlavný adresár z ktorého bude statický obsah servovaný. - -Informácie ohľadom `options` parametra ako i ďalšie detaily ohľadom tohto middleware nájdete tu: [express.static](/sk/4x/api.html#express.static). - -Tu je príklad použitia `express.static` middleware funkcie s rôznou konfiguráciou options objektu: - -
      -
      -var options = {
      -  dotfiles: 'ignore',
      -  etag: false,
      -  extensions: ['htm', 'html'],
      -  index: false,
      -  maxAge: '1d',
      -  redirect: false,
      -  setHeaders: function (res, path, stat) {
      -    res.set('x-timestamp', Date.now());
      -  }
      -}
      -
      -app.use(express.static('public', options));
      -
      -
      - -Môžete nastaviť aj viac ako jeden priečinok so statickým obsahom: - -
      -
      -app.use(express.static('public'));
      -app.use(express.static('uploads'));
      -app.use(express.static('files'));
      -
      -
      - -Pre viac detailov ohľadom `serve-static` funkcie a jej možnostiach si pozrite dokumentáciu k [serve-static](https://github.com/expressjs/serve-static) modulu. - -

      Third-party middleware

      - -V Express aplikácii možete využiť taktiež third-party middleware funkcionalitu. - -Nainštalujte požadovaný Node.js modul a načítajte ho do aplikácie ako aplikačný, či router middleware. - -Nasledujúci príklad demonštruje inštaláciu a načítanie middleware funkcie `cookie-parser` slúžiacej na prácu s cookies. - -
      -
      -$ npm install cookie-parser
      -
      -
      - -
      -
      -var express = require('express');
      -var app = express();
      -var cookieParser = require('cookie-parser');
      -
      -// load the cookie-parsing middleware
      -app.use(cookieParser());
      -
      -
      - -Čiastočný zoznam bežne používaných third-party middleware funkcií pre Express nájdete v sekcii: [Third-party middleware](../resources/middleware.html). diff --git a/sk/guide/using-template-engines.md b/sk/guide/using-template-engines.md deleted file mode 100644 index b374328f98..0000000000 --- a/sk/guide/using-template-engines.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -layout: page -title: Použitie template enginov v Express -menu: guide -lang: sk ---- - - -# Použitie template enginov v Express - -_Template engine_ umožňuje použitie statických template súborov vo vašej aplikácii. Template engine nahradí v runtime premenné aktuálnymi hodnotami a pretransformuje template do HTML súboru poslaného klientovi. -Tento prístup robí návrh HTML stránok jednoduchším. - -Medzi populárne template enginy fungujúce s Express patria [Pug](https://pugjs.org/api/getting-started.html), [Mustache](https://www.npmjs.com/package/mustache) a [EJS](https://www.npmjs.com/package/ejs). -[Express generátor](/{{ page.lang }}/starter/generator.html) požíva ako defaultný Pug, avšak podporuje aj mnohé ďalšie. - -Zoznam podporovaných template enginov nájdete tu: [Template Engines (Express wiki)](https://github.com/expressjs/express/wiki#template-engines). -Pozrite si taktiež [Comparing JavaScript Templating Engines: Jade, Mustache, Dust and More](https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/). - -Aby Express dokázal spracovať a vyrendrovať template súbory, musí aplikácia obsahovať [nasledujúce nastavenia](/{{ page.lang }}/4x/api.html#app.set): - -* `views`, cesta k priečinku, kde sa nachádzajú template súbory. Napr: `app.set('views', './views')`. Defaultne to je priečinok `views` nachádzajúci sa v hlavnom priečinku aplikácie. -* `view engine`, template engine, ktorý chcete použiť. Napr., ak by ste chceli použiť Pug: `app.set('view engine', 'pug')` - -Potom nainštalujte vybraný template engine ako npm dependenciu. Napr. pre inštaláciu Pug spustite: - -
      -
      -$ npm install pug --save
      -
      -
      - -
      -Templatovacie enginy kompatibilné s Express ako napr. Pug exportujú funkciu `__express(filePath, options, callback)`, ktorá je volaná pomocou `res.render()` funkcie k vyrendrovaniu template kódu. - -Niektoré template enginy používajú inú konvenciu. [Consolidate.js](https://www.npmjs.org/package/consolidate) knižnica mapuje konvencie všetkých populárnych Node.js template enginov tak, aby bezproblémov fungovali s Express. -
      - -Nastavenie parametra view engine zabezpečí, že nie je potrebné špecifikovať engine, ani načítať modul template enginu vo vašej aplikácii; Express načíta tento modul interne, ako je (pre príklad hore) zobrazené nižšie. - -
      -
      -app.set('view engine', 'pug');
      -
      -
      - -Vo `views` priečinku vytvorte Pug template súbor s názvom `index.pug` s takýmto obsahom: - -
      -
      -html
      -  head
      -    title= title
      -  body
      -    h1= message
      -
      -
      - -Potom zadefinujte route pre rendrovanie `index.pug` súboru. Ak `view engine` parameter nie je nastavený, musíte špecifikovať príponu vášho `view` súboru. V opačnom prípade ju špecifikovať netreba. - -
      -
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -
      - -Po vykonaní requestu na hlavnú stránku, sa súbor `index.pug` vyrendruje ako HTML. - -Pre viac informácií ohľadom fungovania template enginov v Express si prečítajte: ["Vývoj template enginov pre Express"](/{{ page.lang }}/advanced/developing-template-engines.html). diff --git a/sk/guide/writing-middleware.md b/sk/guide/writing-middleware.md deleted file mode 100644 index e8d85081e0..0000000000 --- a/sk/guide/writing-middleware.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -layout: page -title: Tvorba middleware pre použitie v Express applikáciách -menu: guide -lang: sk ---- - - -# Tvorba middleware pre použitie v Express aplikáciách - -

      Prehľad

      - -_Middleware_ funkcie sú funkcie, ktoré majú prístup k [request objektu](/4x/api.html#req) (`req`), [response objektu](/4x/api.html#res) (`res`) a nasledujúcej middleware funkcii v request-response cykle aplikácie. Nasledujúca middleware funkcia v poradí je bežne označovaná premennou `next`. - -Middleware funkcie dokážu vykonávať nasledujúce úlohy: - -* Vykonať akýkoľvek kód. -* Vykonať zmeny na request a response objektoch. -* Ukončiť request-response cyklus. -* Zavolať nasledujúcu middleware funkciu v poradí. - -Ak aktuálna middleware funkcia neukončuje request-response cyklus, musí posunúť obsluhu nasledujúcej middleware funkcii vyvolaním `next()`. V opačnom prípade zostane request 'visieť'. - -Nasledujúci diagram ukazuje jednotlivé časti volania middleware funkcie: - - - - -
      - - -
      HTTP metóda pre ktorú je middleware funkcia aplikovateľná.
      - -
      Cesta (route) pre ktorú je middleware funkcia aplikovateľná.
      - -
      Middleware funkcia.
      - -
      Callback argument k middleware funkcii, nazvaný "next" podľa konvencie.
      - -
      HTTP response argument k middleware funkcii, nazvaný "res" podľa konvencie.
      - -
      HTTP request argument k middleware funkcii, nazvaný "req" podľa konvencie.
      -
      - -

      Príklad

      - -Tu je príklad jednoduchej "Hello World" Express aplikácie. -Zvyšná časť tohto článku definuje a pridáva do aplikácie dve middleware funkcie: -jedna nazvaná `myLogger` ktorá vypíše jednoduchú log message a druhá nazvaná `requestTime` ktorá vypíše timestamp HTTP requestu. - -
      -
      -var express = require('express');
      -var app = express();
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -app.listen(3000);
      -
      -
      - -

      Middleware funkcia myLogger

      - -Tu je príklad jednoduchej middleware funkcie nazvanej "myLogger". Táto funkcia len vypíše "LOGGED", vždy keď aplikácia odchytí request. Middleware funkcia je priradená premennej nazvanej `myLogger`. - -
      -
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      -
      -
      - -
      -Všimnite si volanie `next()` metódy hore. Zavolanie tejto funkcie vyvolá ďalší middleware v aplikácii. -Funkcia `next()` nie je súčasťou Node.js či Express API, ale je tretím argumentom s ktorým je middleware funkcia vyvolaná. -Funkcia `next()` môže byť nazvaná hocijako, ale podľa konvencie sa zvykne nazývať vždy "next". -Aby ste predišli zmätkom používajte túto konvenciu. -
      - -Pre načítanie middleware funkcie zavolajte `app.use()`, prostredníctvom ktorej ho špecifikujete. -Nasledujúci kód načíta `myLogger` middleware funkciu ešte pred route definíciou hlavnej cesty aplikácie (/). - -
      -
      -var express = require('express');
      -var app = express();
      -
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      -
      -app.use(myLogger);
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -app.listen(3000);
      -
      -
      - -Vždy keď aplikácia obdrží request požiadavku, vypíše do konzoly správu "LOGGED". - -Poradie načítania middleware-ov je dôležité: middleware funkcie, ktoré sú načítane prvé, sú aj ako prvé vyvolané. - -Ak by `myLogger` bol načítaný až za definíciou route pre hlavnú stránku aplikácie, nikdy by ho request nedosiahol a aplikácia by nevypísala "LOGGED", pretože route handler ukončí request-response cyklus. - -Táto `myLogger` middleware funkcia len vypisuje správu a posunie spracovanie ďalšej middleware funkcii v poradí zavolaním funkcie `next()`. - -

      Middleware funkcia requestTime

      - -Ďalej vytvoríme middleware funkciu s názvom "requestTime" a ktorá pridáva `requestTime` atribút na request objekt. - -
      -
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      -
      -
      - -Aplikácia teraz používa `requestTime` middleware funkciu. Taktiež callback funkcia pre obsluhu route hlavnej stránky aplikácie používa atribút, ktorý táto middleware funkcia pridala na `req` (request objekt). - -
      -
      -var express = require('express');
      -var app = express();
      -
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      -
      -app.use(requestTime);
      -
      -app.get('/', function (req, res) {
      -  var responseText = 'Hello World!
      '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); - -app.listen(3000); -
      -
      - -Po vykonaní requestu na hlavnú stránku aplikácie sa zobrazí v prehliadači timestamp vášho requestu. - -Keďže máte prístup k request a response objektu, ďalšej middleware funkcii v poradí a celému Node.js API, možnosti middleware funkcií sú nekonečné. - -Pre viac informácií ohľadom Express middleware si pozrite: [Použitie Express middleware](/{{ page.lang }}/guide/using-middleware.html). diff --git a/sk/index.md b/sk/index.md deleted file mode 100644 index a9408a844d..0000000000 --- a/sk/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -layout: home -title: Express - Node.js webový aplikačný framework -menu: home -lang: sk ---- - -
      - {% include header/header-{{ page.lang }}.html %} -
      -
      -
      - - Rýchly, jednoduchý a minimalistický webový aplikačný framework pre Node.js -
      -
      $ npm install express --save
      -
      -
      - -
      -
      - -
      - -
      -
      -

      Webové aplikácie

      Express je minimalistický, flexibilný, webový Node.js framework poskytujúci robustnú škálu funkcionality pre webové a mobilné aplikácie. -
      - -
      -

      API

      S nespočetným množstvom dostupných HTTP utilít a middlewarov je tvorba robustného API rýchla a jednoduchá. -
      - -
      -

      Vyhotovenie

      Express predstavuje tenkú vrstvu elementárnych prvkov webovej aplikácie bez skrývania Node.js prvkov, ktoré poznáte a milujete. -
      - -
      -

      Frameworky

      Mnohé známe frameworky sú založené na Express-e. -
      -
      - -
      - - diff --git a/sk/resources/community.md b/sk/resources/community.md deleted file mode 100644 index 36d1d4ba88..0000000000 --- a/sk/resources/community.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -layout: page -title: Express komunita -menu: resources -lang: sk ---- - - -# Komunita - -## Mailová skupina - -Pridajte sa k 2000 Express používateľom alebo sa pozrite na viac než 5000 -[Google Group](https://groups.google.com/group/express-js) diskusií. - -## Gitter - -[Strongloop/express chatroom](https://gitter.im/expressjs/express) je skvelým miestom pre developerov zaujímajúcich sa a diskutujúcich o Express-e. - -## IRC kanál - -Stovky developerov nájdete každý deň na #express kanály. -Ak máte otázky ohľadom frameworku, spýtajte sa. - -# Príklady - -Pozrite sa na desiatky Express aplikácií v priečinku [examples](https://github.com/expressjs/express/tree/master/examples) -v Express repozitári pokrývajúcich všetko od návrhu API a autentifikácie až po integráciu template enginov. - -## Problémy - -Ak ste sa stretli s problémom, o ktorom si myslíte že je bug, alebo len chcete požiadať o pridanie novej funkcionality, založte tiket v [issue queue](https://github.com/expressjs/express/issues). - -## Tretie strany - -Naša aktívna komunita vytvorila množstvo rozšírení, [middleware modulov](/{{ page.lang }}/resources/middleware.html) a frameworkov. Pre viac info si pozrite [wiki](https://github.com/expressjs/express/wiki). - diff --git a/sk/resources/companies-using-express.md b/sk/resources/companies-using-express.md deleted file mode 100644 index 6cf621bbe1..0000000000 --- a/sk/resources/companies-using-express.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -layout: page -title: Firmy používajúce Express -menu: resources -lang: sk ---- - -# Firmy používajúce Express v produkcii - - - diff --git a/sk/resources/frameworks.md b/sk/resources/frameworks.md deleted file mode 100644 index a74fd34be7..0000000000 --- a/sk/resources/frameworks.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -layout: page -title: Frameworky založené na Express-e -menu: frameworks -lang: sk ---- - - -# Frameworky založené na Express-e - -Na Express-e je založených niekoľko populárnych Node.js frameworkov, ako napr.: - -- [LoopBack](http://loopback.io) -- [Sails](http://sailsjs.org/) -- [Kraken](http://krakenjs.com/) -- [MEAN](http://mean.io/) diff --git a/sk/resources/glossary.md b/sk/resources/glossary.md deleted file mode 100644 index 11f68abeaa..0000000000 --- a/sk/resources/glossary.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -layout: page -title: Express slovník -menu: resources -lang: sk ---- - - -# Slovník - -
      Toto je pracovná verzia
      - -### aplikácia - -Vo všeobecnosti je to jeden, či viacej programov navrhnutých k vykonávaniu operácií za špecifickým účelom. V kontexte Express-u je to program, používajúci Express API fungujúceho na Node.js platforme. Pozrite sa na [app object](/{{ page.lang }}/api.html#express). - -### API - -Application programming interface. Hláskujte po písmenkách. - -### Express - -Express je minimalistický, flexibilný, webový framework pre Node.js aplikácie. Vo všeobecnosti, názov "Express" je preferovaný pred "Express.js," ktorý je ale taktiež zaužívaný a akceptovaný. - -### libuv - -Multi-platformová knižnica zameriavajúca sa na asynchrónne I/O, primárne navrhnutá pre použitie s Node.js. - -### middleware - -Je funkcia vyvolaná Express routing layer-om ešte pred zavolaním finálneho request handlera a preto "sedí" v strede medzi samotným requestom a routom. Zopár ďalších bodov terminológie týkajúcej sa middleware: - - * `var foo = require('middleware')` je zavolaný _requirnutím_ alebo _použitím_ Node.js modulu. Potom, výraz `var mw = foo()` typicky vracia middleware. - * `app.use(mw)` je zavolaný _pridaním middlewaru do globálneho stacku spracovania_. - * `app.get('/foo', mw, function (req, res) { ... })` je zavolaný pridaním middlewaru do stacku spracovania "GET /foo"_. - -### Node.js - -Sofvérová platforma používaná na budovanie škálovateľných aplikácií. Node.js používa JavaScript ako svoj skriptovací jazyk a dosahuje vysokú priepustnosť pomocou neblokujúcich I/O operácií a single-thread event loop-u. Pozrite sa na [nodejs.org](https://nodejs.org/en/). **Pozn. používania**: Pôvodne, "Node.js," neskor už len "Node". - -### open-source, open source - -Keď je použitý vo význame prídavného mena, používa sa pomlčka; Napr." Toto je open-source softvér". Pozrite sa na [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Pozn.: Hoci sa bežne pomlčka nepoužíva, v tejto dokumentácii sú použité pravidlá angličtiny, kde sa zložené prídavné mená spájajú pomlčkou. - -### request - -HTTP request. Klient zašle HTTP request message na server, ktorý vráti response. Request musí používať niektorú z [request metód](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) ako je GET, POST a pod.. - -### response - -HTTP response. Server vracia klientovi HTTP response message. Response obsahuje informáciu o stave spracovania requestu a taktiež môže obsahovať message body. - -### route - -Časť URL identifikujúca resource. Napr. v prípade `http://foo.com/products/id` je route "/products/id". - -### router - -Pozrite sa na definíciu [router](/{{ page.lang }}/api.html#router) v API dokumentácii. diff --git a/sk/resources/learning.md b/sk/resources/learning.md deleted file mode 100644 index 6cc24a816d..0000000000 --- a/sk/resources/learning.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -layout: page -title: Dodatočné vzdelávanie -menu: resources -lang: sk ---- - - -# Dodatočné vzdelávanie - -
      Upozornenie: Príspevky komunity nepodliehajúce schvalovaniu.
      - -## Knihy - -Tu je zopár z mnohých kníh o Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Pridajte vašu knihu! - -[Upravte Markdown súbor](https://github.com/expressjs/expressjs.com/blob/gh-pages/resources/learning.md) a pridajte odkaz na knihu, zašlite pull request (potrebné prihlásenie pomocou GitHub konta). Dodržiavajte formát zavedený v horeuvedenom zozname. - -## Blogy - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Baboon Blog: Express category](http://www.baboon.ir/tutorials/expressjs/) (Persian language) - -### Pridajte váš blog! - -[Upravte Markdown súbor](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) a pridajte odkaz na váš blog, zašlite pull request (potrebné prihlásenie pomocou GitHub konta). Dodržiavajte formát zavedený v horeuvedenom zozname. diff --git a/sk/resources/middleware.md b/sk/resources/middleware.md deleted file mode 100644 index 8129d10330..0000000000 --- a/sk/resources/middleware.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -layout: page -title: Express middleware -menu: resources -lang: sk ---- - - -# Third-party middleware - -Tu je zoznam niektorých Express middleware modulov: - - - [body-parser](https://github.com/expressjs/body-parser): kedysi `express.bodyParser`, `json` a `urlencoded`. - Pozrite sa taktiež na: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): kedysi `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): Connect/Express middleware moduly pre optimálne servovanie obrázkov. V prípade podpory transformuje obrázky na `.webp` príp. `.jxr`. - - [connect-timeout](https://github.com/expressjs/timeout): kedysi `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): kedysi `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): kedysi `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): kedysi `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): kedysi `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): nenápadný development tool, ktorý pridá panel s informáciami ohľadom template premenných, aktuálnej session, informácie o request dátach a ďalšie užitočné informácie. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): Express middleware modul slúžiaci k odfiltrovaniu častí JSON odpovedi na podľa hodnoty query parametra `fields`. - - [express-session](https://github.com/expressjs/session): predtým `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): Express middleware modul pre používanie CDN na statické assety s podporou viacerých hostov (napr.: cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): Express middleware modul pre ľudí ktorí to s trailing slashes myslia vážne. - - [express-stormpath](https://github.com/stormpath/stormpath-express): Express middleware modul pre ukladanie, autentifikáciu, autorizáciu, SSO a bezpečnosť dát. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): middleware modul slúžiaci na presmerovávanie HTTP requestov obsahujúcich uppercase na canonical lowercase formu. - - [helmet](https://github.com/helmetjs/helmet): modul ktorý vám pomôže zabezpečiť vašu aplikáciu pomocou nastavenia rozličných HTTP hlavičiek. - - [join-io](https://github.com/coderaiser/join-io "join-io"): modul slúžiaci na spájanie súborov "on the fly" kvoli zredukovaniu počtu volaní. - - [method-override](https://github.com/expressjs/method-override): kedysi `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): kedysi `logger` - - [passport](https://github.com/jaredhanson/passport): Express middleware modul slúžiaci na autentifikáciu. - - [response-time](https://github.com/expressjs/response-time): kedysi `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): kedysi `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): kedysi `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): modul pre servovanie statického obsahu. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): modul na tvorbu tzv. fingerprinted URL a caching hlavičiek pre statický obsah s podporou jednej i viacerých domén. - - [vhost](https://github.com/expressjs/vhost): kedysi `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): Express middleware modul poskytujúci bežné helper metódy pre views. - - [sriracha-admin](https://github.com/hdngr/siracha): Express middleware modul ktorý dynamicky generuje admin stránky pre Mongoose. - -Niektoré middleware moduly, ktoré kedysi boli súčasťou Connect-u už viac nie sú podporované Connect/Express tímom. Tieto moduly boli, alebo by mali byť, nahradené alternatívnymi lepšími modulmi. Používajte niektoré z nasledujúcich alternatív: - - - express.cookieParser - - [cookies](https://github.com/jed/cookies) a [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) - -Ďalšie middleware moduly nájdete tu: - - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) diff --git a/sk/starter/basic-routing.md b/sk/starter/basic-routing.md deleted file mode 100644 index ea766a08c2..0000000000 --- a/sk/starter/basic-routing.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: page -title: Express základný routing -menu: starter -lang: sk ---- - - -# Základný routing - -_Routing_ rozhoduje o tom, ako aplikácia odpovedá na požiadavky (requesty) klientov na jednotlivých koncových bodoch (endpointoch) reprezentovaných pomocou URI (alebo cesty) a špecifickej HTTP request metódy (GET, POST, atď.). - -Každý definovaný route môže mať jednu, alebo viacero handler funkcií, ktoré sa vykonajú v prípade, ak je route spárovaný s požiadavkou klienta. - -Route definícia má nasledovnú štruktúru: -
      -
      -app.METHOD(PATH, HANDLER)
      -
      -
      - -Kde: - -- `app` je `express` inštancia. -- `METHOD` je [HTTP request metóda](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol). -- `PATH` je cesta na serveri. -- `HANDLER` je funkcia, ktorá sa vykoná, ak je route spárovaný. - -
      -Tento tutoriál predpokladá, že existuje inštancia `express` aplikácie s názvom `app` a server je spustený. Ak nie ste oboznámení s vytváraním a spuštaním aplikácií, začnite [Hello world prikladom](/{{ page.lang }}/starter/hello-world.html). -
      - -Nasledujúce priklady ilustrujú definovanie jednoduchých route-ov. - -Odpoveď s textom `Hello World!` na hlavnej stránke: - -
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -
      - -Odpoveď na POST request na hlavný route (`/`), hlavnú stránku aplikácie: - -
      -
      -app.post('/', function (req, res) {
      -  res.send('Got a POST request');
      -});
      -
      -
      - -Odpoveď na PUT request na route `/user`: - -
      -
      -app.put('/user', function (req, res) {
      -  res.send('Got a PUT request at /user');
      -});
      -
      -
      - -Odpoveď na DELETE request na route `/user`: - -
      -
      -app.delete('/user', function (req, res) {
      -  res.send('Got a DELETE request at /user');
      -});
      -
      -
      - -Viac informácií ohľadom routing-u nájdete v [routing príručke](/{{ page.lang }}/guide/routing.html). diff --git a/sk/starter/faq.md b/sk/starter/faq.md deleted file mode 100644 index 424b01f58d..0000000000 --- a/sk/starter/faq.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -layout: page -title: Express FAQ -menu: starter -lang: sk ---- - - -# FAQ - -## Akú štruktúru priečinkov by som mal zvoliť pre svoju aplikáciu? - -Jednoznačná odpoveď na túto otázku neexistuje. Odpoveď závisí od rozsahu -aplikácie a tímu, ktorí na nej pracuje. Z dôvodu maximálnej flexibility nedefinuje -Express žiadne pravidlá, či obmedzenia. - -Samotná logika pre routing a ostatné špecifické časti aplikácie môže byť rozdelená -do ľubovoľného počtu súborov a organizovaná v ľubovoľnej štruktúre priečinkov, -presne tak, ako vám to vyhovuje. Pre inšpiráciu sa pozrite sa na nasledujúce príklady: - -* [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Route maping](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc) - -Existujú taktiež mnohé rozšírenia tretích strán, ktoré toto zjednodušujú: - -* [Resourceful routing](https://github.com/expressjs/express-resource) - -## Ako si zadefinujem model? - -Samotný Express nemá žiaden koncept databáze. Tento koncept je ponechaný na Node moduly tretích strán, -ktoré umožňujú pracovať s takmer všetkými databázami. - -Pre viac informácií ohľadom frameworku postavenom na Express-e, ktorý sa zameriava na prácu s modelom, -navštívte stránku [LoopBack](http://loopback.io). - -## Ako dokážem autentifikovať používateľov? - -Autentifikácia je ďalšia otvorená oblasť do ktorej Express priamo nezasahuje. -Môžete si zvoliť akúkoľvek autentifikačnú schému, ktorá vám vyhovuje. Pre jednoduchú meno / heslo autentifikáciu si pozrite [tento príklad](https://github.com/expressjs/express/tree/master/examples/auth). - - -## Aké template enginy Express podporuje? - -Express podporuje všetky template enginy definujúce `(path, locals, callback)` signatúru. -Pre porovnanie rozhraní template enginov a caching-u sa pozrite na projekt -[consolidate.js](https://github.com/visionmedia/consolidate.js). -Templatovacie enginy, ktoré nie sú v zozname, môžu byť Express-om taktiež podporované. - -## Ako handlovať 404-ky? - -V Express aplikácii nie sú odpovede 404 výsledkom chyby, preto ich error-handler middleware nezachytí. -Toto správanie je z dôvodu, že odpoveď 404 jednoducho indikuje absenciu práce, ktorú treba vykonať, -inými slovami, Express vykonal všetky middlware funkcie a nenašiel žiaden routing, -ktorý by na danú požiadavku vedel odpovedať. Všetko čo musíte spraviť k odchyteniu 404-ky je, že pridáte nasledovnú middleware funkciu pod všetky ostatné definície: - -
      -
      -app.use(function(req, res, next) {
      -  res.status(404).send('Sorry cant find that!');
      -});
      -
      -
      - -## Ako si zadefinujem error handler? - -Error-handling middleware je rovnakým middlewarom ako všetky ostatné, -s jediným rozdielom a to, že je vyvolaný so štyrmi argumentami, namiesto troch. -Jeho signatúra je nasledovná `(err, req, res, next)`: - -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      - -Viac informácií sa dozviete v kapitole [Error handling](/{{ page.lang }}/guide/error-handling.html). - -## Ako dokážem rendrovať čisté HTML? - -Nedokážeš! Nie je žiaden dôvod na rendrovanie HTML pomocou `res.render()` funkcie. -Ak máte konkrétny súbor, použite `res.sendFile()` funkciu. -Ak potrebujete servovať veľa statických súborov z konkrétneho priečinka, použite `express.static()` -middleware. diff --git a/sk/starter/generator.md b/sk/starter/generator.md deleted file mode 100644 index 370f8fac1f..0000000000 --- a/sk/starter/generator.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -layout: page -title: Express generátor -menu: starter -lang: sk ---- - - -# Express generátor - -Pre rýchle vygenerovanie skeletonu aplikácie môžete použit nástroj `express-generator`. - -Nainštalujte `express-generator` pomocou nasledujúceho príkazu: - -
      -
      -$ npm install express-generator -g
      -
      -
      - -Pre zobrazenie ďalších možností príkazu zadajte prepínač `-h`: - -
      -
      -$ express -h
      -
      -  Usage: express [options] [dir]
      -
      -  Options:
      -
      -    -h, --help          output usage information
      -        --version       output the version number
      -    -e, --ejs           add ejs engine support
      -        --hbs           add handlebars engine support
      -        --pug           add pug engine support
      -    -H, --hogan         add hogan.js engine support
      -        --no-view       generate without view engine
      -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
      -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
      -        --git           add .gitignore
      -    -f, --force         force on non-empty directory
      -
      -
      - -Nasledujúci príkaz vytvorí v aktuálnom priečinku Express aplikáciu s názvom _myapp_: - -
      -
      -$ express --view=pug myapp
      -
      -   create : myapp
      -   create : myapp/package.json
      -   create : myapp/app.js
      -   create : myapp/public
      -   create : myapp/public/javascripts
      -   create : myapp/public/images
      -   create : myapp/routes
      -   create : myapp/routes/index.js
      -   create : myapp/routes/users.js
      -   create : myapp/public/stylesheets
      -   create : myapp/public/stylesheets/style.css
      -   create : myapp/views
      -   create : myapp/views/index.pug
      -   create : myapp/views/layout.pug
      -   create : myapp/views/error.pug
      -   create : myapp/bin
      -   create : myapp/bin/www
      -
      -
      - -Potom nainštalujte dependencie: - -
      -
      -$ cd myapp
      -$ npm install
      -
      -
      - -Na MacOS príp. Linux, spustíte aplikáciu príkazom: - -
      -
      -$ DEBUG=myapp:* npm start
      -
      -
      - -Na Windows, príkazom: - -
      -
      -> set DEBUG=myapp:* & npm start
      -
      -
      - -Potom v prehliadači zadajte `http://localhost:3000/`. - -Vygenerovaná aplikácia má naslednovnú štruktúru priečinkov: - -
      -
      -.
      -├── app.js
      -├── bin
      -│   └── www
      -├── package.json
      -├── public
      -│   ├── images
      -│   ├── javascripts
      -│   └── stylesheets
      -│       └── style.css
      -├── routes
      -│   ├── index.js
      -│   └── users.js
      -└── views
      -    ├── error.pug
      -    ├── index.pug
      -    └── layout.pug
      -
      -7 directories, 9 files
      -
      -
      - -
      -Takáto štruktúra aplikácie je len jedným z mnohých spôsobov usporiadania Express aplikácie. Môžete ju použit, alebo ju zmeniť tak, ako vám bude najlepšie vyhovovať. -
      diff --git a/sk/starter/hello-world.md b/sk/starter/hello-world.md deleted file mode 100644 index 20f1189e71..0000000000 --- a/sk/starter/hello-world.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -layout: page -title: Express "Hello World" príklad -menu: starter -lang: sk ---- - - -# Hello world príklad - -
      -Toto bude v podstate najjednoduchšia Express aplikácia akú možete vytvoriť. Aplikácia s jedným súborom — _nie_ taká, ako keby ste použili [Express generátor](/{{ page.lang }}/starter/generator.html), ktorý vytvorí základnú štruktúru pre plnohodnotnú aplikáciu s niekoľkými JavaScript súbormi, Jade templatami a pod-adresármi pre rôzne účely. -
      - -Najskôr si vytvorte priečinok s názvom `myapp`, presuňte sa tam a spustite príkaz `npm init`. Potom nainštalujte `express` ako dependenciu podľa [inštalačnej príručky](/{{ page.lang }}/starter/installing.html). - -V priečinku `myapp` vytvorte súbor s názvom `app.js` a vložte do neho nasledovný kód: - -
      -
      -const express = require('express')
      -const app = express()
      -const port = 3000
      -
      -app.get('/', (req, res) => {
      -  res.send('Hello World!')
      -})
      -
      -app.listen(port, () => {
      -  console.log(`Example app listening at http://localhost:${port}`)
      -})
      -
      -
      - -Aplikácia naštartuje server a na porte 3000 začne počúvať na pripojenia. Aplikácia odpovie "Hello World!" na request na hlavnú URL (`/`) alebo _route_. Pre každú inú URL odpovie prostredníctvom **404 Not Found**. - -
      -Request (požiadavka) `req` a response (odpoveď) `res` sú presne rovnaké objekty, ktoré Node štandardne poskytuje, takže môžete spraviť `req.pipe()`, `req.on('data', callback)` a hocičo iné, čo by ste spravili v prípade, ak by ste nepoužili Express. -
      - -Spustite aplikáciu pomocou nasledujúceho príkazu: - -
      -
      -$ node app.js
      -
      -
      - -Potom v prehliadači zadajte [http://localhost:3000/](http://localhost:3000/) a pozrite si výstup. - diff --git a/sk/starter/installing.md b/sk/starter/installing.md deleted file mode 100644 index 2f2d3c4fa8..0000000000 --- a/sk/starter/installing.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -layout: page -title: Inštalácia Express -menu: starter -lang: sk ---- - - -# Inštalácia - -Za predpokladu, že už máte nainštalovaný [Node.js](https://nodejs.org/), vytvorte priečinok pre vašu aplikáciu a presuňte sa tam. - -
      -
      -$ mkdir myapp
      -$ cd myapp
      -
      -
      - -Pomocou príkazu `npm init` vytvorte pre vašu aplikáciu súbor `package.json`. -Viac informácií o tom, ako funguje `package.json` sa dozviete po prečítaní [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). - -
      -
      -$ npm init
      -
      -
      - -Tento príkaz vás vyzve k zadaniu viacerých informácií, ako sú napr. názov a verzia vašej aplikácie. -Teraz, kvôli zjednodušeniu, stlačte len ENTER k potvrdeniu defaultných hodnôt väčšiny z nich, okrem bodu: - -
      -
      -entry point: (index.js)
      -
      -
      - -Zadajte `app.js`, prípadne akýkoľvek iný názov hlavného súboru vašej aplikácie. Ak ho chcete nazvať `index.js`, stlačte ENTER k potvrdeniu navrhovaného názvu súboru. - -Teraz v `myapp` priečinku nainštalujte Express a pridajte ho ako dependenciu do package.json. Takto: - -
      -
      -$ npm install express --save
      -
      -
      - -Ak chcete nainštalovať Express bez toho, aby bol pridaný ako dependencia, vynechajte prepínač `--save` - -
      -
      -$ npm install express
      -
      -
      - -
      -Node moduly inštalované s prepínačom `--save` sú automaticky pridané do `dependencies` zoznamu v súbore `package.json`. -Následne spustením príkazu `npm install` v `app` priečinku sa všetky dependencie zo zoznamu automaticky nainštalujú. -
      diff --git a/sk/starter/static-files.md b/sk/starter/static-files.md deleted file mode 100644 index 78937c5c56..0000000000 --- a/sk/starter/static-files.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -layout: page -title: Servovanie statických súborov pomocou Express -menu: starter -lang: sk ---- - - -# Servovanie statických súborov pomocou Express - -Na servovanie statických súborov ako sú obrázky, CSS a JavaScript súbory používajte vstavaný `express.static` middleware. - -Pre priame servovanie statického obsahu zavolajte `express.static` middleware s parametrom predstavujúcim názov priečinka obsahujúceho statické súbory. Napr., pre servovanie obrázkov, CSS a JavaScript súborov z priečinka `public` použite: - -
      -
      -app.use(express.static('public'));
      -
      -
      - -Teraz dokážete načítať súbory obsiahnuté v `public` priečinku: - -
      -
      -http://localhost:3000/images/kitten.jpg
      -http://localhost:3000/css/style.css
      -http://localhost:3000/js/app.js
      -http://localhost:3000/images/bg.png
      -http://localhost:3000/hello.html
      -
      -
      - -
      -Express vyhľadáva súbory relatívne od priečinka so statickým obsahom, takže názov tohto priečinka nie je súčasťou URL. -
      - -V prípade, že chcete použiť viacero priečinkov so statickým obsahom, zavolajte `express.static` funkciu osobitne pre každý priečinok: - -
      -
      -app.use(express.static('public'));
      -app.use(express.static('files'));
      -
      -
      - -Express vyhľadáva súbory v jednotlivých adresároch podľa toho, v akom poradí sú zadefinované pomocou použitia `express.static` funkcie. - -Ak potrebujete vytvoriť virtuálny prefix pre cestu k statickým súborom (kde taká cesta (path) v skutočnosti na súborovom systéme neexistuje) servovaným pomocou `express.static` funkcie, [špecifikujte cestu](/{{ page.lang }}/4x/api.html#app.use) k statickému obsahu nasledovne: - -
      -
      -app.use('/static', express.static('public'));
      -
      -
      - -Teraz môžete načítať súbory nachádzajúce sa v priečinku `public` na ceste s prefixom `/static`. - -
      -
      -http://localhost:3000/static/images/kitten.jpg
      -http://localhost:3000/static/css/style.css
      -http://localhost:3000/static/js/app.js
      -http://localhost:3000/static/images/bg.png
      -http://localhost:3000/static/hello.html
      -
      -
      - -Pozor však na to, že cesta ktorú poskytnete `express.static` funkcii je relatívna k priečinku, z ktorého ste spustili váš `node` proces. Ak spúšťate express aplikáciu z iného priečinka, je bezpečnejšie použiť absolútnu cestu k priečinku, ktorý chcete servovať: - -
      -
      -app.use('/static', express.static(__dirname + '/public'));
      -
      -
      diff --git a/th/3x/api.md b/th/3x/api.md deleted file mode 100644 index 6bea952383..0000000000 --- a/th/3x/api.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -layout: 3x-api -title: Express 3.x - API Reference -menu: api -lang: th ---- -
      - -
      - **Express 3.x IS NO LONGER MAINTAINED** - - Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. -
      - -

      3.x API

      - - {% include api/en/3x/express.md %} - {% include api/en/3x/app.md %} - {% include api/en/3x/req.md %} - {% include api/en/3x/res.md %} - {% include api/en/3x/middleware.md %} - -
      diff --git a/th/4x/api.md b/th/4x/api.md deleted file mode 100644 index cfb93b66f2..0000000000 --- a/th/4x/api.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API Reference -menu: api -lang: th ---- -
      - -

      4.x API

      - - {% include api/en/4x/express.md %} - {% include api/en/4x/app.md %} - {% include api/en/4x/req.md %} - {% include api/en/4x/res.md %} - {% include api/en/4x/router.md %} - -
      diff --git a/th/advanced/best-practice-performance.md b/th/advanced/best-practice-performance.md deleted file mode 100644 index 78981b36be..0000000000 --- a/th/advanced/best-practice-performance.md +++ /dev/null @@ -1,424 +0,0 @@ ---- -layout: page -title: Performance Best Practices Using Express in Production -menu: advanced -lang: th ---- - -# Production best practices: performance and reliability - -## Overview - -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 (the dev part): - * [Use gzip compression](#use-gzip-compression) - * [Don't use synchronous functions](#dont-use-synchronous-functions) - * [Do logging correctly](#do-logging-correctly) - * [Handle exceptions properly](#handle-exceptions-properly) -* Things to do in your environment / setup (the ops part): - * [Set NODE_ENV to "production"](#set-node_env-to-production) - * [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) - * [Run your app in a cluster](#run-your-app-in-a-cluster) - * [Cache request results](#cache-request-results) - * [Use a load balancer](#use-a-load-balancer) - * [Use a reverse proxy](#use-a-reverse-proxy) - -## Things to do in your code {#in-code} - -Here are some things you can do in your code to improve your application's performance: - -* [Use gzip compression](#use-gzip-compression) -* [Don't use synchronous functions](#dont-use-synchronous-functions) -* [Do logging correctly](#do-logging-correctly) -* [Handle exceptions properly](#handle-exceptions-properly) - -### 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: - -```js -var compression = require('compression') -var express = require('express') -var 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](http://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. - -If you are using Node.js 4.0+ or io.js 2.1.0+, 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#cli_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_console_1) 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.err()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.err()` 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 [Winston](https://www.npmjs.com/package/winston) or [Bunyan](https://www.npmjs.com/package/bunyan). For a detailed comparison of these two libraries, see the StrongLoop blog post [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - -### 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://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop blog) - -#### 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#process_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 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. - -Use a tool such as [JSHint](http://jshint.com/) or [JSLint](http://www.jslint.com/) to help you find implicit exceptions like [reference errors on undefined variables](http://www.jshint.com/docs/options/#undef). - -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(() => { - var jsonStr = req.query.params - try { - var 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 - -Promises will handle any exceptions (both explicit and implicit) in asynchronous code blocks that use `then()`. Just add `.catch(next)` to the end of promise chains. For example: - -```js -app.get('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) -}) - -app.use((err, req, res, next) => { - // handle error -}) -``` - -Now all errors asynchronous and synchronous get propagated to the error middleware. - -However, there are two caveats: - -1. All your asynchronous code must return promises (except emitters). If a particular library does not return promises, convert the base object by using a helper function like [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Event emitters (like streams) can still cause uncaught exceptions. So make sure you are handling the error event properly; for example: - -```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) - -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) -``` - -For more information about error-handling by using promises, see: - -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) - -## Things to do in your environment / setup {#in-environment} - -Here are some things you can do in your system environment to improve your app's performance: - -* [Set NODE_ENV to "production"](#set-node_env-to-production) -* [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) -* [Run your app in a cluster](#run-your-app-in-a-cluster) -* [Cache request results](#cache-request-results) -* [Use a load balancer](#use-a-load-balancer) -* [Use a reverse proxy](#use-a-reverse-proxy) - -### 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](http://apmblog.dynatrace.com/2015/07/22/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 or Upstart). 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 Upstart, use the `env` keyword in your job file. For example: - -```sh -# /etc/init/env.conf - env NODE_ENV=production -``` - -For more information, see the [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). - -With systemd, use the `Environment` directive in your unit file. For example: - -```sh -# /etc/systemd/system/myservice.service -Environment=NODE_ENV=production -``` - -For more information, see [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). - -### 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 (StrongLoop PM and pm2). - -The most popular process managers for Node are as follows: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -For a feature-by-feature comparison of the three process managers, see [http://strong-pm.io/compare/](http://strong-pm.io/compare/). For a more detailed introduction to all three, see [Process managers for Express apps](/{{ page.lang }}/advanced/pm.html). - -Using any of these process managers will suffice to keep your application up, even if it does crash from time to time. - -However, StrongLoop PM has lots of features that specifically target production deployment. You can use it and the related StrongLoop tools to: - -* Build and package your app locally, then deploy it securely to your production system. -* Automatically restart your app if it crashes for any reason. -* Manage your clusters remotely. -* View CPU profiles and heap snapshots to optimize performance and diagnose memory leaks. -* View performance metrics for your application. -* Easily scale to multiple hosts with integrated control for Nginx load balancer. - -As explained below, when you install StrongLoop PM as an operating system service using your init system, it will automatically restart when the system restarts. Thus, it will keep your application processes and clusters alive forever. - -#### 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 two main init systems in use today are [systemd](https://wiki.debian.org/systemd) and [Upstart](http://upstart.ubuntu.com/). - -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 variables: -Environment=NODE_ENV=production - -# Allow many incoming connections -LimitNOFILE=infinity - -# Allow core dumps for debugging -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)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM as a systemd service - -You can easily install StrongLoop Process Manager as a systemd service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. - -To install StrongLoop PM as a systemd service: - -```sh -$ sudo sl-pm-install --systemd -``` - -Then start the service with: - -```sh -$ sudo /usr/bin/systemctl start strong-pm -``` - -For more information, see [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart is a system tool available on many Linux distributions for starting tasks and services during system startup, stopping them during shutdown, and supervising them. You can configure your Express app or process manager as a service and then Upstart will automatically restart it when it crashes. - -An Upstart service is defined in a job configuration file (also called a "job") with filename ending in `.conf`. The following example shows how to create a job called "myapp" for an app named "myapp" with the main file located at `/projects/myapp/index.js`. - -Create a file named `myapp.conf` at `/etc/init/` with the following content (replace the bold text with values for your system and app): - -```sh -# When to start the process -start on runlevel [2345] - -# When to stop the process -stop on runlevel [016] - -# Increase file descriptor limit to be able to handle more requests -limit nofile 50000 50000 - -# Use production mode -env NODE_ENV=production - -# Run as www-data -setuid www-data -setgid www-data - -# Run from inside the app dir -chdir /projects/myapp - -# The process to start -exec /usr/local/bin/node /projects/myapp/index.js - -# Restart the process if it is down -respawn - -# Limit restart attempt to 10 times within 10 seconds -respawn limit 10 10 -``` - -NOTE: This script requires Upstart 1.4 or newer, supported on Ubuntu 12.04-14.10. - -Since the job is configured to run when the system starts, your app will be started along with the operating system, and automatically restarted if the app crashes or the system goes down. - -Apart from automatically restarting the app, Upstart enables you to use these commands: - -* `start myapp` – Start the app -* `restart myapp` – Restart the app -* `stop myapp` – Stop the app. - -For more information on Upstart, see [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM as an Upstart service - -You can easily install StrongLoop Process Manager as an Upstart service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. - -To install StrongLoop PM as an Upstart 1.4 service: - -```sh -$ sudo sl-pm-install -``` - -Then run the service with: - -```sh -$ sudo /sbin/initctl start strong-pm -``` - -NOTE: On systems that don't support Upstart 1.4, the commands are slightly different. See [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) for more information. - -### 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](http://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/dist/latest-v4.x/docs/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it's far better to use one of the many tools out there that does it for you automatically; for example [node-pm](https://www.npmjs.com/package/node-pm) or [cluster-service](https://www.npmjs.com/package/cluster-service). - -#### Using StrongLoop PM - -If you deploy your application to StrongLoop Process Manager (PM), then you can take advantage of clustering _without_ modifying your application code. - -When StrongLoop Process Manager (PM) runs an application, it automatically runs it in a cluster with a number of workers equal to the number of CPU cores on the system. You can manually change the number of worker processes in the cluster using the slc command line tool without stopping the app. - -For example, assuming you've deployed your app to prod.foo.com and StrongLoop PM is listening on port 8701 (the default), then to set the cluster size to eight using slc: - -```sh -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8 -``` - -For more information on clustering with StrongLoop PM, see [Clustering](https://docs.strongloop.com/display/SLC/Clustering) in StrongLoop 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-cache.org/) or [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (see also [Nginx Caching](https://serversforhackers.com/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](http://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](http://socket.io/docs/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://www.nginx.com/) or [HAProxy](http://www.haproxy.org/) in production. diff --git a/th/advanced/best-practice-security.md b/th/advanced/best-practice-security.md deleted file mode 100644 index f32fd924dd..0000000000 --- a/th/advanced/best-practice-security.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -layout: page -title: Security Best Practices for Express in Production -menu: advanced -lang: th ---- - -# Production Best Practices: Security - -## Overview - -The term _"production"_ refers to the stage in the software lifecycle when an application or API is generally available to its end-users or consumers. In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively. - -Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production. - -{% include note.html content="If you believe you have discovered a security vulnerability in Express, please see -[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). -" %} - -Security best practices for Express applications in production include: - -- [Don’t use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) -- [Use TLS](#use-tls) -- [Use Helmet](#use-helmet) -- [Use cookies securely](#use-cookies-securely) -- [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) -- [Avoid other known vulnerabilities](#avoid-other-known-vulnerabilities) -- [Additional considerations](#additional-considerations) - - -## Don't use deprecated or vulnerable versions of Express - -Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html). - -Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/{{ page.lang }}/advanced/security-updates.html). If you are, update to one of the stable releases, preferably the latest. - -## Use TLS - -If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). - -You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_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://letsencrypt.org/isrg/). - -## Use Helmet - -[Helmet](https://www.npmjs.com/package/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. - -Helmet is actually just a collection of nine smaller middleware functions that set security-related HTTP headers: - -* [csp](https://github.com/helmetjs/csp) sets the `Content-Security-Policy` header to help prevent cross-site scripting attacks and other cross-site injections. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) removes the `X-Powered-By` header. -* [hsts](https://github.com/helmetjs/hsts) sets `Strict-Transport-Security` header that enforces secure (HTTP over SSL/TLS) connections to the server. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) sets `X-Download-Options` for IE8+. -* [noCache](https://github.com/helmetjs/nocache) sets `Cache-Control` and Pragma headers to disable client-side caching. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) sets `X-Content-Type-Options` to prevent browsers from MIME-sniffing a response away from the declared content-type. -* [frameguard](https://github.com/helmetjs/frameguard) sets the `X-Frame-Options` header to provide [clickjacking](https://www.owasp.org/index.php/Clickjacking) protection. -* [xssFilter](https://github.com/helmetjs/x-xss-protection) sets `X-XSS-Protection` to enable the Cross-site scripting (XSS) filter in most recent web browsers. - -Install Helmet like any other module: - -```sh -$ npm install --save helmet -``` - -Then to use it in your code: - -```js -// ... - -var helmet = require('helmet') -app.use(helmet()) - -// ... -``` - -### At a minimum, disable X-Powered-By header - -If you don't want to use Helmet, then at least disable the `X-Powered-By` header. Attackers can use this header (which is enabled by default) to detect apps running Express and then launch specifically-targeted attacks. - -So, best practice is to to turn off the header with the `app.disable()` method: - -```js -app.disable('x-powered-by') -``` - -If you use `helmet.js`, it takes care of this for you. - -{% include note.html content="Disabling the `X-Powered-By header` does not prevent -a sophisticated attacker from determining that an app is running Express. It may -discourage a casual exploit, but there are other ways to determine an app is running -Express. "%} - -## Use cookies securely - -To ensure cookies don't open your app to exploits, don't use the default session cookie name and set cookie security options appropriately. - -There are two main middleware cookie session modules: - -* [express-session](https://www.npmjs.com/package/express-session) that replaces `express.session` middleware built-in to Express 3.x. -* [cookie-session](https://www.npmjs.com/package/cookie-session) that replaces `express.cookieSession` middleware built-in to Express 3.x. - -The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. 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). - -In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then express-session may be a better choice. - -### Don't use the default session cookie name - -Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. - -To avoid this problem, use generic cookie names; for example using [express-session](https://www.npmjs.com/package/express-session) middleware: - -```js -var session = require('express-session') -app.set('trust proxy', 1) // trust first proxy -app.use(session({ - secret: 's3Cur3', - name: 'sessionId' -})) -``` - -### Set cookie security options - -Set the following cookie options to enhance security: - -* `secure` - Ensures the browser only sends the cookie over HTTPS. -* `httpOnly` - Ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks. -* `domain` - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next. -* `path` - indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request. -* `expires` - use to set expiration date for persistent cookies. - -Here is an example using [cookie-session](https://www.npmjs.com/package/cookie-session) middleware: - -```js -var session = require('cookie-session') -var express = require('express') -var app = express() - -var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour -app.use(session({ - name: 'session', - keys: ['key1', 'key2'], - cookie: { - secure: true, - httpOnly: true, - domain: 'example.com', - path: 'foo/bar', - expires: expiryDate - } -})) -``` - -## Ensure your dependencies are secure - -Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. - -Since npm@6, npm automatically reviews every install request. Also you can use 'npm audit' to analyze your dependency tree. - -```sh -$ 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: - -```sh -$ npm install -g snyk -$ cd your-app -``` - -Use this command to test your application for vulnerabilities: - -```sh -$ snyk test -``` - -Use this command to open a wizard that walks you through the process of applying updates or patches to fix the vulnerabilities that were found: - -```sh -$ snyk wizard -``` - -## Avoid other known vulnerabilities - -Keep an eye out for [Node Security Project](https://npmjs.com/advisories) or [Snyk](https://snyk.io/vuln/) 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/index.php/Top_10_2013-Top_10) and take precautions to avoid them. - -## Additional considerations - -Here are some further recommendations from the excellent [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Refer to that blog post for all the details on these recommendations: - -* Implement rate-limiting to prevent brute-force attacks against authentication. One way to do this is to use [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) to enforce a rate-limiting policy. Alternatively, you can use middleware such as [express-limiter](https://www.npmjs.com/package/express-limiter), but doing so will require you to modify your code somewhat. -* Use [csurf](https://www.npmjs.com/package/csurf) middleware to protect against cross-site request forgery (CSRF). -* 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 [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. diff --git a/th/advanced/developing-template-engines.md b/th/advanced/developing-template-engines.md deleted file mode 100755 index 5c43cac5d9..0000000000 --- a/th/advanced/developing-template-engines.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: page -title: Developing template engines for Express -menu: advanced -lang: th ---- - -# Developing template engines for Express - -Use the `app.engine(ext, callback)` method to create your own template engine. `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. - -The following code is an example of implementing a very simple template engine for rendering `.ntl` files. - -```js -var fs = require('fs') // this engine requires the fs module -app.engine('ntl', function (filePath, options, callback) { // define the template engine - fs.readFile(filePath, function (err, content) { - if (err) return callback(err) - // this is an extremely simple template engine - var rendered = content.toString().replace('#title#', '' + options.title + '') - .replace('#message#', '

      ' + options.message + '

      ') - return callback(null, rendered) - }) -}) -app.set('views', './views') // specify the views directory -app.set('view engine', 'ntl') // register the template engine -``` - -Your app will now be able to render `.ntl` files. Create a file named `index.ntl` in the `views` directory with the following content. - -```text -#title# -#message# -``` -Then, create the following route in your app. - -```js -app.get('/', function (req, res) { - res.render('index', { title: 'Hey', message: 'Hello there!' }) -}) -``` -When you make a request to the home page, `index.ntl` will be rendered as HTML. diff --git a/th/advanced/pm.md b/th/advanced/pm.md deleted file mode 100755 index 9ebd1caa4f..0000000000 --- a/th/advanced/pm.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -layout: page -title: Process managers for Express apps -menu: advanced -lang: th ---- - -# Process managers for Express apps - -When you run Express apps for production, it is helpful to use a _process manager_ to achieve the following tasks: - -- Restart the app automatically if it crashes. -- Gain insights into runtime performance and resource consumption. -- Modify settings dynamically to improve performance. -- Control clustering. - -A process manager is somewhat like an application server: it's a "container" for applications that facilitates deployment, -provides high availability, and enables you to manage the application at runtime. - -The most popular process managers for Express and other Node.js applications are as follows: - -- [StrongLoop Process Manager](#strongloop-process-manager) -- [PM2](#pm2) -- [Forever](#forever) -- [SystemD](#systemd) - - -Using any of these four tools can be very helpful, however StrongLoop Process Manager is the only tool that provides a comprehensive runtime and deployment solution that addresses the entire Node.js application life cycle, with tooling for every step before and after production, in a unified interface. - -Here's a brief look at each of these tools. -For a detailed comparison, see [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) is a production process manager for Node.js applications. StrongLoop PM has built-in load balancing, monitoring, and multi-host deployment, and a graphical console. -You can use StrongLoop PM for the following tasks: - -- Build, package, and deploy your Node.js application to a local or remote system. -- View CPU profiles and heap snapshots to optimize performance and diagnose memory leaks. -- Keep processes and clusters alive forever. -- View performance metrics on your application. -- Easily manage multi-host deployments with Nginx integration. -- Unify multiple StrongLoop PMs to a distributed microservices runtime that is managed from Arc. - -You can work with StrongLoop PM by using a powerful command-line interface tool called `slc`, or a graphical tool called Arc. Arc is open source, with professional support provided by StrongLoop. - -For more information, see [http://strong-pm.io/](http://strong-pm.io/). - -Full documentation: - -- [Operating Node apps (StrongLoop documentation)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Installation -```sh -$ [sudo] npm install -g strongloop -``` - -### Basic use -```sh -$ cd my-app -$ slc start -``` - -View the status of Process Manager and all deployed apps: - -```sh -$ slc ctl -Service ID: 1 -Service Name: my-app -Environment variables: - No environment variables defined -Instances: - Version Agent version Cluster size - 4.1.13 1.5.14 4 -Processes: - ID PID WID Listening Ports Tracking objects? CPU profiling? - 1.1.57692 57692 0 - 1.1.57693 57693 1 0.0.0.0:3001 - 1.1.57694 57694 2 0.0.0.0:3001 - 1.1.57695 57695 3 0.0.0.0:3001 - 1.1.57696 57696 4 0.0.0.0:3001 -``` - -List all the apps (services) under management: - -```sh -$ slc ctl ls -Id Name Scale - 1 my-app 1 -``` - -Stop an app: - -```sh -$ slc ctl stop my-app -``` - -Restart an app: - -```sh -$ slc ctl restart my-app -``` - -You can also "soft restart," which gives worker processes a grace period to close existing connections, then restarts the current application: - -```sh -$ slc ctl soft-restart my-app -``` - -To remove an app from management: - -```sh -$ slc ctl remove my-app -``` - -## PM2 - -PM2 is a production process manager for Node.js applications, that has a built-in load balancer. PM2 allows you to keep applications alive forever and reload them without downtime, and will facilitate common system admin tasks. PM2 also enables you to manage application logging, monitoring, and clustering. - -For more information, see [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Installation - -```sh -$ [sudo] npm install pm2 -g -``` - -### Basic use - -When you start an app by using the `pm2` command, you must specify the path of the app. However, when you stop, restart, or delete an app, you can specify just the name or the id of the app. - -```sh -$ pm2 start npm --name my-app -- start -[PM2] restartProcessId process id 0 -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐ -│ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤ -│ my-app │ 0 │ fork │ 64029 │ online │ 1 │ 0s │ 17.816 MB │ disabled │ -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘ - Use the `pm2 show ` command to get more details about an app. -``` - -When you start an app by using the `pm2` command, the app is immediately sent to the background. You can control the background app from the command line by using various `pm2` commands. - -After an app is started by using the `pm2` command, it is registered in PM2's list of processes with an ID. You can therefore manage apps with the same name from different directories on the system, by using their IDs. - -Note that if more than one app with the same name is running, `pm2` commands affect all of them. So use IDs instead of names to manage individual apps. - -List all running processes: - -```sh -$ pm2 list -``` - -Stop an app: - -```sh -$ pm2 stop 0 -``` - -Restart an app: - -```sh -$ pm2 restart 0 -``` - -To view detailed information about an app: - -```sh -$ pm2 show 0 -``` - -To remove an app from PM2's registry: - -```sh -$ pm2 delete 0 -``` - - -## Forever - -Forever is a simple command-line interface tool for ensuring that a given script runs continuously (forever). Forever's simple interface makes it ideal for running smaller deployments of Node.js apps and scripts. - -For more information, see [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Installation - -```sh -$ [sudo] npm install forever -g -``` - -### Basic use - -To start a script, use the `forever start` command and specify the path of the script: - -```sh -$ forever start script.js -``` - -This command will run the script in daemon mode (in the background). - -To run the script so that it is attached to the terminal, omit `start`: - -```sh -$ forever script.js -``` - -It is a good idea to log output from the Forever tool and the script by using the logging options `-l`, `-o`, and `-e`, as shown this example: - -```sh -$ forever start -l forever.log -o out.log -e err.log script.js -``` - -To view the list of scripts that were started by Forever: - -```sh -$ forever list -``` - -To stop a script that was started by Forever use the `forever stop` command and specify the process index (as listed by the `forever list` command). - -```sh -$ forever stop 1 -``` - -Alternatively, specify the path of the file: - -```sh -$ forever stop script.js -``` - -To stop all the scripts that were started by Forever: - -```sh -$ forever stopall -``` - -Forever has many more options, and it also provides a programmatic API. - -## SystemD - -### Introduction - -SystemD is the default process manager on modern Linux distributions. Running a Node service based on SystemD is very simple. NOTE: This section is based on [a blog post by Ralph Slooten (@axllent)](https://www.axllent.org/docs/view/nodejs-service-with-systemd/). - -### Set up the service - -Create a file in `/etc/systemd/system/express.service`: - -``` -[Unit] -Description=Express -# Set dependencies to other services (optional) -#After=mongodb.service - -[Service] -# Run Grunt before starting the server (optional) -#ExecStartPre=/usr/bin/grunt - -# Start the js-file starting the express server -ExecStart=/usr/bin/node server.js -WorkingDirectory=/usr/local/express -Restart=always -RestartSec=10 -StandardOutput=syslog -StandardError=syslog -SyslogIdentifier=Express -# Change to a non-root user (optional, but recommended) -#User= -#Group= -# Set environment options -Environment=NODE_ENV=production PORT=8080 - -[Install] -WantedBy=multi-user.target -``` - -### Enable service - -``` -$ systemctl enable express.service -``` - -### Start service - -``` -$ systemctl start express.service -``` - -### Check service status - -``` -$ systemctl status express.service -``` diff --git a/th/advanced/security-updates.md b/th/advanced/security-updates.md deleted file mode 100755 index 0110097320..0000000000 --- a/th/advanced/security-updates.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -layout: page -title: Express security updates -menu: advanced -lang: th ---- -# Security updates - -
      -Node.js vulnerabilities directly affect Express. Therefore [keep a watch on Node.js vulnerabilities](http://blog.nodejs.org/vulnerability/) and make sure you are using the latest stable version of Node.js. -
      - -The list below enumerates the Express vulnerabilities that were fixed in the specified version update. - -**NOTE**: If you believe you have discovered a security vulnerability in Express, please see -[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). - -## 4.x - - * 4.16.0 - * The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. - * The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. - * 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. - * 4.15.3 - * The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. - * 4.15.2 - * The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. - * 4.11.1 - * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` - * 4.10.7 - * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 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 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. - * 4.8.0 - * Sparse arrays that have extremely high indexes in the query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - -## 3.x - -
      - **Express 3.x IS NO LONGER MAINTAINED** - - Known and unknown security issues in 3.x have not been addressed since the last update (1 August, 2015). Using the 3.x line should not be considered secure. -
      - - * 3.19.1 - * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` - * 3.19.0 - * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Fixed directory traversal vulnerabilities in `express.static`. - * 3.16.6 - * Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. - * 3.16.0 - * Sparse arrays that have extremely high indexes in query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - * 3.3.0 - * The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks. diff --git a/th/api.md b/th/api.md deleted file mode 100644 index f6f105d853..0000000000 --- a/th/api.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - การอ้างอิง API -lang: th ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/th/guide/behind-proxies.md b/th/guide/behind-proxies.md deleted file mode 100755 index 40ef11e8e1..0000000000 --- a/th/guide/behind-proxies.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -layout: page -title: Express behind proxies -menu: guide -lang: th ---- -# Express behind proxies - -When running an Express app behind a proxy, set (by using [app.set()](/{{ page.lang }}/4x/api.html#app.set)) the application variable `trust proxy` to one of the values listed in the following table. - -
      -Although the app will not fail to run if the application variable `trust proxy` is not set, it will incorrectly register the proxy's IP address as the client IP address unless `trust proxy` is configured. -
      - - - - - - - - - - - - - - - - - - - - - -
      TypeValue
      Boolean -If `true`, the client's IP address is understood as the left-most entry in the `X-Forwarded-*` header. - -If `false`, the app is understood as directly facing the Internet and the client's IP address is derived from `req.connection.remoteAddress`. This is the default setting. -
      IP addresses -An IP address, subnet, or an array of IP addresses and subnets to trust. The following list shows the pre-configured subnet names: - -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` - -You can set IP addresses in any of the following ways: - -```js -app.set('trust proxy', 'loopback') // specify a single subnet -app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address -app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array -``` - -When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address. -
      Number -Trust the `n`th hop from the front-facing proxy server as the client. -
      Function -Custom trust implementation. Use this only if you know what you are doing. - -```js -app.set('trust proxy', function (ip) { - if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs - else return false -}) -``` -
      - -Enabling `trust proxy` will have the following impact: - -
        -
      • The value of [req.hostname](/{{ page.lang }}/api.html#req.hostname) is derived from the value set in the `X-Forwarded-Host` header, which can be set by the client or by the proxy. -
      • -
      • `X-Forwarded-Proto` can be set by the reverse proxy to tell the app whether it is `https` or `http` or even an invalid name. This value is reflected by [req.protocol](/{{ page.lang }}/api.html#req.protocol). -
      • -
      • The [req.ip](/{{ page.lang }}/api.html#req.ip) and [req.ips](/{{ page.lang }}/api.html#req.ips) values are populated with the list of addresses from `X-Forwarded-For`. -
      • -
      - -The `trust proxy` setting is implemented using the [proxy-addr](https://www.npmjs.com/package/proxy-addr) package. For more information, see its documentation. diff --git a/th/guide/database-integration.md b/th/guide/database-integration.md deleted file mode 100644 index 3650dcf8e9..0000000000 --- a/th/guide/database-integration.md +++ /dev/null @@ -1,467 +0,0 @@ ---- -layout: page -title: Express database integration -menu: guide -lang: th ---- -# Database integration - -Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app: - -* [Cassandra](#cassandra) -* [Couchbase](#couchbase) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongodb) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgresql) -* [Redis](#redis) -* [SQL Server](#sql-server) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) - -
      -These database drivers are among many that are available. For other options, -search on the [npm](https://www.npmjs.com/) site. -
      - -## Cassandra - -**Module**: [cassandra-driver](https://github.com/datastax/nodejs-driver) - -### Installation - -```sh -$ npm install cassandra-driver -``` - -### Example - -```js -var cassandra = require('cassandra-driver') -var client = new cassandra.Client({ contactPoints: ['localhost'] }) - -client.execute('select key from system.local', function (err, result) { - if (err) throw err - console.log(result.rows[0]) -}) -``` - -## Couchbase - -**Module**: [couchnode](https://github.com/couchbase/couchnode) - -### Installation - -```sh -$ npm install couchbase -``` - -### Example - -```js -var couchbase = require('couchbase') -var bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') - -// add a document to a bucket -bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, result) { - if (err) { - console.log(err) - } else { - console.log(result) - } -}) - -// get all documents with shoe size 13 -var n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' -var query = N1qlQuery.fromString(n1ql) -bucket.query(query, [13], function (err, result) { - if (err) { - console.log(err) - } else { - console.log(result) - } -}) -``` - -## CouchDB - -**Module**: [nano](https://github.com/dscape/nano) - -### Installation - -```sh -$ npm install nano -``` - -### Example - -```js -var nano = require('nano')('http://localhost:5984') -nano.db.create('books') -var books = nano.db.use('books') - -// Insert a book document in the books database -books.insert({ name: 'The Art of war' }, null, function (err, body) { - if (err) { - console.log(err) - } else { - console.log(body) - } -}) - -// Get a list of all books -books.list(function (err, body) { - if (err) { - console.log(err) - } else { - console.log(body.rows) - } -}) -``` - -## LevelDB - -**Module**: [levelup](https://github.com/rvagg/node-levelup) - -### Installation - -```sh -$ npm install level levelup leveldown -``` - -### Example - -```js -var levelup = require('levelup') -var db = levelup('./mydb') - -db.put('name', 'LevelUP', function (err) { - if (err) return console.log('Ooops!', err) - - db.get('name', function (err, value) { - if (err) return console.log('Ooops!', err) - - console.log('name=' + value) - }) -}) -``` - -## MySQL - -**Module**: [mysql](https://github.com/felixge/node-mysql/) - -### Installation - -```sh -$ npm install mysql -``` - -### Example - -```js -var mysql = require('mysql') -var connection = mysql.createConnection({ - host: 'localhost', - user: 'dbuser', - password: 's3kreee7', - database: 'my_db' -}) - -connection.connect() - -connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) { - if (err) throw err - - console.log('The solution is: ', rows[0].solution) -}) - -connection.end() -``` - -## MongoDB - -**Module**: [mongodb](https://github.com/mongodb/node-mongodb-native) - -### Installation - -```sh -$ npm install mongodb -``` - -### Example - -```js -var MongoClient = require('mongodb').MongoClient - -MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { - if (err) throw err - - db.collection('mammals').find().toArray(function (err, result) { - if (err) throw err - - console.log(result) - }) -}) -``` - -If you want an object model driver for MongoDB, look at [Mongoose](https://github.com/LearnBoost/mongoose). - -## Neo4j - -**Module**: [apoc](https://github.com/hacksparrow/apoc) - -### Installation - -```sh -$ npm install apoc -``` - -### Example - -```js -var apoc = require('apoc') - -apoc.query('match (n) return n').exec().then( - function (response) { - console.log(response) - }, - function (fail) { - console.log(fail) - } -) -``` - -## Oracle - -**Module**: [oracledb](https://github.com/oracle/node-oracledb) - -### Installation - - NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). - -```sh -$ npm install oracledb -``` - -### Example - -```js -const oracledb = require('oracledb') -const config = { - user: '', - password: '', - connectString: 'localhost:1521/orcl' -} - -async function getEmployee (empId) { - let conn - - try { - conn = await oracledb.getConnection(config) - - const result = await conn.execute( - 'select * from employees where employee_id = :id', - [empId] - ) - - console.log(result.rows[0]) - } catch (err) { - console.log('Ouch!', err) - } finally { - if (conn) { // conn assignment worked, need to close - await conn.close() - } - } -} - -getEmployee(101) -``` - -## PostgreSQL - -**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise) - -### Installation - -```sh -$ npm install pg-promise -``` - -### Example - -```js -var pgp = require('pg-promise')(/* options */) -var db = pgp('postgres://username:password@host:port/database') - -db.one('SELECT $1 AS value', 123) - .then(function (data) { - console.log('DATA:', data.value) - }) - .catch(function (error) { - console.log('ERROR:', error) - }) -``` - -## Redis - -**Module**: [redis](https://github.com/mranney/node_redis) - -### Installation - -```sh -$ npm install redis -``` - -### Example - -```js -var redis = require('redis') -var client = redis.createClient() - -client.on('error', function (err) { - console.log('Error ' + err) -}) - -client.set('string key', 'string val', redis.print) -client.hset('hash key', 'hashtest 1', 'some value', redis.print) -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print) - -client.hkeys('hash key', function (err, replies) { - console.log(replies.length + ' replies:') - - replies.forEach(function (reply, i) { - console.log(' ' + i + ': ' + reply) - }) - - client.quit() -}) -``` - -## SQL Server - -**Module**: [tedious](https://github.com/tediousjs/tedious) - -### Installation - -```sh -$ npm install tedious -``` - -### Example - -```js -var Connection = require('tedious').Connection -var Request = require('tedious').Request - -var config = { - userName: 'your_username', // update me - password: 'your_password', // update me - server: 'localhost' -} - -var connection = new Connection(config) - -connection.on('connect', function (err) { - if (err) { - console.log(err) - } else { - executeStatement() - } -}) - -function executeStatement () { - request = new Request("select 123, 'hello world'", function (err, rowCount) { - if (err) { - console.log(err) - } else { - console.log(rowCount + ' rows') - } - connection.close() - }) - - request.on('row', function (columns) { - columns.forEach(function (column) { - if (column.value === null) { - console.log('NULL') - } else { - console.log(column.value) - } - }) - }) - - connection.execSql(request) -} -``` - -## SQLite - -**Module**: [sqlite3](https://github.com/mapbox/node-sqlite3) - -### Installation - -```sh -$ npm install sqlite3 -``` - -### Example - -```js -var sqlite3 = require('sqlite3').verbose() -var db = new sqlite3.Database(':memory:') - -db.serialize(function () { - db.run('CREATE TABLE lorem (info TEXT)') - var stmt = db.prepare('INSERT INTO lorem VALUES (?)') - - for (var i = 0; i < 10; i++) { - stmt.run('Ipsum ' + i) - } - - stmt.finalize() - - db.each('SELECT rowid AS id, info FROM lorem', function (err, row) { - console.log(row.id + ': ' + row.info) - }) -}) - -db.close() -``` - -## ElasticSearch - -**Module**: [elasticsearch](https://github.com/elastic/elasticsearch-js) - -### Installation - -```sh -$ npm install elasticsearch -``` - -### Example - -```js -var elasticsearch = require('elasticsearch') -var client = elasticsearch.Client({ - host: 'localhost:9200' -}) - -client.search({ - index: 'books', - type: 'book', - body: { - query: { - multi_match: { - query: 'express js', - fields: ['title', 'description'] - } - } - } -}).then(function (response) { - var hits = response.hits.hits -}, function (error) { - console.trace(error.message) -}) -``` diff --git a/th/guide/debugging.md b/th/guide/debugging.md deleted file mode 100755 index 64509eaa95..0000000000 --- a/th/guide/debugging.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -layout: page -title: Debugging Express -menu: guide -lang: th ---- -# Debugging Express - -Express uses the [debug](https://www.npmjs.com/package/debug) module -internally to log information about route matches, middleware functions that are in use, application mode, -and the flow of the request-response cycle. - -
      -`debug` is like an augmented version of `console.log`, but unlike `console.log`, you don't have to -comment out `debug` logs in production code. Logging is turned off by default and can be conditionally turned on by using the `DEBUG` environment variable. -
      - -To see all the internal logs used in Express, set the `DEBUG` environment variable to -`express:*` when launching your app. - -```sh -$ DEBUG=express:* node index.js -``` - -On Windows, use the corresponding command. - -```sh -> set DEBUG=express:* & node index.js -``` - -Running this command on the default app generated by the [express generator](/{{ page.lang }}/starter/generator.html) prints the following output: - -```sh -$ 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 / <anonymous> +0ms - express:router:layer new / +0ms - express:router use / <anonymous> +0ms - express:router:layer new / +0ms - express:router use / <anonymous> +0ms - express:router:layer new / +0ms -``` - -When a request is then made to the app, you will see the logs specified in the Express code: - -```sh - 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 -``` - -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` - -An application generated by the `express` command also uses the `debug` module and its debug namespace is scoped to the name of the application. - -For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: - -```sh -$ DEBUG=sample-app:* node ./bin/www -``` - -You can specify more than one debug namespace by assigning a comma-separated list of names: - -```sh -$ DEBUG=http,mail,express:* node index.js -``` - -For more information about `debug`, see the [debug](https://www.npmjs.com/package/debug). diff --git a/th/guide/error-handling.md b/th/guide/error-handling.md deleted file mode 100755 index 6f569ce849..0000000000 --- a/th/guide/error-handling.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -layout: page -title: Express error handling -menu: guide -lang: th ---- -# Error handling - -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)`. For example: - -```js -app.use(function (err, req, res, next) { - console.error(err.stack) - res.status(500).send('Something broke!') -}) -``` - -You define error-handling middleware last, after other `app.use()` and routes calls; for example: - -```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') - -app.use(bodyParser.urlencoded({ - extended: true -})) -app.use(bodyParser.json()) -app.use(methodOverride()) -app.use(function (err, req, res, next) { - // logic -}) -``` - -Responses from within a middleware function can be in any format that you prefer, such as an HTML error page, a simple message, or a JSON string. - -For organizational (and higher-level framework) purposes, you can define -several error-handling middleware functions, much like you would with -regular middleware functions. For example, if you wanted to define an error-handler -for requests made by using `XHR`, and those without, you might use the following commands: - -```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') - -app.use(bodyParser.urlencoded({ - extended: true -})) -app.use(bodyParser.json()) -app.use(methodOverride()) -app.use(logErrors) -app.use(clientErrorHandler) -app.use(errorHandler) -``` - -In this example, the generic `logErrors` might write request and -error information to `stderr`, for example: - -```js -function logErrors (err, req, res, next) { - console.error(err.stack) - next(err) -} -``` - -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. - -```js -function clientErrorHandler (err, req, res, next) { - if (req.xhr) { - res.status(500).send({ error: 'Something failed!' }) - } else { - next(err) - } -} -``` - -The "catch-all" `errorHandler` function might be implemented as follows: - -```js -function errorHandler (err, req, res, next) { - res.status(500) - res.render('error', { error: err }) -} -``` - -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 you want to handle that error in some way, you'll have to create an error-handling route as described in the next section. - -If you have a route handler with multiple callback functions you can use the `route` parameter to skip to the next route handler. For example: - -```js -app.get('/a_route_behind_paywall', - function checkIfPaidSubscriber (req, res, next) { - if (!req.user.hasPaid) { - // continue handling this request - next('route') - } else { - next() - } - }, function getPaidContent (req, res, next) { - PaidContent.find(function (err, doc) { - if (err) return next(err) - res.json(doc) - }) - }) -``` - -In this example, the `getPaidContent` handler will be skipped but any remaining handlers in `app` for `/a_route_behind_paywall` would continue to be executed. - -
      -Calls to `next()` and `next(err)` indicate that the current handler is complete and in what state. `next(err)` will skip all remaining handlers in the chain except for those that are set up to handle errors as described above. -
      - -## The Default Error Handler - -Express comes with a built-in error handler, which takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack. - -If you pass an error to `next()` and you do not handle it in -an error handler, it will be handled by the built-in error handler; the error will be written to the client with the -stack trace. The stack trace is not included in the production environment. - -
      -Set the environment variable `NODE_ENV` to `production`, to run the app in production mode. -
      - -If you call `next()` with an error after you have started writing the -response (for example, if you encounter an error while streaming the -response to the client) the Express default error handler closes the -connection and fails the request. - -So when you add a custom error handler, you will want to delegate to -the default error handling mechanisms in Express, when the headers -have already been sent to the client: - -```js -function errorHandler (err, req, res, next) { - if (res.headersSent) { - return next(err) - } - res.status(500) - res.render('error', { error: err }) -} -``` - -Note that the default error handler can get triggered if you call `next()` with an error -in your code more than once, even if custom error handling middleware is in place. diff --git a/th/guide/migrating-4.md b/th/guide/migrating-4.md deleted file mode 100755 index 957987d9d9..0000000000 --- a/th/guide/migrating-4.md +++ /dev/null @@ -1,606 +0,0 @@ ---- -layout: page -title: Migrating to Express 4 -menu: guide -lang: th ---- -# Moving to Express 4 - -

      Overview

      - -Express 4 is a breaking change from Express 3. That means an existing Express 3 app will _not_ work if you update the Express version in its dependencies. - -This article covers: - - - -

      Changes in Express 4

      - -There are several significant changes in Express 4: - - - -See also: - -* [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) - -

      -Changes to Express core and middleware system -

      - -Express 4 no longer depends on Connect, and removes all built-in -middleware from its core, except for the `express.static` function. This means that -Express is now an independent routing and middleware web framework, and -Express versioning and releases are not affected by middleware updates. - -Without built-in middleware, you must explicitly add all the -middleware that is required to run your app. Simply follow these steps: - -1. Install the module: `npm install --save ` -2. In your app, require the module: `require('module-name')` -3. Use the module according to its documentation: `app.use( ... )` - -The following table lists Express 3 middleware and their counterparts in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Express 3Express 4
      express.bodyParserbody-parser + -multer
      express.compresscompression
      express.cookieSessioncookie-session
      express.cookieParsercookie-parser
      express.loggermorgan
      express.sessionexpress-session
      express.faviconserve-favicon
      express.responseTimeresponse-time
      express.errorHandlererrorhandler
      express.methodOverridemethod-override
      express.timeoutconnect-timeout
      express.vhostvhost
      express.csrfcsurf
      express.directoryserve-index
      express.staticserve-static
      - -Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. - -In most cases, you can simply replace the old version 3 middleware with -its Express 4 counterpart. For details, see the module documentation in -GitHub. - -

      app.use accepts parameters

      - -In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler. -For example: - -```js -app.use('/book/:id', function (req, res, next) { - console.log('ID:', req.params.id) - next() -}) -``` -

      -The routing system -

      - -Apps now implicitly load routing middleware, so you no longer have to -worry about the order in which middleware is loaded with respect to -the `router` middleware. - -The way you define routes is unchanged, but the routing system has two -new features to help organize your routes: - -{: .doclist } -* A new method, `app.route()`, to create chainable route handlers for a route path. -* A new class, `express.Router`, to create modular mountable route handlers. - -

      app.route() method

      - -The new `app.route()` method enables you to create chainable route handlers -for a route path. Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more -information about routes, see [`Router()` documentation](/{{ page.lang }}/4x/api.html#router). - -Here is an example of chained route handlers that are defined by using the `app.route()` function. - -```js -app.route('/book') - .get(function (req, res) { - res.send('Get a random book') - }) - .post(function (req, res) { - res.send('Add a book') - }) - .put(function (req, res) { - res.send('Update the book') - }) -``` - -

      express.Router class

      - -The other feature that helps to organize routes is a new class, -`express.Router`, that you can use 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 middleware in -it, defines some routes, and mounts it on a path on the main app. - -For example, create a router file named `birds.js` in the app directory, -with the following content: - -```js -var express = require('express') -var router = express.Router() - -// middleware specific to this router -router.use(function timeLog (req, res, next) { - console.log('Time: ', Date.now()) - next() -}) -// define the home page route -router.get('/', function (req, res) { - res.send('Birds home page') -}) -// define the about route -router.get('/about', function (req, res) { - res.send('About birds') -}) - -module.exports = router -``` - -Then, load the router module in the app: - -```js -var birds = require('./birds') - -// ... - -app.use('/birds', birds) -``` - -The app will now be able to handle requests to the `/birds` and -`/birds/about` paths, and will call the `timeLog` -middleware that is specific to the route. - -

      -Other changes -

      - -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. -
      - -

      Example app migration

      - -Here is an example of migrating an Express 3 application to Express 4. -The files of interest are `app.js` and `package.json`. - -

      -Version 3 app -

      - -

      app.js

      - -Consider an Express v.3 application with the following `app.js` file: - -```js -var express = require('express') -var routes = require('./routes') -var user = require('./routes/user') -var http = require('http') -var path = require('path') - -var app = express() - -// all environments -app.set('port', process.env.PORT || 3000) -app.set('views', path.join(__dirname, 'views')) -app.set('view engine', 'pug') -app.use(express.favicon()) -app.use(express.logger('dev')) -app.use(express.methodOverride()) -app.use(express.session({ secret: 'your secret here' })) -app.use(express.bodyParser()) -app.use(app.router) -app.use(express.static(path.join(__dirname, 'public'))) - -// development only -if (app.get('env') === 'development') { - app.use(express.errorHandler()) -} - -app.get('/', routes.index) -app.get('/users', user.list) - -http.createServer(app).listen(app.get('port'), function () { - console.log('Express server listening on port ' + app.get('port')) -}) -``` - -

      package.json

      - -The accompanying version 3 `package.json` file might look - something like this: - -```json -{ - "name": "application-name", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "node app.js" - }, - "dependencies": { - "express": "3.12.0", - "pug": "*" - } -} -``` - -

      -Process -

      - -Begin the migration process by installing the required middleware for the -Express 4 app and updating Express and Pug to their respective latest -version with the following command: - -```sh -$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save -``` - -Make the following changes to `app.js`: - -1. The built-in Express middleware functions `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` and - `express.errorHandler` are no longer available on the - `express` object. You must install their alternatives - manually and load them in the app. - -2. You no longer need to load the `app.router` function. - It is not a valid Express 4 app object, so remove the - `app.use(app.router);` code. - -3. Make sure that the middleware functions are loaded in the correct order - load `errorHandler` after loading the app routes. - -

      Version 4 app

      - -

      package.json

      - -Running the above `npm` command will update `package.json` as follows: - -```json -{ - "name": "application-name", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "node app.js" - }, - "dependencies": { - "body-parser": "^1.5.2", - "errorhandler": "^1.1.1", - "express": "^4.8.0", - "express-session": "^1.7.2", - "pug": "^2.0.0", - "method-override": "^2.1.2", - "morgan": "^1.2.2", - "multer": "^0.1.3", - "serve-favicon": "^2.0.1" - } -} -``` - -

      app.js

      - -Then, remove invalid code, load the required middleware, and make other -changes as necessary. The `app.js` file will look like this: - -```js -var http = require('http') -var express = require('express') -var routes = require('./routes') -var user = require('./routes/user') -var path = require('path') - -var favicon = require('serve-favicon') -var logger = require('morgan') -var methodOverride = require('method-override') -var session = require('express-session') -var bodyParser = require('body-parser') -var multer = require('multer') -var errorHandler = require('errorhandler') - -var app = express() - -// all environments -app.set('port', process.env.PORT || 3000) -app.set('views', path.join(__dirname, 'views')) -app.set('view engine', 'pug') -app.use(favicon(path.join(__dirname, '/public/favicon.ico'))) -app.use(logger('dev')) -app.use(methodOverride()) -app.use(session({ - resave: true, - saveUninitialized: true, - secret: 'uwotm8' -})) -app.use(bodyParser.json()) -app.use(bodyParser.urlencoded({ extended: true })) -app.use(multer()) -app.use(express.static(path.join(__dirname, 'public'))) - -app.get('/', routes.index) -app.get('/users', user.list) - -// error handling middleware should be loaded after the loading the routes -if (app.get('env') === 'development') { - app.use(errorHandler()) -} - -var server = http.createServer(app) -server.listen(app.get('port'), function () { - console.log('Express server listening on port ' + app.get('port')) -}) -``` - -
      -Unless you need to work directly with the `http` module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way: - -```js -app.listen(app.get('port'), function () { - console.log('Express server listening on port ' + app.get('port')) -}) -``` -
      - -

      Run the app

      - -The migration process is complete, and the app is now an -Express 4 app. To confirm, start the app by using the following command: - -```sh -$ node . -``` - -Load [http://localhost:3000](http://localhost:3000) - and see the home page being rendered by Express 4. - -

      Upgrading to the Express 4 app generator

      - -The command-line tool to generate an Express app is still - `express`, but to upgrade to the new version, you must uninstall - the Express 3 app generator and then install the new - `express-generator`. - -

      Installing

      - -If you already have the Express 3 app generator installed on your system, -you must uninstall it: - -```sh -$ npm uninstall -g express -``` -Depending on how your file and directory privileges are configured, -you might need to run this command with `sudo`. - -Now install the new generator: - -```sh -$ npm install -g express-generator -``` - -Depending on how your file and directory privileges are configured, -you might need to run this command with `sudo`. - -Now the `express` command on your system is updated to the -Express 4 generator. - -

      Changes to the app generator

      - -Command options and use largely remain the same, with the following exceptions: - -{: .doclist } -* Removed the `--sessions` option. -* Removed the `--jshtml` option. -* Added the `--hogan` option to support [Hogan.js](http://twitter.github.io/hogan.js/). - -

      Example

      - -Execute the following command to create an Express 4 app: - -```sh -$ express app4 -``` - -If you look at the contents of the `app4/app.js` file, you will notice -that all the middleware functions (except `express.static`) that are required for -the app are loaded as independent modules, and the `router` middleware -is no longer explicitly loaded in the app. - -You will also notice that the `app.js` file is now a Node.js module, in contrast to the standalone app that was generated by the old generator. - -After installing the dependencies, start the app by using the following command: - -```sh -$ npm start -``` - -If you look at the npm start script in the `package.json` file, -you will notice that the actual command that starts the app is -`node ./bin/www`, which used to be `node app.js` -in Express 3. - -Because the `app.js` file that was generated by the Express 4 generator -is now a Node.js module, it can no longer be started independently as an app -(unless you modify the code). The module must be loaded in a Node.js file -and started via the Node.js file. The Node.js file is `./bin/www` -in this case. - -Neither the `bin` directory nor the extensionless `www` -file is mandatory for creating an Express app or starting the app. They are -just suggestions made by the generator, so feel free to modify them to suit your -needs. - -To get rid of the `www` directory and keep things the "Express 3 way", -delete the line that says `module.exports = app;` at the end of the -`app.js` file, then paste the following code in its place: - -```js -app.set('port', process.env.PORT || 3000) - -var server = app.listen(app.get('port'), function () { - debug('Express server listening on port ' + server.address().port) -}) -``` - -Ensure that you load the `debug` module at the top of the `app.js` file by using the following code: - -```js -var debug = require('debug')('app4') -``` - -Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`. - -You have now moved the functionality of `./bin/www` back to -`app.js`. This change is not recommended, but the exercise helps you -to understand how the `./bin/www` file works, and why the `app.js` file -no longer starts on its own. diff --git a/th/guide/migrating-5.md b/th/guide/migrating-5.md deleted file mode 100755 index 9299c2d1db..0000000000 --- a/th/guide/migrating-5.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -layout: page -title: Migrating to Express 5 -menu: guide -lang: th ---- -# Moving to Express 5 - -

      Overview

      - -Express 5.0 is still in the alpha release stage, but here is a preview of the changes that will be in the release and how to migrate your Express 4 app to Express 5. - -Express 5 is not very different from Express 4: The changes to the API are not as significant as from 3.0 to 4.0. Although the basic API remains the same, there are still breaking changes; in other words an existing Express 4 program might not work if you update it to use Express 5. - -To install the latest alpha and to preview Express 5, enter the following command in your application root directory: - -```sh -$ npm install express@5.0.0-alpha.2 --save -``` - -You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported. - -

      Changes in Express 5

      - -Here is the list of changes (as of the alpha 2 release ) that will affect you as a user of Express. -See the [pull request](https://github.com/expressjs/express/pull/2237) for a list of all the planned features. - -**Removed methods and properties** - - - -**Changed** - - - -**Improvements** - - - -

      Removed methods and properties

      - -If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5. - -

      app.del()

      - -Express 5 no longer supports the `app.del()` function. If you use this function an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. - -Initially `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. - -

      app.param(fn)

      - -The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. - -

      Pluralized method names

      - -The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: - -`req.acceptsCharset()` is replaced by `req.acceptsCharsets()`. - -`req.acceptsEncoding()` is replaced by `req.acceptsEncodings()`. - -`req.acceptsLanguage()` is replaced by `req.acceptsLanguages()`. - -

      Leading colon (:) in the name for app.param(name, fn)

      - -A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon. - -This should not affect your code if you follow the Express 4 documentation of [app.param](/{{ page.lang }}/4x/api.html#app.param), as it makes no mention of the leading colon. - -

      req.param(name)

      - -This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object. - -

      res.json(obj, status)

      - -Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`. - -

      res.jsonp(obj, status)

      - -Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`. - -

      res.send(body, status)

      - -Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. - -

      res.send(status)

      - -Express 5 no longer supports the signature res.send(status), where _`status`_ is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. -If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature. - -

      res.sendfile()

      - -The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5. - -

      Changed

      - -

      app.router

      - -The `app.router` object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. - -

      req.host

      - -In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5 the port number is maintained. - -

      req.query

      - -In Express 4.7 and Express 5 onwards, the query parser option can accept `false` to disable query string parsing when you want to use your own function for query string parsing logic. - -

      Improvements

      - -

      res.render()

      - -This method now enforces asynchronous behavior for all view engines, avoiding bugs caused by view engines that had a synchronous implementation and that violated the recommended interface. diff --git a/th/guide/routing.md b/th/guide/routing.md deleted file mode 100755 index 4cf90f6227..0000000000 --- a/th/guide/routing.md +++ /dev/null @@ -1,353 +0,0 @@ ---- -layout: page -title: Express routing -menu: guide -lang: th ---- - -# Routing - -_Routing_ refers to how an application's endpoints (URIs) respond to client requests. -For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/basic-routing.html). - -You define routing using methods of the Express `app` object that correspond to HTTP methods; -for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, -see [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/4x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/4x/api.html#app.use) to -specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). - -These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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 fact, the routing methods can more than one callback function as arguments. -With multiple callback functions, it is important to call provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control -to the next callback. - -The following code is an example of a very basic route. - -```js -var express = require('express') -var app = express() - -// respond with "hello world" when a GET request is made to the homepage -app.get('/', function (req, res) { - res.send('hello world') -}) -``` - -

      Route methods

      - -A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class. - -The following code is an example of routes that are defined for the GET and the POST methods to the root of the app. - -```js -// GET method route -app.get('/', function (req, res) { - res.send('GET request to the homepage') -}) - -// POST method route -app.post('/', function (req, res) { - res.send('POST request to the homepage') -}) -``` - -Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. -or a full list, see [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). - -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, POST, PUT, DELETE, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). - -```js -app.all('/secret', function (req, res, next) { - console.log('Accessing the secret section ...') - next() // pass control to the next handler -}) -``` - -

      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. - -The characters `?`, `+`, `*`, and `()` are subsets of their regular expression counterparts. The hyphen (`-`) and the dot (`.`) are interpreted literally by string-based paths. - -If you need to use the dollar character (`$`) in a path string, enclose it escaped within `([` and `])`. For example, the path string for requests at "`/data/$book`", would be "`/data/([\$])book`". - -
      - Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) is a handy tool for testing basic Express routes, although it does not support pattern matching. -
      - -
      -Query strings are not part of the route path. -
      - -Here are some examples of route paths based on strings. - -This route path will match requests to the root route, `/`. - -```js -app.get('/', function (req, res) { - res.send('root') -}) -``` - -This route path will match requests to `/about`. - -```js -app.get('/about', function (req, res) { - res.send('about') -}) -``` - -This route path will match requests to `/random.text`. - -```js -app.get('/random.text', function (req, res) { - res.send('random.text') -}) -``` - -Here are some examples of route paths based on string patterns. - -This route path will match `acd` and `abcd`. - -```js -app.get('/ab?cd', function (req, res) { - res.send('ab?cd') -}) -``` - -This route path will match `abcd`, `abbcd`, `abbbcd`, and so on. - -```js -app.get('/ab+cd', function (req, res) { - res.send('ab+cd') -}) -``` - -This route path will match `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, and so on. - -```js -app.get('/ab*cd', function (req, res) { - res.send('ab*cd') -}) -``` - -This route path will match `/abe` and `/abcde`. - -```js -app.get('/ab(cd)?e', function (req, res) { - res.send('ab(cd)?e') -}) -``` - -Examples of route paths based on regular expressions: - -This route path will match anything with an "a" in the route name. - -```js -app.get(/a/, function (req, res) { - res.send('/a/') -}) -``` - -This route path will match `butterfly` and `dragonfly`, but not `butterflyman`, `dragonflyman`, and so on. - -```js -app.get(/.*fly$/, function (req, res) { - res.send('/.*fly$/') -}) -``` - -

      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 path: /users/:userId/books/:bookId -Request URL: http://localhost:3000/users/34/books/8989 -req.params: { "userId": "34", "bookId": "8989" } -``` - -To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. - -```js -app.get('/users/:userId/books/:bookId', function (req, res) { - res.send(req.params) -}) -``` - -
      -The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). -
      - -Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. - -``` -Route path: /flights/:from-:to -Request URL: http://localhost:3000/flights/LAX-SFO -req.params: { "from": "LAX", "to": "SFO" } -``` - -``` -Route path: /plantae/:genus.:species -Request URL: http://localhost:3000/plantae/Prunus.persica -req.params: { "genus": "Prunus", "species": "persica" } -``` - -To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): - -``` -Route path: /user/:userId(\d+) -Request URL: http://localhost:3000/user/42 -req.params: {"userId": "42"} -``` - -
      -Because the regular expression is usually part of a literal string, be sure to escape any \ characters with an additional backslash, for example \\d+. -
      - -
      -In Express 4.x, the * character in regular expressions is not interpreted in the usual way. As a workaround, use {0,} instead of *. This will likely be fixed in Express 5. -
      - -

      Route handlers

      - -You can provide multiple callback functions that behave like [middleware](/{{ page.lang }}/guide/using-middleware.html) 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. - -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 -app.get('/example/a', function (req, res) { - res.send('Hello from A!') -}) -``` - -More than one callback function can handle a route (make sure you specify the `next` object). For example: - -```js -app.get('/example/b', function (req, res, next) { - console.log('the response will be sent by the next function ...') - next() -}, function (req, res) { - res.send('Hello from B!') -}) -``` - -An array of callback functions can handle a route. For example: - -```js -var cb0 = function (req, res, next) { - console.log('CB0') - next() -} - -var cb1 = function (req, res, next) { - console.log('CB1') - next() -} - -var cb2 = function (req, res) { - res.send('Hello from C!') -} - -app.get('/example/c', [cb0, cb1, cb2]) -``` - -A combination of independent functions and arrays of functions can handle a route. For example: - -```js -var cb0 = function (req, res, next) { - console.log('CB0') - next() -} - -var cb1 = function (req, res, next) { - console.log('CB1') - next() -} - -app.get('/example/d', [cb0, cb1], function (req, res, next) { - console.log('the response will be sent by the next function ...') - next() -}, function (req, res) { - res.send('Hello from D!') -}) -``` - -

      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. - -| Method | Description -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Prompt a file to be downloaded. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | End the response process. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Send a JSON response. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Send a JSON response with JSONP support. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirect a request. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Render a view template. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Send a response of various types. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Send a file as an octet stream. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. - -

      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](/{{ page.lang }}/4x/api.html#router). - -Here is an example of chained route handlers that are defined by using `app.route()`. - -```js -app.route('/book') - .get(function (req, res) { - res.send('Get a random book') - }) - .post(function (req, res) { - res.send('Add a book') - }) - .put(function (req, res) { - res.send('Update the book') - }) -``` - -

      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". - -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 the following content: - -```js -var express = require('express') -var router = express.Router() - -// middleware that is specific to this router -router.use(function timeLog (req, res, next) { - console.log('Time: ', Date.now()) - next() -}) -// define the home page route -router.get('/', function (req, res) { - res.send('Birds home page') -}) -// define the about route -router.get('/about', function (req, res) { - res.send('About birds') -}) - -module.exports = router -``` - -Then, load the router module in the app: - -```js -var birds = require('./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. diff --git a/th/guide/using-middleware.md b/th/guide/using-middleware.md deleted file mode 100644 index 5ecf95cedb..0000000000 --- a/th/guide/using-middleware.md +++ /dev/null @@ -1,244 +0,0 @@ ---- -layout: page -title: Using Express middleware -menu: guide -lang: th ---- -# Using middleware - -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. - -_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/4x/api.html#req) (`req`), the [response object](/{{ page.lang }}/4x/api.html#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 can perform the following tasks: - -* Execute any code. -* Make changes to the request and the response objects. -* End the request-response cycle. -* Call the next middleware function in the stack. - -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. - -An Express application can use the following types of middleware: - - - [Application-level middleware](#middleware.application) - - [Router-level middleware](#middleware.router) - - [Error-handling middleware](#middleware.error-handling) - - [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. - -

      Application-level middleware

      - -Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/4x/api.html#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. - -This example shows a middleware function with no mount path. The function is executed every time the app receives a request. - -```js -var app = express() - -app.use(function (req, res, next) { - console.log('Time:', Date.now()) - next() -}) -``` - -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. - -```js -app.use('/user/:id', function (req, res, next) { - console.log('Request Type:', req.method) - next() -}) -``` - -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', function (req, res, next) { - 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. - -```js -app.use('/user/:id', function (req, res, next) { - console.log('Request URL:', req.originalUrl) - next() -}, function (req, res, next) { - console.log('Request Type:', req.method) - next() -}) -``` - -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. - -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. - -```js -app.get('/user/:id', function (req, res, next) { - console.log('ID:', req.params.id) - next() -}, function (req, res, next) { - res.send('User Info') -}) - -// handler for the /user/:id path, which prints the user ID -app.get('/user/:id', function (req, res, next) { - res.end(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. -**NOTE**: `next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. - -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. - -```js -app.get('/user/:id', function (req, res, next) { - // if the user ID is 0, skip to the next route - if (req.params.id === '0') next('route') - // otherwise pass the control to the next middleware function in this stack - else next() -}, function (req, res, next) { - // render a regular page - res.render('regular') -}) - -// handler for the /user/:id path, which renders a special page -app.get('/user/:id', function (req, res, next) { - res.render('special') -}) -``` - -

      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()`. - -```js -var 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: - -```js -var app = express() -var router = express.Router() - -// a middleware function with no mount path. This code is executed for every request to the router -router.use(function (req, res, next) { - console.log('Time:', Date.now()) - next() -}) - -// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path -router.use('/user/:id', function (req, res, next) { - console.log('Request URL:', req.originalUrl) - next() -}, function (req, res, next) { - console.log('Request Type:', req.method) - next() -}) - -// a middleware sub-stack that handles GET requests to the /user/:id path -router.get('/user/:id', function (req, res, next) { - // if the user ID is 0, skip to the next router - if (req.params.id === '0') next('route') - // otherwise pass control to the next middleware function in this stack - else next() -}, function (req, res, next) { - // render a regular page - res.render('regular') -}) - -// handler for the /user/:id path, which renders a special page -router.get('/user/:id', function (req, res, next) { - console.log(req.params.id) - res.render('special') -}) - -// mount the router on the app -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. - -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. - -```js -var app = express() -var router = express.Router() - -// predicate the router with a check and bail out when needed -router.use(function (req, res, next) { - if (!req.headers['x-auth']) return next('router') - next() -}) - -router.get('/', function (req, res) { - res.send('hello, user!') -}) - -// use the router and 401 anything falling through -app.use('/admin', router, function (req, res) { - res.sendStatus(401) -}) -``` - -

      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 -app.use(function (err, req, res, next) { - console.error(err.stack) - res.status(500).send('Something broke!') -}) -``` - -For details about error-handling middleware, see: [Error handling](/{{ page.lang }}/guide/error-handling.html). - -

      Built-in middleware

      - -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). - -Express has the following built-in middleware functions: - -- [express.static](/en/4x/api.html#express.static) serves static assets such as HTML files, images, and so on. -- [express.json](/en/4x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** -- [express.urlencoded](/en/4x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** - -

      Third-party middleware

      - -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`. - -```sh -$ npm install cookie-parser -``` - -```js -var express = require('express') -var app = express() -var cookieParser = require('cookie-parser') - -// load the cookie-parsing middleware -app.use(cookieParser()) -``` - -For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](../resources/middleware.html). diff --git a/th/guide/using-template-engines.md b/th/guide/using-template-engines.md deleted file mode 100755 index 4e6a06a8b6..0000000000 --- a/th/guide/using-template-engines.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -layout: page -title: Using template engines with Express -menu: guide -lang: th ---- -# Using template engines with Express - -A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces -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. - -Some popular template engines that work with Express are [Pug](https://pugjs.org/api/getting-started.html), -[Mustache](https://www.npmjs.com/package/mustache), and [EJS](https://www.npmjs.com/package/ejs). -The [Express application generator](/{{ page.lang }}/starter/generator.html) uses [Jade](https://www.npmjs.com/package/jade) as its default, but it also supports several others. - -See [Template Engines (Express wiki)](https://github.com/expressjs/express/wiki#template-engines) -for a list of template engines you can use with Express. -See also [Comparing JavaScript Templating Engines: Jade, Mustache, Dust and More](https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/). - -
      -**Note**: Jade has been renamed to [Pug](https://www.npmjs.com/package/pug). You can continue to use Jade in your app, and it will work just fine. However if you want the latest updates to the template engine, you must replace Jade with Pug in your app. -
      - -To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), set in `app.js` in the default app created by the generator: - -* `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: - -```sh -$ npm install pug --save -``` - -
      -Express-compliant template engines such as Jade and Pug export a function named `__express(filePath, options, callback)`, -which is called by the `res.render()` function to render the template code. - -Some template engines do not follow this convention. The [Consolidate.js](https://www.npmjs.org/package/consolidate) -library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express. -
      - -After the view engine is set, you don't have to specify the engine or load the template engine module in your app; -Express loads the module internally, as shown below (for the above example). - -```js -app.set('view engine', 'pug') -``` - -Create a Pug template file named `index.pug` in the `views` directory, with the following content: - -```pug -html - head - title= title - body - h1= message -``` - -Then create a route to render the `index.pug` file. If the `view engine` property is not set, -you must specify the extension of the `view` file. Otherwise, you can omit it. - -```js -app.get('/', function (req, res) { - res.render('index', { title: 'Hey', message: 'Hello there!' }) -}) -``` - -When you make a request to the home page, the `index.pug` file will be rendered as HTML. - -Note: The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. - -To learn more about how template engines work in Express, see: -["Developing template engines for Express"](/{{ page.lang }}/advanced/developing-template-engines.html). diff --git a/th/guide/writing-middleware.md b/th/guide/writing-middleware.md deleted file mode 100755 index 805f97ff2f..0000000000 --- a/th/guide/writing-middleware.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -layout: page -title: Writing middleware for use in Express apps -menu: guide -lang: th ---- -# Writing middleware for use in Express apps - -

      Overview

      - -_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/4x/api.html#req) (`req`), the [response object](/{{ page.lang }}/4x/api.html#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. - -Middleware functions can perform the following tasks: - -* Execute any code. -* Make changes to the request and the response objects. -* End the request-response cycle. -* Call the next middleware in the stack. - -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. - -The following figure shows the elements of a middleware function call: - - - - -
      - - -
      HTTP method for which the middleware function applies.
      - -
      Path (route) for which the middleware function applies.
      - -
      The middleware function.
      - -
      Callback argument to the middleware function, called "next" by convention.
      - -
      HTTP response argument to the middleware function, called "res" by convention.
      - -
      HTTP request argument to the middleware function, called "req" by convention.
      -
      - -

      Example

      - -Here is an example of a simple "Hello World" Express application. -The remainder of this article will define and add two middleware functions to the application: -one called `myLogger` that prints a simple log message and another called `requestTime` that -displays the timestamp of the HTTP request. - -```js -var express = require('express') -var app = express() - -app.get('/', function (req, res) { - res.send('Hello World!') -}) - -app.listen(3000) -``` - -

      Middleware function myLogger

      -Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. The middleware function is assigned to a variable named `myLogger`. - -```js -var myLogger = function (req, res, next) { - console.log('LOGGED') - next() -} -``` - -
      -Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. -The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next". -To avoid confusion, always use this convention. -
      - -To load the middleware function, call `app.use()`, specifying the middleware function. -For example, the following code loads the `myLogger` middleware function before the route to the root path (/). - -```js -var express = require('express') -var app = express() - -var myLogger = function (req, res, next) { - console.log('LOGGED') - next() -} - -app.use(myLogger) - -app.get('/', function (req, res) { - res.send('Hello World!') -}) - -app.listen(3000) -``` - -Every time the app receives a request, it prints the message "LOGGED" to the terminal. - -The order of middleware loading is important: middleware functions that are loaded first are also executed first. - -If `myLogger` is loaded after the route to the root path, the request never reaches it and the app doesn't print "LOGGED", because the route handler of the root path terminates the request-response cycle. - -The middleware function `myLogger` simply prints a message, then passes on the request to the next middleware function in the stack by calling the `next()` function. - -

      Middleware function requestTime

      - -Next, we'll create a middleware function called "requestTime" and add it as a property called `requestTime` -to the request object. - -```js -var requestTime = function (req, res, next) { - req.requestTime = Date.now() - next() -} -``` - -The app now uses the `requestTime` middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to `req` (the request object). - -```js -var express = require('express') -var app = express() - -var requestTime = function (req, res, next) { - req.requestTime = Date.now() - next() -} - -app.use(requestTime) - -app.get('/', function (req, res) { - var responseText = 'Hello World!
      ' - responseText += 'Requested at: ' + req.requestTime + '' - res.send(responseText) -}) - -app.listen(3000) -``` - -When you make a request to the root of the app, the app now displays the timestamp of your request in the browser. - -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. - -For more information about Express middleware, see: [Using Express middleware](/{{ page.lang }}/guide/using-middleware.html). - -

      Configurable middleware

      - -If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. - -File: `my-middleware.js` - -```js -module.exports = function (options) { - return function (req, res, next) { - // Implement the middleware function based on the options object - next() - } -} -``` - -The middleware can now be used as shown below. - -```js -var mw = require('./my-middleware.js') - -app.use(mw({ option1: '1', option2: '2' })) -``` - -Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/th/index.md b/th/index.md deleted file mode 100644 index 4c2cfb4e86..0000000000 --- a/th/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: home -title: Express - เว็บแอปพลิเคชันเฟรมเวอร์คสำหรับ Node.js -menu: home -lang: th ---- -
      - {% include header/header-{{ page.lang }}.html %} -
      -
      -
      - - เว็บแอปพลิเคชันเฟรมเวอร์คที่ รวดเร็ว คล่องตัว และ เรียบง่าย สำหรับ Node.js -
      -
      $ npm install express --save
      -
      -
      - -
      -
      - -
      - {% include announcement/announcement-{{ page.lang }}.md %} -
      - -
      - -
      -
      -

      เว็บแอปพลิเคชัน

      Express เป็น Node.js เว็บแอปพลิเคชันเฟรมเวอร์คที่เรียบง่ายและคล่องตัว สำหรับเว็บและแอปพลิเคชันบนมือถือ ที่มีชุดของคุณสมบัติที่สมบูรณ์ -
      - -
      -

      APIs

      ด้วยเครืองมือสำหรับ HTTP method ที่นับไม่ถ่วน และ ที่จัดการมิดเดิลแวร์ ให้คุณ ทำให้คุณสามารถสร้าง API ที่สมบูรณ์ได้อย่างง่ายและรวดเร็ว -
      - -
      -

      ประสิทธิภาพ

      Express มีชั้นบางๆ ของคุณลักษณะพื้นฐานของเว็บแอปพลิเคชัน โดยไม่ปิดบังคุณสมบัติของ Node.js ที่คุณคุ้นเคยและชื่นชอบ -
      - -
      -

      เฟรมเวอร์ค

      เฟรมเวอร์คยอดนิยมมากยาย ที่มีพื้นฐานจาก Express. -
      -
      - -
      diff --git a/th/resources/community.md b/th/resources/community.md deleted file mode 100755 index 919ad906f0..0000000000 --- a/th/resources/community.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -layout: page -title: Express community -menu: resources -lang: th ---- - -# Community - -## Mailing List - -Join over 2000 Express users or browse over 5000 -discussions in the [Google Group](https://groups.google.com/group/express-js). - -## Gitter - -The [expressjs/express chatroom](https://gitter.im/expressjs/express) is great place -for developers interested in the everyday discussions related to Express. - -## IRC channel - -Hundreds of developers idle in #express on freenode every day. -If you have questions about the framework, jump in for quick -feedback. - -## Issues - -If you've come across what you think is a bug, or just want to make -a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues). - -## Technical committee - -The Express technical committee meets online every two weeks to discuss development and maintenance of Express, and other issues relevant to the Express project. -Each meeting is typically announced in an [expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to the Google Hangout, which is -open to all observers. - -The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). - -Members of the Express technical committee are: - -- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey -- [@crandmck](https://github.com/crandmck) - Rand McKinney -- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson -- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa -- [@jonathanong](https://github.com/jonathanong) - jongleberry -- [@LinusU](https://github.com/LinusU) - Linus Unnebäck -- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce -- [@troygoode](https://github.com/troygoode) - Troy Goode - -## Examples - -View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples) -in the repository covering everything from API design and authentication to template engine integration. - -## Other modules - -Our vibrant community has created a large variety of extensions, -[middleware modules](/{{ page.lang }}/resources/middleware.html) and -[higher-level frameworks](frameworks.html). - -Additionally, the Express community maintains modules in these two GitHub orgs: - -- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). -- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. - -See also the [Express wiki](https://github.com/expressjs/express/wiki). diff --git a/th/resources/companies-using-express.md b/th/resources/companies-using-express.md deleted file mode 100644 index 7af2fe1eab..0000000000 --- a/th/resources/companies-using-express.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -layout: page -title: Companies using Express -menu: resources -lang: th ---- - -# Companies using Express in production - - diff --git a/th/resources/contributing.md b/th/resources/contributing.md deleted file mode 100644 index 06f3896bc4..0000000000 --- a/th/resources/contributing.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -layout: page -title: Contributing to Express -menu: resources -lang: th ---- - -# Contributing to Express - -Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [Node.js Foundation](https://nodejs.org/foundation/). -These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. - -* [Technical committee](#technical-committee) -* [Community contributing guide](#community-contributing-guide) -* [Collaborator's guide](#collaborators-guide) -* [Security policies and procedures](#security-policies-and-procedures) - -## Technical committee - -The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). - -## Community contributing guide - -> NOTE: This is copied from the [Contributing Guide in the repo](https://github.com/expressjs/express/blob/master/Contributing.md). - -The goal of this guide is to create a contribution process that: - -* Encourages new contributions. -* Encourages contributors to remain involved. -* Avoids unnecessary processes and bureaucracy whenever possible. -* Creates a transparent decision making process which makes it clear how -contributors can be involved in decision making. - -This document is based on much prior art in the Node.js community, io.js, -and the Node.js project. - -Vocabulary: - -* A **Contributor** is any individual creating or commenting on an issue or pull request. -* A **Committer** is a subset of contributors who have been given write access to the repository. -* A **TC (Technical Committee)** is a group of committers representing the required technical -expertise to resolve rare disputes. - -### Logging issues - -Log an issue for any question or problem you might have. When in doubt, log an issue, -any additional policies about what to include will be provided in the responses. The only -exception is security dislosures which should be sent privately. - -Committers may direct you to another repository, ask for additional clarifications, and -add appropriate metadata before the issue is addressed. - -Please be courteous, respectful, and every participant is expected to follow the -project's Code of Conduct. - -### Contributions - -Any change to resources in this repository must be through pull requests. This applies to all changes -to documentation, code, binary files, etc. Even long term committers and TC members must use -pull requests. - -No pull request can be merged without being reviewed. - -For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that -contributors in other timezones have time to review. Consideration should also be given to -weekends and other holiday periods to ensure active committers all have reasonable time to -become involved in the discussion and review process if they wish. - -The default for each contribution is that it is accepted once no committer has an objection. -During 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. There is no additional "sign off" -process for contributions to land. Once all issues brought by committers are addressed it can -be landed by any committer. - -In the case of an objection being raised in a pull request by another committer, all involved -committers should seek to arrive at a consensus by way of addressing concerns being expressed -by discussion, compromise on the proposed change, or withdrawal of the proposed change. - -If a contribution is controversial and committers cannot agree about how to get it to land -or if it should land then it should be escalated to the TC. TC members should regularly -discuss pending contributions in order to find a resolution. It is expected that only a -small minority of issues be brought to the TC for resolution and that discussion and -compromise among committers be the default resolution mechanism. - -### Becoming a committer - -All contributors who land a non-trivial contribution should be on-boarded in a timely manner, -and added as a committer, and be given write access to the repository. - -Committers are expected to follow this policy and continue to send pull requests, go through -proper review, and have other committers merge their pull requests. - -### TC process - -The TC uses a "consensus seeking" process for issues that are escalated to the TC. -The group tries to find a resolution that has no open objections among TC members. -If a consensus cannot be reached that has no objections then a majority wins vote -is called. It is also expected that the majority of decisions made by the TC are via -a consensus seeking process and that voting is only used as a last-resort. - -Resolution may involve returning the issue to committers with suggestions on how to -move forward towards a consensus. It is not expected that a meeting of the TC -will resolve all issues on its agenda during that meeting and may prefer to continue -the discussion happening among the committers. - -Members can be added to the TC at any time. Any committer 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. Members who do not participate consistently at the level of -a majority of the other members are expected to resign. - -## Collaborator's guide - -> NOTE: This is copied from the [Collaborator guide in the Express repository](https://github.com/expressjs/express/blob/master/Collaborator-Guide.md). - -### Website Issues - -Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. - -### PRs and code contributions - -* Tests must pass. -* Follow existing coding style. -* If you fix a bug, add a test. - -### Branches - -* Use the `master` branch for bug fixes or minor work that is intended for the current release stream -* Use the correspondingly named branch, e.g. `5.0`, for anything intended for a future release of Express - -### Steps for contributing - -* [Create an issue](https://github.com/expressjs/express/issues/new) for the bug you want to fix or the feature that you want to add. -* Create your own [fork](https://github.com/expressjs/express) on github, then checkout your fork. -* Write your code in your local copy. It's good practice to create a branch for each new issue you work on, although not compulsory. -* To run the test suite, first install the dependencies by running `npm install`, then run `npm test`. -* If the tests pass, you can commit your changes to your fork and then create a pull request from there. Make sure to reference your issue from the pull request comments by including the issue number e.g. #123. - -### Issues which are questions - -We will typically close any vague issues or questions that are specific to some app you are writing. Please double check the docs and other references before being trigger happy with posting a question issue. - -Things that will help get your question issue looked at: - -* Full and runnable JS code. -* Clear description of the problem or unexpected behavior. -* Clear description of the expected result. -* Steps you have taken to debug it yourself. - -If you post a question and do not outline the above items or make it easy for us to understand and reproduce your issue, it will be closed. - -## Security Policies and Procedures - -> NOTE: This is copied from [Security Policies and Procedures in the Express repository](https://github.com/expressjs/express/blob/master/Security.md). - -This document outlines security procedures and general policies for the Express -project. - - * [Reporting a Bug](#reporting-a-bug) - * [Disclosure Policy](#disclosure-policy) - * [Comments on this Policy](#comments-on-this-policy) - -### Reporting a Bug - -The Express team and community take all security bugs in Express seriously. -Thank you for improving the security of Express. We appreciate your efforts and -responsible disclosure and will make every effort to acknowledge your -contributions. - -Report security bugs by emailing the lead maintainer in the Readme.md file. - -The lead maintainer will acknowledge your email within 48 hours, and will send a -more detailed response within 48 hours indicating the next steps in handling -your report. After the initial reply to your report, the security team will -endeavor to keep you informed of the progress towards a fix and full -announcement, and may ask for additional information or guidance. - -Report security bugs in third-party modules to the person or team maintaining -the module. You can also report a vulnerability through the -[Node Security Project](https://nodesecurity.io/report). - -### Disclosure Policy - -When the security team receives a security bug report, they will assign it to a -primary handler. This person will coordinate the fix and release process, -involving the following steps: - - * Confirm the problem and determine the affected versions. - * Audit code to find any potential similar problems. - * Prepare fixes for all releases still under maintenance. These fixes will be - released as fast as possible to npm. - -### Comments on this Policy - -If you have suggestions on how this process could be improved please submit a -pull request. diff --git a/th/resources/frameworks.md b/th/resources/frameworks.md deleted file mode 100644 index e996419e53..0000000000 --- a/th/resources/frameworks.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -layout: page -title: Frameworks built on Express -menu: frameworks -lang: th ---- - -# Frameworks built on Express - -Several popular Node.js frameworks are built on Express: - -- **[Feathers](http://feathersjs.com)**: Build prototypes in minutes and production ready real-time apps in days. -- **[ItemsAPI](https://www.itemsapi.com/)**: Search backend for web and mobile applications built on Express and Elasticsearch. -- **[KeystoneJS](http://keystonejs.com/)**: Website and API Application Framework / CMS with an auto-generated React.js Admin UI. -- **[Kraken](http://krakenjs.com/)**: Secure and scalable layer that extends Express by providing structure and convention. -- **[LEAN-STACK](http://lean-stack.io)**: The Pure JavaScript Stack. -- **[LoopBack](http://loopback.io)**: Highly-extensible, open-source Node.js framework for quickly creating dynamic end-to-end REST APIs. -- **[MEAN](http://mean.io/)**: Opinionated fullstack JavaScript framework that simplifies and accelerates web application development. -- **[Sails](http://sailsjs.org/)**: MVC framework for Node.js for building practical, production-ready apps. -- **[Bottr](http://bottr.co/)**: Framework that simplifies building chatbot applications. -- **[Hydra-Express](https://github.com/flywheelsports/fwsp-hydra-express)**: Hydra-Express is a light-weight library which facilitates building Node.js Microservices using ExpressJS. -- **[Blueprint](http://github.com/onehilltech/blueprint)**: Highly-configurable MVC framework for composing production-ready services from reusable components -- **[Locomotive](http://locomotivejs.org/)**: Powerful MVC web framework for Node.js from the maker of Passport.js -- **[graphql-yoga](https://github.com/graphcool/graphql-yoga)**: Fully-featured, yet simple and lightweight GraphQL server diff --git a/th/resources/glossary.md b/th/resources/glossary.md deleted file mode 100755 index 135c898823..0000000000 --- a/th/resources/glossary.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -layout: page -title: Express glossary -menu: resources -lang: th ---- - -# Glossary - -### application - -In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/{{ page.lang }}/api.html#express). - -### API - -Application programming interface. Spell out the abbreviation when it is first used. - -### Express - -A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable. - -### libuv - -A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js. - -### middleware - -A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: - - * `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware. - * `app.use(mw)` is called _adding the middleware to the global processing stack_. - * `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_. - -### Node.js - -A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". - -### open-source, open source - -When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Note: Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. - -### request - -An HTTP request. A client submits an HTTP request message to a server, which returns a response. 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 - -An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body. - -### route - -Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route. - -### router - -See [router](/{{ page.lang }}/api.html#router) in the API reference. diff --git a/th/resources/learning.md b/th/resources/learning.md deleted file mode 100644 index 267f1630f5..0000000000 --- a/th/resources/learning.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -layout: page -title: การเรียนรู้เพิ่มเติม -menu: resources -lang: th ---- - -# การเรียนรู้เพิ่มเติม - -
      Disclaimer: Unendorsed community content.
      - -## Books - -Here are a few of the many books on Express: - -- **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, April 2016. - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Getting MEAN with Mongo, Express, Angular, and Node, Second Edition](http://www.manning.com/sholmes2/)**, -Manning Publications, April 2017. - - **[Pro Express.js: Master Express.js: The Node.js Framework For Your Web Development](http://www.apress.com/9781484200384)**, -Apress, December 2014. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](https://strongloop.com/strongblog/tag_Express.html) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Node-tricks Blog: Express category](http://node-tricks.com/category/express/) -- [Baboon Blog: Express category](http://www.baboon.ir/tutorials/expressjs/) (Persian language) -- [Techforgeek Blog: Express category](http://techforgeek.com/expressjs/) -- [RoseHosting.com Blog: Express tag](https://www.rosehosting.com/blog/tag/express/) -- [ThisHosting.Rocks: Express tag](https://thishosting.rocks/tag/express-js/) -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/th/resources/middleware.md b/th/resources/middleware.md deleted file mode 100755 index ea21ad56ad..0000000000 --- a/th/resources/middleware.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -layout: middleware -title: Express middleware -menu: resources -lang: th -module: mw-home ---- - -## Express middleware - -The Express middleware modules listed here are maintained by the -[Expressjs team](https://github.com/orgs/expressjs/people). - -|Middleware module | Description | Replaces built-in function (Express 3)| -|---------------------------|---------------------|----------------------| -| [body-parser](/resources/middleware/body-parser.html) | Parse HTTP request body. See also: [body](https://github.com/raynos/body), [co-body](https://github.com/visionmedia/co-body), and [raw-body](https://github.com/stream-utils/raw-body). | express.bodyParser | -| [compression](/resources/middleware/compression.html) | Compress HTTP responses. | express.compress | -| [connect-rid](/resources/middleware/connect-rid.html) | Generate unique request ID. | NA | -| [cookie-parser](/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies) and [keygrip](https://github.com/jed/keygrip). | express.cookieParser| -| [cookie-session](/resources/middleware/cookie-session.html) | Establish cookie-based sessions.| express.cookieSession | -| [cors](/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options.| NA -| [csurf](/resources/middleware/csurf.html) | Protect from CSRF exploits.|express.csrf | -| [errorhandler](/resources/middleware/errorhandler.html) |Development error-handling/debugging. |express.errorHandler | -| [method-override](/resources/middleware/method-override.html) |Override HTTP methods using header. |express.methodOverride | -| [morgan](/resources/middleware/morgan.html) | HTTP request logger. | express.logger | -| [multer](/resources/middleware/multer.html) | Handle multi-part form data. | express.bodyParser | -| [response-time](/resources/middleware/response-time.html) | Record HTTP response time. |express.responseTime | -| [serve-favicon](/resources/middleware/serve-favicon.html) | Serve a favicon. |express.favicon | -| [serve-index](/resources/middleware/serve-index.html) | Serve directory listing for a given path.| express.directory | -| [serve-static](/resources/middleware/serve-static.html) |Serve static files. |express.static | -| [session](/resources/middleware/session.html) | Establish server-based sessions (development only). | express.session | -| [timeout](/resources/middleware/timeout.html) | Set a timeout period for HTTP request processing.|express.timeout | -| [vhost](/resources/middleware/vhost.html) |Create virtual domains.|express.vhost| - -## Additional middleware modules - -These are some additional popular middleware modules. - -|Middleware module | Description | -|---------------------------|---------------------| -| [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus) | Optimize image serving. Switches images to `.webp` or `.jxr`, if possible.| -| [express-debug](https://github.com/devoidfury/express-debug) | Development tool that adds information about template variables (locals), current session, and so on.| -| [express-partial-response](https://github.com/nemtsov/express-partial-response) | Filters out parts of JSON responses based on the `fields` query-string; by using Google API's Partial Response.| -| [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn) | Use a CDN for static assets, with multiple host support.| -| [express-slash](https://github.com/ericf/express-slash) | Handles routes with and without trailing slashes.| -| [express-stormpath](https://github.com/stormpath/stormpath-express) | User storage, authentication, authorization, SSO, and data security.| -| [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize) | Redirects HTTP requests containing uppercase to a canonical lowercase form.| -| [helmet](https://github.com/helmetjs/helmet) |Helps secure your apps by setting various HTTP headers.| -| [join-io](https://github.com/coderaiser/join-io) | Joins files on the fly to reduce the requests count.| -| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [http://passportjs.org/](http://passportjs.org/) for more information.| -| [static-expiry](https://github.com/paulwalker/connect-static-expiry) | Fingerprint URLs or caching headers for static assets.| -| [view-helpers](https://github.com/madhums/node-view-helpers) | Common helper methods for views.| -| [sriracha-admin](https://github.com/hdngr/siracha) | Dynamically generate an admin site for Mongoose. | - -For more middleware modules, see [http-framework](https://github.com/Raynos/http-framework#modules). diff --git a/th/resources/middleware/body-parser.md b/th/resources/middleware/body-parser.md deleted file mode 100644 index b142f25860..0000000000 --- a/th/resources/middleware/body-parser.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express body-parser middleware -menu: resources -lang: en -module: body-parser ---- diff --git a/th/resources/middleware/compression.md b/th/resources/middleware/compression.md deleted file mode 100644 index 0907a7df4f..0000000000 --- a/th/resources/middleware/compression.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express compression middleware -menu: resources -lang: en -module: compression ---- diff --git a/th/resources/middleware/connect-rid.md b/th/resources/middleware/connect-rid.md deleted file mode 100644 index d95420263d..0000000000 --- a/th/resources/middleware/connect-rid.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express connect-rid middleware -menu: resources -lang: en -module: connect-rid ---- diff --git a/th/resources/middleware/cookie-parser.md b/th/resources/middleware/cookie-parser.md deleted file mode 100644 index c1ce24a5c5..0000000000 --- a/th/resources/middleware/cookie-parser.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express cookie-parser middleware -menu: resources -lang: en -module: cookie-parser ---- diff --git a/th/resources/middleware/cookie-session.md b/th/resources/middleware/cookie-session.md deleted file mode 100644 index 76d978ccad..0000000000 --- a/th/resources/middleware/cookie-session.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express cookie-session middleware -menu: resources -lang: en -module: cookie-session ---- diff --git a/th/resources/middleware/cors.md b/th/resources/middleware/cors.md deleted file mode 100644 index 65b6b4b939..0000000000 --- a/th/resources/middleware/cors.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express cors middleware -menu: resources -lang: en -module: cors ---- diff --git a/th/resources/middleware/csurf.md b/th/resources/middleware/csurf.md deleted file mode 100644 index 03f23fdfbf..0000000000 --- a/th/resources/middleware/csurf.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express csurf middleware -menu: resources -lang: en -module: csurf ---- diff --git a/th/resources/middleware/errorhandler.md b/th/resources/middleware/errorhandler.md deleted file mode 100644 index acc252ef85..0000000000 --- a/th/resources/middleware/errorhandler.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express errorhandler middleware -menu: resources -lang: en -module: errorhandler ---- diff --git a/th/resources/middleware/method-override.md b/th/resources/middleware/method-override.md deleted file mode 100644 index e276b6eace..0000000000 --- a/th/resources/middleware/method-override.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express method-override middleware -menu: resources -lang: en -module: method-override ---- diff --git a/th/resources/middleware/morgan.md b/th/resources/middleware/morgan.md deleted file mode 100644 index 9a01e52f9d..0000000000 --- a/th/resources/middleware/morgan.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express morgan middleware -menu: resources -lang: en -module: morgan ---- diff --git a/th/resources/middleware/multer.md b/th/resources/middleware/multer.md deleted file mode 100644 index 5dfa0f8e47..0000000000 --- a/th/resources/middleware/multer.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express multer middleware -menu: resources -lang: en -module: multer ---- diff --git a/th/resources/middleware/response-time.md b/th/resources/middleware/response-time.md deleted file mode 100644 index 6f42eba9ca..0000000000 --- a/th/resources/middleware/response-time.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express response-time middleware -menu: resources -lang: en -module: response-time ---- diff --git a/th/resources/middleware/serve-favicon.md b/th/resources/middleware/serve-favicon.md deleted file mode 100644 index 5268ce1c50..0000000000 --- a/th/resources/middleware/serve-favicon.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express serve-favicon middleware -menu: resources -lang: en -module: serve-favicon ---- diff --git a/th/resources/middleware/serve-index.md b/th/resources/middleware/serve-index.md deleted file mode 100644 index 06f3e89de2..0000000000 --- a/th/resources/middleware/serve-index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express serve-index middleware -menu: resources -lang: en -module: serve-index ---- diff --git a/th/resources/middleware/serve-static.md b/th/resources/middleware/serve-static.md deleted file mode 100644 index 9c7afaa31e..0000000000 --- a/th/resources/middleware/serve-static.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express serve-static middleware -menu: resources -lang: en -module: serve-static ---- diff --git a/th/resources/middleware/session.md b/th/resources/middleware/session.md deleted file mode 100644 index eda9faa738..0000000000 --- a/th/resources/middleware/session.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express session middleware -menu: resources -lang: en -module: session ---- diff --git a/th/resources/middleware/timeout.md b/th/resources/middleware/timeout.md deleted file mode 100644 index 54de8855cd..0000000000 --- a/th/resources/middleware/timeout.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express timeout middleware -menu: resources -lang: en -module: timeout ---- diff --git a/th/resources/middleware/vhost.md b/th/resources/middleware/vhost.md deleted file mode 100644 index 57bdb266ef..0000000000 --- a/th/resources/middleware/vhost.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: middleware -title: Express vhost middleware -menu: resources -lang: en -module: vhost ---- diff --git a/th/resources/utils.md b/th/resources/utils.md deleted file mode 100644 index 8ce9386f45..0000000000 --- a/th/resources/utils.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -layout: page -title: Express utilities -menu: resources -lang: th ---- - -## 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-match](https://www.npmjs.com/package/path-match) | Thin wrapper around [path-to-regexp](https://github.com/component/path-to-regexp) to make extracting parameter names easier.| -| [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. | -| [routington](https://www.npmjs.com/package/routington) | Trie-based URL router for defining and matching URLs. | -| [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.| -| [templation](https://www.npmjs.com/package/templation) | View system similar to `res.render()` inspired by [co-views](https://github.com/visionmedia/co-views) and [consolidate.js](https://github.com/visionmedia/consolidate.js/). | - - -For additional low-level HTTP-related modules, see [jshttp](http://jshttp.github.io/) . diff --git a/th/starter/basic-routing.md b/th/starter/basic-routing.md deleted file mode 100755 index 59b12c1bef..0000000000 --- a/th/starter/basic-routing.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -layout: page -title: Express basic routing -menu: starter -lang: th ---- - -# เส้นทางเบื้องต้น - -_เส้นทาง (Routing)_ เป็นการกำหนดการอ้างอิงว่าแอปพลิเคชันจะตอบสนองต่อคำร้องขอของเครื่องลูกข่ายที่มายังปลายทาง (endpoint) โดยเฉพาะได้อย่างไร ซึ่งเป็น URI (หรือ path) และวิธีการร้องขอ HTTP (GET, POST, และ อื่นๆ) - -แต่ละเส้นทางสามารถมีได้มากกว่าหนึ่งฟังชันส์จัดการ (handler function) ซึ่งสามารถดำเนินการเมื่อเส้นทางถูกจับคู่ - -การกำหนดเส้นทางใช้โครงสร้างดังนี้: - -```js -app.METHOD(PATH, HANDLER) -``` - -เมื่อ: - -- `app` เป็นอินสแตนซ์ของ `express`. -- `METHOD` เป็น [HTTP request method](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods), เป็นตัวพิมพ์เล็ก. -- `PATH` เป็นเส้นทางบนเซิร์ฟเวอร์. -- `HANDLER` เป็นฟังชันส์ที่กระทำเมื่อเส้นทางถูกจับคู่. - -
      -การสอนนี้จะสมมติว่าอินสแตนซ์ของ `express` ชื่อว่า `app` จะถูกสร้างขึ้นเมื่อรันเซิร์ฟเวอร์ ถ้าไม่คุ้นเคยกับการสร้าง app และโครงสร้างของมัน ดูเพิ่มเติมได้ที่ [ตัวอย่าง Hello world](/{{ page.lang }}/starter/hello-world.html) -
      - -ตัวอย่างดังต่อไปนี้จะแสดงให้เห็นการกำหนดเส้นทางอย่างง่าย - -ตอบสนองด้วยข้อความ `Hello World!` บนเพจหลัก: - -```js -app.get('/', function (req, res) { - res.send('Hello World!') -}) -``` - -ตอบสนองต่อการร้องขอด้วยวิธี POST บนเส้นทาง root (`/`) บนเพจหลักของแอปพลิเคชัน: - -```js -app.post('/', function (req, res) { - res.send('Got a POST request') -}) -``` - -ตอบสนองต่อการร้องขอด้วยวิธี PUT บนเส้นทาง `/user`: - -```js -app.put('/user', function (req, res) { - res.send('Got a PUT request at /user') -}) -``` - -ตอบสนองต่อการร้องขอด้วยวิธี DELETE บนเส้นทาง `/user`: - -```js -app.delete('/user', function (req, res) { - res.send('Got a DELETE request at /user') -}) -``` -สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดเส้นทาง ดูได้ที่ [คำแนะนำการกำหนดเส้นทาง](/{{ page.lang }}/guide/routing.html) diff --git a/th/starter/faq.md b/th/starter/faq.md deleted file mode 100755 index 218ecebd70..0000000000 --- a/th/starter/faq.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -layout: page -title: Express FAQ -menu: starter -lang: th ---- - -# คำถามที่พบบ่อย - -## โครงสร้างแอปพลิเคชันของผมควรจะเป็นอย่าไร? - -ไม่มีการกำหนดนิยามของคำตอบสำหรับคำถามนี้ คำตอบขึ้นอยู่กับว่าขนาดของแอปพลิเคชันเท่าใด -และทีมงานที่ร่วมทำงานด้วยมีจำนวนขนาดไหน เพื่อที่จะทำงานคล่องตัวที่สุด Express ไม่มีข้อบังคับของโครงสร้าง - -เส้นทางและตรรกะเฉพาะแอปพลิเคชัน (application-specific) อื่นๆ สามารถทำงานในหลากหลายไฟล์ที่คุณต้องการ -ในหลายๆ ไดเรกเทอรีที่คุณต้องการ สามารถดูตัวอย่างด้านล่างนี้เพื่อเป็นแนวทาง: - -* [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc) - -ยังมีแหล่งตัวอย่างอื่นๆ สำหรับ Express ซึ่งทำให้ง่ายโดยใช้รูปแบบ: - -* [Resourceful routing](https://github.com/expressjs/express-resource) - -## จะกำหมดโมเกลอย่างไร? - -Express ไม่มีความคิดของฐานข้อมูล แนวคิดนี้อยู่ในโมดูลอื่นของ Node ที่จะทำให้คุณติดต่อกับหลากหลายฐานข้อมูล - -ดู [LoopBack](http://loopback.io) for an Express-based framework that is centered around models. - -## จะพิสูจน์ตัวตนของผู้ใช้งานได้อย่างไร? - -การพิสูจน์ตัวตนของผู้ใช้งานเป็นอีกส่วนหนี่งที่ Express ไม่ได้เข้าร่วม คุณอาจใช้รูปแบบพิสูจน์ตัวตนของผู้ใช้งานที่คุณต้องการ -สำหรับตัวอย่างที่ง่ายที่สุดคือรูปแบบ username / password, ดู [ตัวอย่างนี้](https://github.com/expressjs/express/tree/master/examples/auth) - - -## template engines ไหนบ้างที่ Express รองรับ? - -Express รองรับทุก template engine ที่สอดคล้องกับ `(path, locals, callback)` -เพื่อสร้างอินเทอร์เฟสสำหรับ template engine และการเคช ดูที่ [consolidate.js](https://github.com/visionmedia/consolidate.js) -โครงการที่รองรับ ที่ไม่อยู่ในรายการ template engines อาจยังคงรองรับโดย Express - -สำหรับข้อมูลเพิ่มเติม, ดูที่ [การใช้ template engine กับ Express](/{{page.lang}}/guide/using-template-engines.html) - -## จะจัดการกับการตอบสนอง 404 ได้อย่างไร? - -ใน Express, การตอบสนอง 404 ไม่ใช้ผลของความผิดพลาด ดังนั้น -มิดเดิลแวร์ที่จัดการกับความผิดพลาด (error-handler) จะไม่ตรวจจับมัน พฤติกรรมเป็นแบบนี้ -เพราะว่าการตอบสนอง 404 เป็นการบ่งชี้ว่ามีสิ่งผิดปรกติเกิดขึ้นอาจจะต้อมีสิ่งเพิ่มเติมมาจัดการ -ในงานอื่นๆ Express จะดำเนินการฟังก์ชันมิดเดิลแวร์และเส้นทางทั้งหมด และพบว่าไม่มีอะไรที่จะตอบสนอง -สิ่งที่คุณต้องทำคือเพิ่มฟังก์ชันมิดเดิลแวร์ที่ด้านล่างสุดเพื่อจัดการกับการตอบสนอง 404: - -```js -app.use(function (req, res, next) { - res.status(404).send("Sorry can't find that!") -}) -``` - -## จะตั้งค่าจัดการความผิดพลาดได้อย่างไร? - -กำหนดมิดเดิลแวร์จัดการความผิดพลาด (error-handler) เช่นเดียวกับมิดเดิลแวร์อื่น ยกเว้นอาร์กิวเมนต์ 4 ตัวแทนที่จะเป็น 3 ตัว -ดังนี้ `(err, req, res, next)` - -```js -app.use(function (err, req, res, next) { - console.error(err.stack) - res.status(500).send('Something broke!') -}) -``` - -สำหรับข้อมูลเพิ่มเติม, ดูที่ [Error handling](/{{ page.lang }}/guide/error-handling.html). - -## จะสร้าง HTML ธรรมดาได้อย่างไร? - -คุณไม่ต้อง! ไม่จำเป็นต้องสร้าง HTML ด้วยฟังก์ชัน `res.render()` -ถ้าคุณมีไฟล์เฉพาะ ใช้ฟังก์ชัน `res.sendFile()` ถ้าคุณต้องการบริการหลายสินทรัพย์จากไดเรกเทอรี ใช้ฟังก์ชันมิดเดิลแวร์ `express.static()` diff --git a/th/starter/generator.md b/th/starter/generator.md deleted file mode 100755 index 34635be6e6..0000000000 --- a/th/starter/generator.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -layout: page -title: Express application generator -menu: starter -lang: th ---- - -# เครื่องมือสร้าง Express - -ใช้เครื่องมือสร้าง โดยพินพ์คำสั่ง `express-generator` เพื่อสร้างโครงสร้างหลักของแอปพลิเคชันอย่างรวดเร็ว - -`express-generator` ติดตั้งแพ็กเกจไปยังชุดคำสั่ง `express` ใช้คำสั่งด้านล่างนี้เพื่อติดตั้ง: - -```sh -$ npm install express-generator -g -``` -แสดงตัวเลือกคำสั่งทั้งหมดด้วย `h`: - -```sh -$ express -h - - Usage: express [options] [dir] - - Options: - - -h, --help output usage information - --version output the version number - -e, --ejs add ejs engine support - --hbs add handlebars engine support - --pug add pug engine support - -H, --hogan add hogan.js engine support - --no-view generate without view engine - -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) - -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css) - --git add .gitignore - -f, --force force on non-empty directory -``` -สำหรับตัวอย่าง คำสั่งข้างล่างนี้เพื่อสร้าง Express app ที่ชื่อว่า _myapp_ โดยจะสร้างโฟล์เดอร์ชื่อ _myapp_ ในไดเรกเทอรีที่ใช้งานอยู่ และตั้ง view engine เป็น Pug: - -```sh -$ express --view=pug myapp - - create : myapp - create : myapp/package.json - create : myapp/app.js - create : myapp/public - create : myapp/public/javascripts - create : myapp/public/images - create : myapp/routes - create : myapp/routes/index.js - create : myapp/routes/users.js - create : myapp/public/stylesheets - create : myapp/public/stylesheets/style.css - create : myapp/views - create : myapp/views/index.pug - create : myapp/views/layout.pug - create : myapp/views/error.pug - create : myapp/bin - create : myapp/bin/www -``` -แล้วติดตั้งโมดูลเกี่ยวโยง (dependencies): - -```sh -$ cd myapp -$ npm install -``` - -บน MacOS หรือ Linux รัน app ด้วยคำสั่งนี้: - -```sh -$ DEBUG=myapp:* npm start -``` - -บน Windows ใช้คำสั่งนี้: - -```sh -> set DEBUG=myapp:* & npm start -``` - -แล้วโหลด `http://localhost:3000/` ในเว็บเบราว์เซอร์ของคุณเพื่อเข้าถึง app - -หลังจากสร้าง app แล้วจะได้โครงสร้างไดเรกทอรีดังนี้: - -```sh -. -├── app.js -├── bin -│ └── www -├── package.json -├── public -│ ├── images -│ ├── javascripts -│ └── stylesheets -│ └── style.css -├── routes -│ ├── index.js -│ └── users.js -└── views - ├── error.pug - ├── index.pug - └── layout.pug - -7 directories, 9 files -``` - -
      -โครงสร้าง app ที่สร้างโดยเครื่องมือสร้างเป็นเพียงวิธีหนึ่งของอีกหลายวิธี ของการสร้างโครงสร้าง app ของ Express สามารถใช้โครงสร้างนี้ได้ หรือว่าจะแก้ไขเพื่อให้เหมาะสมที่สุดสำหรับความต้องการของคุณ -
      diff --git a/th/starter/hello-world.md b/th/starter/hello-world.md deleted file mode 100755 index 3e3ac38c47..0000000000 --- a/th/starter/hello-world.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -layout: page -title: Express "Hello World" example -menu: starter -lang: th ---- - -# ตัวอย่าง Hello world - -
      -โค้ดด้านล่างนี้เป็นแอปพลิเคชัน Express จำเป็นแบบง่ายที่สุดที่คุณสามารถสร้างขึ้นได้ โดยเป็นไฟล์ app ไฟล์เดียว — _ไม่ใช้_ โค้ดที่ได้จาก [Express generator](/{{ page.lang }}/starter/generator.html) ที่สร้างโครงสร้างเริ่มต้นสำหรับแอปพลิเคชันตัวเต็มที่มีไฟล์ JavaScript มากมาย และไดเรทอรีย่อยสำหรับวัตถุประสงค์ต่างๆ -
      - - -
      
      -const express = require('express')
      -const app = express()
      -const port = 3000
      -
      -app.get('/', (req, res) => {
      -  res.send('Hello World!')
      -})
      -
      -app.listen(port, () => {
      -  console.log(`Example app listening at http://localhost:${port}`)
      -})
      -
      - -app นี้จะเริ่มต้นเซิร์ฟเวอร์และเฝ้าตรวจสอบ (listen) การเชื่อมต่อที่พอร์ต 3000 โดยที่ app จะตอบสนองด้วงคำว่า "Hello World!" สำหรับการร้องขอ -มายัง root URL (`/`) หรือ _route_ แต่สำหรับ path อื่นๆ app จะตอบสนองด้วย **404 Not Found** - -ตัวอย่างด้านบนเป็นเซิร์ฟเวอร์ที่ทำงานได้จริง โดยกดไปที่ลิงค์ URL ที่แสดงอยู่จะเปิดหน้าเว็บใหม่และตอบสนองคำร้องขอของคุณอย่างทันที และสิ่งที่คุณแก้ไขจะเปลี่ยนแปลงที่หน้าเว็บ เพียงกดไปที่ลิงค์อีกครั้ง ได้รับการสนับสนุนจาก [RunKit](https://runkit.com) ซึ่งให้การเชื่อมต่อ interactive JavaScript playground สำหรับสิ่งแวดล้อมที่สมบูรณ์ของ Node บนเว็บเบราว์เซอร์ คำสั่งด้านล้างสำหรับรัน app เดียวกันบนเครื่องของคุณ - -
      -RunKit เป็นบริการของบริษัทอื่นที่ไม่ใช้หน่วยงานของโครงการ Express -
      - -### รันบนเครื่องของคุณ - -เริ่มต้นด้วยการสร้างไดเรกทอรีชื่อว่า `myapp` เปลี่ยนไปที่ไดเรกทอรีที่สร้างขึ้นแล้วใสคำสั่ง `npm init` แล้วติดตั้ง `express` และ dependency ต่างๆ ดัง[ขั้นตอนการติดตั้ง](/{{ page.lang }}/starter/installing.html) - -ในไดเรกทอรี `myapp` สร้างไฟล์ `app.js` ขึ้นมาและคัดลอกโค้ดจากตัวอย่างข้างบนมากใส่ในไฟล์ - -
      -`req` (คำร้องขอ) และ `res` (คำตอบสนอง) เป็นอ็อบเจกต์เดียวกันที่จัดให้โดย Node ซึ่งคุณสมารถเรียกใช้ `req.pip()` `req.on('data', callback)` และอื่นๆ โดยไม่ต้องเรียกใช้ Express -
      - -รัน app ด้วยคำสั่งนี้: - -```sh -$ node app.js -``` - -แล้วโหลด `http://localhost:3000/` ในเว็บเบราว์เซอร์เพื่อดูผลลัพธ์ diff --git a/th/starter/installing.md b/th/starter/installing.md deleted file mode 100755 index 0109802b31..0000000000 --- a/th/starter/installing.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: page -title: Installing Express -menu: starter -lang: th ---- - -# การติดตั้ง - -สมมุติว่าคุณได้ติดตั้ง [Node.js](https://nodejs.org/) ในเครื่องคุณเรียบร้อยแล้ว ใช้คำสั่งข้างล่างนี้เพื่อสร้างไดเรกทอรีสำหรับเก็บแอปพลิเคชันของคุณ และใช้เป็นเก็บไฟล์ที่จะสร้างขึ้นต่อไป - -```sh -$ mkdir myapp -$ cd myapp -``` - -ใช้คำสั่ง `npm init` เพื่อสร้างไฟล์ `package.json` สำหรับแอปพลิเคชันของคุณ - -สำหรับข้อมูลเพิ่มเติมว่า `package.json` ทำงานอย่างไร สำมารถดูได้ที่ [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json) - -```sh -$ npm init -``` - -หลังจากใส่คำสั่งนี้จะมีข้อความพร้อมรับให้คุณใส่ข้อมูลต่างๆ สำหรับการสร้างแอปพลิเคชัน เช่น ชื่อและรุ่นของแอปพลิเคชันของคุณ -สำหรับตอนนี้ คุณเพียงแต่กดปุ่ม ENTER เพื่อใช้ค่าเริ่มต้นของข้อมูลส่วนต่างๆ ยกเว้นข้อมูลดังต่อไปนี้ - -```sh -entry point: (index.js) -``` - -ใส่ `app.js` หรือชื่ออะไรก็ตามที่คุณต้องการสำหรับไฟล์หลักที่จะสร้าง ถ้าคุณต้องการใช้ค่าเริ่มต้นเป็น `index.js` เพียงกดปุ่ม ENTER เพื่อรับค่าเริ่มต้นของไฟล์หลักที่แนะนำ - -ต่อไปเป็นการติดตั้ง Express ในไดเรกเทอรี `myapp` และบันทึกไว้ในรายการเกี่ยวโยง (dependencies list) ตัวอย่างเช่น: - -```sh -$ npm install express --save -``` -สามารถติดตั้ง Express ชั่วคราวได้โดยไม่ใส่ไว้ในรายการเกี่ยวโยง ด้วยคำสั่ง: - -```sh -$ npm install express --no-save -``` - -
      -โดยค่าเริ่มต้นของ npm รุ่นที่ 5.0 ขึ้นไป คำสั่ง `npm install` เพิ่มโมดูลต่างๆ ไปที่รายการ `dependencies` ในไฟล์ `package.json` ถ้าเป็นรุ่นแรกๆ ของ npm คุณจำเป็นต้องใส่คำสั่ง `--save` ไปพร้อมกับคำสั่ง `npm install` ซึ่อหลังจากนี้ใช้คำสั่ง `npm install` ในไดเรกเทอรีของคุณ จะติดตั้งโมดูลที่อยู่ในรายการ dependencies โดยอัตโนมัติ -
      diff --git a/th/starter/static-files.md b/th/starter/static-files.md deleted file mode 100755 index ec00bcb7a2..0000000000 --- a/th/starter/static-files.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -layout: page -title: Serving static files in Express -menu: starter -lang: th ---- - -# ให้บริการไฟล์คงที่ใน Express - -เพื่อให้บริการไฟล์แบบคงที่อย่างเช่น ไฟล์รูปภาพ, ไฟล์ CSS, และไฟล์ JavaScript ใช้ฟังก์ชันของมิดเดิลแวร์ในตัว `express.static` ใน Express - - -โครงสร้างของฟังก์ชันคือ: - -```js -express.static(root, [options]) -``` - -อาร์กิวเมนต์ `root` เป็นตัวกำหนดไดเรกเทอรีฐานราก ซึ่งให้บริการสินทรัพย์คงที่ (static assets) -สำหรับข้อมูลเพิ่มเติมของอาร์กิวเมนต์ `options` ดูได้ที่ [express.static](/{{page.lang}}/4x/api.html#express.static) - -ตัวอย่างเช่น การใช้งานโค้ดข้างล่างนี้เพื่อให้บริการ ไฟล์รูปภาพ, ไฟล์ CSS, และไฟล์ JavaScript ในไดเรกเทอรีชื่อว่า `public`: - -```js -app.use(express.static('public')) -``` -ตอนนี้คุณสามารถโหลดไฟล์ที่อยู่ในไดเรกเทอรี `public` ได้ดังนี้: - -```plain-text -http://localhost:3000/images/kitten.jpg -http://localhost:3000/css/style.css -http://localhost:3000/js/app.js -http://localhost:3000/images/bg.png -http://localhost:3000/hello.html -``` - -
      -Express จะมองหาไฟล์ที่เกี่ยวข้องกับไดเรกเทอรีคงที่ ดังนั้นชื่อของไดเรกเทอรีคงที่จะต้องไม่เป็นส่วนหนึ่งของ URL -
      - -เพื่อใช้สินทรัพย์คงที่หลายไดเรกเทอรี สามารถเรียกใช้มิดเดิลแวร์ฟังก์ชัน `express.static` ได้หลายครั้ง: - -```js -app.use(express.static('public')) -app.use(express.static('files')) -``` - -Express จะมองหาไฟล์ตามลำดับตามที่คุณตั้งค่าไดเรกเทอรี่คงที่ด้วยมิดเดิลแวร์ฟังก์ชัน `express.static` - -
      **หมายเหตุ:** สำหรับผลที่ดีที่สุด, [ใช้พร็อกซี่ย้อนกลับ](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) แคซเพื่อเพิ่มประสิทธิภาพของการใช้บริการสินทรัพย์ไฟล์คงที่ -
      - -เพื่อสร้างคำนำหน้าเส้นทางเสมือน (ที่ซึ่งเส้นทางไม่สามารถมายังที่อยู่ของไฟล์จริงในระบบได้) สำหรับไฟล์ที่ให้บริการโดยฟังก์ชัน `express.static` [ระบุเส้นทาง](/{{ page.lang }}/4x/api.html#app.use) สำหรับไดเรทเทอรีคงที่ ดังนี้: - -```js -app.use('/static', express.static('public')) -``` - -ตอนนี้คุณสามารถโหลดไฟล์ที่อยู่ในไดเรกเทอรี `public` จากคำนำหน้าเส้นทาง `/static` - -```plain-text -http://localhost:3000/static/images/kitten.jpg -http://localhost:3000/static/css/style.css -http://localhost:3000/static/js/app.js -http://localhost:3000/static/images/bg.png -http://localhost:3000/static/hello.html -``` - -อย่างไรก็ตาม เส้นทางที่คุณให้ไว้ในฟังก์ชัน `express.static` มีความสัมพันธ์กับไดเรกเทอรีจากที่ซึ่งคุณการบวนการรัน `node` ของคุณ ถ้าคุณรัน app จากไดเรกเทอรีอื่น มันจะปลอดภัยกว่าถ้าใช้เส้นทางจริงของไดเรกเทอรีที่คุณต้องการบริการไฟล์คงที่: - -```js -const path = require('path') -app.use('/static', express.static(path.join(__dirname, 'public'))) -``` - -สำหรับข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชัน `serve-static` และตัวเลือก ดูได้ที่ [serve-static](/resources/middleware/serve-static.html) diff --git a/tr/3x/api.md b/tr/3x/api.md deleted file mode 100644 index 4cfcc0b88a..0000000000 --- a/tr/3x/api.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -layout: 3x-api -title: Express 3.x - API Kaynak -menu: api -lang: tr ---- -
      - -
      - **Express 3.x IS NO LONGER MAINTAINED** - - Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. -
      - -

      3.x API

      - - {% include api/en/3x/express.md %} - {% include api/en/3x/app.md %} - {% include api/en/3x/req.md %} - {% include api/en/3x/res.md %} - {% include api/en/3x/middleware.md %} - -
      diff --git a/tr/4x/api.md b/tr/4x/api.md deleted file mode 100644 index 47c05f5568..0000000000 --- a/tr/4x/api.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API Kaynak -menu: api -lang: tr ---- -
      - -

      4.x API

      - - {% include api/en/4x/express.md %} - {% include api/en/4x/app.md %} - {% include api/en/4x/req.md %} - {% include api/en/4x/res.md %} - {% include api/en/4x/router.md %} - -
      diff --git a/tr/advanced/best-practice-performance.md b/tr/advanced/best-practice-performance.md deleted file mode 100644 index 82a01893de..0000000000 --- a/tr/advanced/best-practice-performance.md +++ /dev/null @@ -1,454 +0,0 @@ ---- -layout: page -title: Üretim (Production) ortamında Express kullanarak en iyi performans pratikleri -menu: advanced -lang: tr -redirect_from: "/advanced/best-practice-performance.html" ---- - -# Üretim ortamı en iyi pratikleri: performans ve güvenilirlik - -## Genel bakış - -Bu makalede üretim ortamına dağıtılımış Express uygulamaları için en iyi performans ve güvenilirlik pratikleri anlatılıyor. - -Bu konu açıkça her iki geleneksel geliştirme ve operasyonları da kapsayarak "devops" dünyasına girer. Buna göre, buradaki bilgiler iki kısma ayrılmıştır: - -* Kodunuzda yapılacak şeyler (geliştirme kısmı): - * [gzip sıkıştırma kullan](#use-gzip-compression) - * [Senkron fonksiyonlar kullan](#dont-use-synchronous-functions) - * [Loglamayı doğru yap](#do-logging-correctly) - * [İstisnaları düzgün işle](#handle-exceptions-properly) - -* Ortamınızda / kurulumunuzda yapılacak şeyler (operasyon kısmı): - * [NODE_ENV değerini "production" olarak ayarla](#set-node_env-to-production) - * [Uygulamanızın otomatik olarak yeniden başlatıldığından emin ol](#ensure-your-app-automatically-restarts) - * [Uygulamanızı bir kümede (cluster) koş](#run-your-app-in-a-cluster) - * [İstek sonuçlarını önbelleğe al (cache)](#cache-request-results) - * [Bir yük dengeleyicisi (load balancer) kullan](#use-a-load-balancer) - * [Bir ters proxy kullan (reverse proxy)](#use-a-reverse-proxy) - -## Kodunuzda yapılacak şeyler {#in-code} - -Uygulamanızın performansını iyileştirmek için yapabileceğiniz bazı şeyler: - -* [gzip sıkıştırma kullan](#use-gzip-compression) -* [Senkron fonksiyonlar kullanma](#dont-use-synchronous-functions) -* [Loglamayı doğru yap](#do-logging-correctly) -* [İstisnaları düzgün işle](#handle-exceptions-properly) - -### gzip sıkıştırma kullan - -Gzip sıkıştırma, yanıt gövdesininin boyutunu büyük ölçüde azaltabilir ve dolayısıyla da web uygulamanın hızını arttırır. Express uygulamanızda gzip sıkıştırması için [compression](https://www.npmjs.com/package/compression) ara yazılımını kullanın. Örnek olarak: - -```js -var compression = require('compression') -var express = require('express') -var app = express() -app.use(compression()) -``` - -Üretim ortamındaki yüksek-trafikli bir website için yapılabilecek sıkıştırmanın en iyi yolu ters proxy sevisyesinde uygulamaktır (bakınız [Ters proxy kullanımı](#use-a-reverse-proxy)). Bu durumda sıkıştırma ara yazılımı kullanmak zorunda değilsiniz. Nginx'te gzip sıkıştırmayı devreye alma hakkında daha fazla detay için Nginx dökümantasyonuna bakınız [ngx_http_gzip_module modülü](http://nginx.org/en/docs/http/ngx_http_gzip_module.html). - -### Senkron fonksiyonlar kullanma - -Senkron fonksiyon ve metodlar kod çalıştırma sürecini bir şey döndürene kadar tutarlar. Senkron bir fonksiyona yapılacak bir çağrı birkaç mikrosaniye veya milisaniye içinde dönerler, ancak yüksek-trafikli websitelerde bu çağrılar toplanıp uygulamanın performansını düşürürler. Üretim ortamında bu kullanımdan uzak durun. - -Node ve birçok modül kendi fonksiyonlarının senkron ve asenkron versiyonlarını sunmalarına rağmen, üretim ortamında her zaman asenkron versiyonları kullanın. Senkron bir fonksiyonun kullanımının haklı olabileceği tek zaman uygulamanın ilk başlangıcıdır. - -Node.js 4.0+ veya io.js 2.1.0+ kullanıyorsanız, uygulamanız senkron bir API kullandığında bir uyarı ve yığın izleme (stack trace) yazdırmak için `--trace-sync-io` komut satırı bayrağını kullanabilirsiniz. Elbette bunu üretim ortamında kullanmak istemezsiniz, daha çok bunu kodunuzun üretim için hazır olduğundan emin olmak için. Daha fazla bilgi için bakınız: [node komut satırı seçenekler dökümantasyonu](https://nodejs.org/api/cli.html#cli_trace_sync_io). - -### Loglamayı doğru yap - -Genelde, uygulamanızdan loglama yapmak için iki neden vardır: Hata ayıklama ve uygulama aktivitesini loglama için (yani, diğer her şey). Geliştirme ortamında log mesajlarını terminale yazdırmak için `console.log()` veya `console.error()` kullanmak yaygın bir kullanımdır. Ancak hedef bir terminal veya dosya olduğunda [bu fonksiyonlar senkrondur](https://nodejs.org/api/console.html#console_console_1), dolayısıyla, çıktıyı başka bir programa aktarmadığınız sürece bunlar üretim ortamı için uygun değiller. - -#### Hata ayıklamak için - -Hata ayıklama amacıyla loglama yapıyorsanız, o zaman `console.log()` yerine [debug](https://www.npmjs.com/package/debug) gibi özel bir hata ayıklama modülü kullanın. Bu modül, `console.error()` fonksiyonuna gönderilecek mesajları kontrol etmek için DEBUG ortam değişkenini kullanmanızı sağlar. Uygulamanızı sade asenkron halde tutmak istiyorsanız, yine `console.error()` çıktılarını başka bir programa aktarmanız gerekir. Ama yine de, üretim ortamında hata ayıklamayacaksınız, değil mi? - -#### Uygulama aktivitesi için - -Uygulama aktivitesini logluyorsanız (örneğin trafik izleme veya API çağrıları), `console.log()` yerine [Winston](https://www.npmjs.com/package/winston) veya [Bunyan](https://www.npmjs.com/package/bunyan) gibi bir loglama kütüphanesi kullanın. Bu iki kütüphanenin detaylı bir karşılaştırması için, StrongLoop blog yazısına bakınız [Winston ve Bunyan Node.js Loglama Karşılaştırması](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - -### İstisnaları düzgün işle - -Node uygulamaları yakalanmamış istisnalar ile karşılaştıklarında patlarlar. İstisnaları işlememe ve gerekli aksiyonları almama Express uygulamanızın patlamasına ve çevrimdışına çıkmasına neden olur. Aşağıdaki [Uygulamanızın otomatik olarak yeniden başlatıldığından emin olma](#ensure-your-app-automatically-restarts) tavsiyesine uyarsanız, o zaman uygulamanız bir çökmeden tekrar ayağa kalkabilir. Neyse ki Express uygulamalarının tipik olarak kısa bir başlama süresi var. Yine de patlamalardan kaçınmak gerekir ve bunu yapmak için de istisnaları uygun bir şekilde işlemeniz gerek. - -Tüm istisnaları işlediğinizden emin olmak için, aşağıdaki teknikleri kullanın: - -* [try-catch](#use-try-catch) -* [promises](#use-promises) - -Bu konulara girmeden önce Node/Express istisna işleme ile ilgili temel bir anlayışa sahip olmanız lazım: hata-öncellikli geri çağırmaları kullanmak ve hataları ara yazılımda yaymak. Node, asenkron fonksiyonlardan hataları dönmek için "hata-öncellikli geri çağırma" anlayışını kullanır, bu fonksiyonlarda birinci parametre hata objesi ve ondan sonraki parametreleri ise sonuç verileri takip eder. Hata olmadığını belirtmek için ilk parametreye null geçin. İstisnaları anlamlı bir şekilde işlemek için bu geri çağırma fonksiyonlarının hata-öncellikli geri çağırma anlayışını takip etmesi gerek. Ve Express'te ara yazılım zincirinde hataları yaymak için en iyi yöntem `next()` fonksiyonunu kullanmaktır. - -Hata işleme temelleri hakkında daha fazla bilgi için bakınız: - -* [Node.js'te Hata İşleme](https://www.joyent.com/developers/node/design/errors) -* [Güçlü Node Uygulamaları Yazmak: Hata İşleme](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop blogu) - -#### Ne yapmamalı - -_Yapmamanız_ gereken bir şey var, o da bir istisnanın olay döngüsüne kadar çıkarak yayılmasıyla oluşan `uncaughtException` olayını dinlememek. `uncaughtException` için bir olay dinleyici eklemek, istisna ile karşılaşan bir sürecin varsayılan davranışını değiştirir; süreç istisna almasına rağmen koşmaya devam edecektir. Bu uygulamanızın patlamasını önlemek için iyi bir yol gibi gözükebilir, ancak uygulamayı yakalanmayan bir istisnadan sonra koşturmaya devam ettirmek tehlikeli bir alıştırmadır ve tavsiye edilmez, çünkü sürecin durumu (state) güvenilmez ve öngörülemez hale gelir. - -Ek olarak, `uncaughtException` kullanımı resmen [ham](https://nodejs.org/api/process.html#process_event_uncaughtexception) olarak tanınır. Yani `uncaughtException` olayını dinlemek gerçekten kötü bir fikirdir. Bu yüzden çoklu süreçler ve denetçiler gibi şeyleri tavsiye ediyoruz: patladıktan sonra yeniden başlatma çoğu zaman bir hatayı düzeltmenin en güvenli yoludur. - -Ayrıca [domains](https://nodejs.org/api/domain.html) kullanmanızı tavsiye etmeyiz. Genellikle problemi çözmez ve de kullanımdan kaldırılmış bir modüldür. - -#### try-catch kullan - -Try-catch senkron kodda oluşan istisnaları yakalamak için kullanabileceğiniz bir JavaScript dili yapısıdır. Try-catch yapısını, örneğin, JSON ayrıştırma hatalarını aşağıda gösterildiği gibi ele almak için kullanın. - -[Tanımsız değişkenlerde referans hataları](http://www.jshint.com/docs/options/#undef) gibi kapalı (implicit) istisnaları bulmak için [JSHint](http://jshint.com/) veya [JSLint](http://www.jslint.com/) gibi araçları kullanabilirsiniz. - -Buradaki örnek potansyel bir süreç-patlatıcı istisnayı ele alman try-catch kullanımını gösterir. Bu ara yazılım fonksiyonu JSON objesi olan "params" adında bir sorgu alanı parametresi alıyor. - -```js -app.get('/search', (req, res) => { - // Simulating async operation - setImmediate(() => { - var jsonStr = req.query.params - try { - var jsonObj = JSON.parse(jsonStr) - res.send('Success') - } catch (e) { - res.status(400).send('Invalid JSON string') - } - }) -}) -``` - -Ancak, try-catch sadece senkron kod için çalışır. Node platformu birincil olarak asenkron olduğundan (özellikle de bir üretim ortamında), try-catch çok fazla istisna yakalamayacaktır. - -#### Promise kullan - -Promise'lar `then()` kullanan asenkron kod bloklarında herhangi bir istisnayı (implicit / explicit) işleyebilir. Sadece `.catch(next)` ifadesini promise zincirlerinin sonuna ekleyin. Örneğin: - -```js -app.get('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) -}) - -app.use((err, req, res, next) => { - // handle error -}) -``` - -Şimdi bütün hatalar, asenkron ve senkron olmak üzere, hata işleyici ara yazılıma gider. - -Ancak, iki uyarı var: - -1. Bütün asenkron kodunuz promise döndürmeli (yayıcılar/emitter hariç). Eğer belirli bir kütüphane promise döndürmüyorsa, [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html) gibi bir yardımcı fonksiyon kullanarak temel objeyi dönüştürün. -2. Olay yayıcılar (akışlar gibi) yine de yakalanmayan istisnalara neden olabilir. O yüzden hata olayını düzgün bir şekilde ele aldığınızdan emin olur; örneğin: - -```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) - -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) -``` - -`wrap()` fonksiyonu ret edilen promise'ları yakalayıp birinci argümanı hata olarak `next()` fonkisyonunu çağıran bir sarıcıdır (wrapper). Detaylar için, bakınız [Express'te Promise, Generator ve ES7 ile Asenkron Hata Ele Alma](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/#cleaner-code-with-generators). - -Promise'lerle hata ele alma ile ilgili daha fazla bilgi için bakınız [Node.js'te Q ile Promis'ler – Geri çağrımalara Bir Alternatif](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/). - -## Ortamınızda / kurulumunuzda yapılacak şeyler {#in-environment} - -Uygulamanızın performansını iyileştirmek için sistem ortamınızda yapabileceğiniz bazı şeyler: - -* [NODE_ENV değerini "production" olarak ayarla](#set-node_env-to-production) -* [Uygulamanızın otomatik olarak yeniden başlatıldığından emin ol](#ensure-your-app-automatically-restarts) -* [Uygulamanızı bir kümede (cluster) koş](#run-your-app-in-a-cluster) -* [İstek sonuçlarını önbelleğe al (cache)](#cache-request-results) -* [Bir yük dengeleyicisi (load balancer) kullan](#use-a-load-balancer) -* [Bir ters proxy kullan (reverse proxy)](#use-a-reverse-proxy) - -### NODE_ENV değerini "production" olarak ayarla - -NODE_ENV ortam değişkeni bir uygulamanın hangi ortamda koştuğunu belirtir (genellikle development veya production olur). Performansı iyileştirmek için yapabileceğiniz en basit şeylerden biri NODE_ENV değerini "production" olarak ayarlamaktır. - -NODE_ENV "production" olarak ayarlandığında Express: - -* Görüntü şablonlarını önbelleğe atar. -* CSS uzantılarından oluşturulan CSS dosyalarını önbelleğe atar. -* Daha az ayrıntılı hata mesajları üretir. - -Yapılan [testler](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/) sadece bunu yaparak uygulamanın performansının üç kat arttığını gösteriyor! - -Eğer özellikle bir ortam için kod yazmak istiyorsanız, NODE_ENV değişkeninin değerini `process.env.NODE_ENV` ile kontrol edebilirsiniz. Herhangi bir ortamı değişkeninin değerini kontrol etmenin bir performans düşüşü meydana getirdiğini unutmayın, ve bu yüzden bu işlem idareli yapılmalıdır. - -Geliştirme modunda, tipik olarak ortam değişkenlerini interaktif shell'de `export` veya `.bash_profile` dosyasınızı kullanarak ayarlayabilirsiniz. Ama genellikle üretim sunucusunda bunu yapmamalısınız; onun yerine, işletim sisteminizin init system'ini kullanabilirsiniz (systemd veya Upstart). Bir sonraki kısım genel init system kullanımı hakkında daha fazla detay veriyor, ama NODE_ENV değişkeninin ayarlanması performans için çok önemli olduğundan (ve yapması da kolay olduğundan) burada vurgulanmıştır. - -Upstart ile, job dosyanızda `env` ifadesini kullanın. Örnek olarak: - -```sh -# /etc/init/env.conf - env NODE_ENV=production -``` - -Daha fazla bilgi için bakınız [Upstart Giril, Cookbook ve En İyi Pratikler](http://upstart.ubuntu.com/cookbook/#environment-variables). - -Systemd ile, ünite dosyanızdaki `Environment` direktifini kullanın. Örnek olarak: - -```sh -# /etc/systemd/system/myservice.service -Environment=NODE_ENV=production -``` - -Daha fazla bilgi için bakınız [Systemd Ünitelerindeki Ortam Değişkenlerini Kullanma](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). - -### Uygulamanızın otomatik olarak yeniden başlatıldığından emin olun - -Üretim ortamında hiçbir zaman uygulamanızın çevrimdışı kalmasını istemezsiniz. Bu, uygulamanızın veya sunucunun kendisinin patlaması durumunda yeniden başlatıldığından emin olmanız gerektiği anlamına gelir. Bu olaylardan hiçbirinin olmamasını ummanıza rağmen, gerçekçi olarak her iki olasılığı da hesaba katarak: - -* Patladığında uygulamayı (ve Node'u) yeniden başlatmak için bir süreç yöneticisi kullanmak. -* İşletim sisteminiz tarafından sağlanan init system'i kullanarak, işletim sistemi çöktüğünde yeniden başlatmak. Init system'i bir süreç yöneticisi olmadan da kullanabilirsiniz. - -Node uygulamaları yakalanmayan bir istisna ile karşılaştıklarında patlarlar. En başta yapmanız gereken şey uygulamanızın iyi test edilmiş olmasını ve bütün istisnaları (detaylar için bakınız [istisnaları düzgün bir şekilde ele almak](#handle-exceptions-properly)) ele aldığını sağlamaktır. Ancak yine de tedbir olarak, uygulamanız patlarsa ve patladığında, yeniden başlatılacağını sağlayan bir mekanizmayı yapmak. - -#### Süreç yöneticisi kullan - -Geliştirme ortamında, uygulamanızı basitçe komut satırından `node server.js` veya benzeri bir şeyle başlatırsınız. Ama bunu üretim ortamında yapmak, felakete davetiye çıkarmaktır. Uygulama patladığında, siz tekrar başlatana kadar çevrimdışı kalacaktır. Patladığında uygulamanızın yeniden başlatılmasını sağlamak için bir süreç yöneticisi kullanın. Süreç yöneticisi, uygulamaların dağıtımını (deployment) kolaylaştırıan, yüksek kullanılabilirlik sağlayan ve uygulamayı çalışma zamanında yönetmeye imkan sağlayan konteynerlardır. - -Uygulamanızın patladığında tekrar başlatılmasına ek olarak, bir süreç yöneticisi aşağıdakileri yapabilmenizi sağlar: - -* Çalışma zamanı performansı ve kaynak tüketimi hakkında içgörüler elde edebilme. -* Performansı iyileştirmek için ayarları dinamik olarak değiştirme. -* Cluster kontrolü (StrongLoop PM ve pm2). - -Node için en popüler süreç yöneticileri aşağıdakilerdir: - -* [StrongLoop Süreç Yöneticisi](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -Bu üç süreç yöneticisinin özellik bazında bir karşılaştırması için bakınız [http://strong-pm.io/compare/](http://strong-pm.io/compare/). Her üçü ile ilgili daha detaylı bir giriş için bakınız [Express uygulamaları için süreç yöneticileri](/{{ page.lang }}/advanced/pm.html). - -Uygulamanız zaman zaman patlasa bile, bu süreç yöneticilerinden birini kullanmanız uygulamanızı ayakta tutmak için yeterli olacaktır. - -Ancak, StrongLoop süreç yöneticisi özellikle üretim dağıtımını hedefleyen birçok özelliğe sahiptir. Bunları ve ilgili StrongLoop araçlarını aşağıdakileri yapmak için kullanabilirsiniz: - -* Uygulamanızı lokal olarak derleyip paketlemek, ve daha sonra güvenli bir şekilde üretim sisteminize dağıtmak. -* Herhangi bir nedenden dolayı uygulamanız patladığında otomatik olarak yeniden başlatmak. -* Kümelerinizi (cluster) uzaktan yönetmek. -* Performansı iyileştirmek ve bellek sızıntılarını teşhis etmek için CPU profillerini ve heap anlık görüntülerini görüntülemek. -* Uygulamanız için performans ölçülerini görüntülemek. -* Nginx yük dengeleyici için entegre kontrol ile birden çok ana bilgisayara kolayca ölçeklendirmek. - -Aşağıda anlatıldığı gibi, init systeminizi kullanarak StronLoop süreç yöneticisini işletim sistemi servisi olarak yüklediğinizde, sistem tekrar başlatıldığında bu da tekrar başlatılacaktır. Dolayısıyla, uygulamanızın süreçlerini ve kümelerini sonsuza dek beraber ayakta tutacaktır. - -#### Init system kullan - -Güvenilirliğin bir sonraki katmanı, sunucu yeniden başladığında uygulamanızın da yeniden başlatılmasını sağlamaktır. Sistemler çeşitli nedenlerle yine de çökebilir. Sunucu patladığında uygulamanızında yeniden başlatıldığından emin olmak için, işletim sisteminizdeki gömülü init system'i kullanın. Bugün kullanımda olan iki ana init system şunlardır: [systemd](https://wiki.debian.org/systemd) ve [Upstart](http://upstart.ubuntu.com/). - -Express uygulamanızda init system'i kullanmanın iki yolu var: - -* Uygulamanızı bir süreç yöneticisinde koşun, ve süreç yöneticisini bir servis olarak init system'le yükleyin. Süreç yöneticisi, uygulamanız patladığında yeniden başlatacaktır, ve işletim sistemi de yeniden başlatıldığında, init system süreç yöneticisini başlatacaktır. Tavsiye edilen yaklaşım budur. -* Uygulamanızı (ve Node'u) direkt olarak init system ile koşun. Bu biraz daha basittir, ama süreç yöneticisini kullanmanın verdiği ek avantajları elde etmiyorsunuz. - -##### Systemd - -Systemd, bir Linux sistemi ve servis yöneticisidir. Çoğu büyük Linux dağıtımları varsayılan init system olarak systemd'yi benimsemiştir. - -Bir systemd servis konfigürasyon dosyasına _unit file_ denir ve `.service` dosya ismiyle biter. Aşağıdaki örnek bir Node uygulamasını direkt olarak yöneten bir unit dosyasını gösterir. `` ile kapanmış değerleri uygulamanız ve sisteminiz ile değiştirin: - -```sh -[Unit] -Description= - -[Service] -Type=simple -ExecStart=/usr/local/bin/node -WorkingDirectory= - -User=nobody -Group=nogroup - -# Ortam değişkenleri: -Environment=NODE_ENV=production - -# Birden fazla gelen bağlantıya izin ver -LimitNOFILE=infinity - -# Hata ayıklama için temel dökümlere (core dump) izin ver -LimitCORE=infinity - -StandardInput=null -StandardOutput=syslog -StandardError=syslog -Restart=always - -[Install] -WantedBy=multi-user.target -``` -Systemd ile ilgili daha fazla bilgi için bakınız [systemd referansı (kılavuz)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### systemd servisi olarak StrongLoop PM (süreç yöneticisi) - -StrongLoop süreç yöneticisini systemd servisi olarak kolaylıkla yükleyebilirsiniz. Bunu yaptıktan sonra, sunucu yeniden başlatıldığında, StrongLoop süreç yöneticisini de otomatik olarak başlatılacak, ve bu da StrongLoop tarafından yönetilen bütün uygulamaların yeniden başlatılmasını sağlayacak. - -StrongLoop süreç yöneticisini bir systemd servisi olarak yüklemek için: - -```sh -$ sudo sl-pm-install --systemd -``` - -Daha sonra, servisi başlatmak için: - -```sh -$ sudo /usr/bin/systemctl start strong-pm -``` - -Daha fazla bilgi için bakınız [Üretim hostu kurmak (StrongLoop dökümantasyonu)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart, birçok Linux dağıtımında bulunan sistem başlangıcında görevleri ve servisleri başlatan, kapanma sırasında kapatan ve denetleyen bir sistem aracıdır. Express uygulamanızı veya süreç yöneticinizi bir servis olarak yapılandırabilirsiniz ve bunlar patladığında, Upstart otomatik olarak yeniden başlatacaktır. - -Bir Upstart servisi, `.conf` uzantılı bir job konfigürasyon dosyasında ("job" olarak adlandırılır) tanımlanır. Aşağıdaki örnek, ana dosyası `/projects/myapp/index.js` konumunda bulunan "myapp" adında bir uygulama için "myapp" adında bir job yaratmayı gösterir. - -Aşağıdakileri içererek `/etc/init/` konumunda `myapp.conf` adında bir dosya yaratın (kalın yazıları sisteminizin ve uygulamanızın değerleriyle değiştirin): - -```sh -# Sürecin ne zaman başlayacağı -start on runlevel [2345] - -# Sürecin ne zaman duracağı -stop on runlevel [016] - -# Daha fazla isteği işleyebilmek için dosya tanımlayıcı sınırını artır -limit nofile 50000 50000 - -# production modunu kullan -env NODE_ENV=production - -# www-data olarak koş -setuid www-data -setgid www-data - -# Uygulamanın dizininden koş -chdir /projects/myapp - -# Başlatılacak süreç -exec /usr/local/bin/node /projects/myapp/index.js - -# Süreç çöktüğünde yeninden başlat -respawn - -# Yeniden başlatma girişimini 10 saniye içinde 10 kez ile sınırla -respawn limit 10 10 -``` - -NOT: Bu kod Ubuntu 12.04-14.10'da desteklenen Upstart 1.4 ve üstüne ihtiyaç duyar. - -Job, sistem başladığında koşması için yapılandırıldığından uygulamanız da işletim sistemiyle beraber başlayacak, ve sistem çöktüğünde veya uygulama patladığında otomatik olarak yeniden başlatılacaktır. - -Uygulamanın otomatik olarak yeniden başlatılmasının yanından, Upstart aşağıdaki komutları da kullanmanızı sağlar: - -* `start myapp` – Uygulamayı başlat -* `restart myapp` – Uygulamayı yeniden başlat -* `stop myapp` – Uygulamayı durdur - -Upstart ile ilgili daha fazla bilgi için bakınız [Upstart Giriş, Kılavuz and En İyi Pratikler](http://upstart.ubuntu.com/cookbook). - -##### Upstart servisi olarak StrongLoop süreç yöneticisi - -StrongLoop süreç yöneticisini bir Upstart servisi olarak kolaylıkla yükleyebilirsiniz. Bunu yaptıktan sonra, sunucu yeninden başladığında StrongLoop süreç yöneticisini otomatik olarak yeniden başlatır, ve süreç yöneticisinin yönettiği bütün uygulamaları da yeniden başlatır. - -Strong Loop süreç yöneticisini bir Upstart 1.4 servisi olarak yüklemek için: - -```sh -$ sudo sl-pm-install -``` - -Daha sonra servisi koşmak için: - -```sh -$ sudo /sbin/initctl start strong-pm -``` - -NOT: Upstart 1.4'ü desteklemeyen sistemlerde bu komutlar biraz farklıdır. Daha fazla bilgi için bakınız [Production hostu kurmak (StrongLoop dökümantasyonu)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10). - -### Uygulamanızı bir kümede (cluster) koş - -Çok çekirdekli bir sistemde, bir işlemler kümesi başlatarak bir Node uygulamasının performansını birçok kez artırabilirsiniz. Bir küme, uygulamanın birden fazla örneğini koşar, ideal olarak her bir CPU çekirdeğinde bir örnek olacak şekilde, dolayısıyla da yük ve görevleri örneklerin arasında dağıtır. - -![cluster API kullanarak uygulama örnekleri arasında dengeleme](/images/clustering.png) - -ÖNEMLİ: Uygulama örnekleri ayrı süreçler olarak koştuklarından, aynı hafıza alanını paylaşmıyorlar. Yani, objeler her uygulama örneği için lokaldir. Bu nedenle, uygulama kodunda durumu (state) koruyamazsınız. Ancak, durum ve oturum ile ilgili veriyi depolamak için [Redis](http://redis.io/) gibi bir in-memory veri deposu kullanabilirsiniz. Bu uyarı esases, kümeleme birden fazla süreç ya da birden fazla fiziksel sunucularla olsun, tüm yatay ölçekleme biçimleri için geçerlidir. - -Kümelenmiş uygulamalarda, çalışan süreçleri (worker process) bireysel olarak geri kalan süreçleri etkilemeden çökebilirler. Performans avantajlarından ayrı olarak, arıza izolasyonu, bir uygulama süreçleri kümesini çalıştırmanın başka bir nedenidir. Ne zaman bir çalışan süreci çökerse, olayı loglayıp ve `cluster.fork()` kullanarak yeni bir süreç yaratmayı unutmayın. - -#### Node'un cluster modülünü kullan - -Kümeleme, Node'un [cluster modülü](https://nodejs.org/dist/latest-v4.x/docs/api/cluster.html) sayesinde mümkün hale gelmiştir. Bu, bir ana sürecin çalışan süreçleri üretmesini ve gelen bağlantıları çalışanlar arasında dağıtmasını sağlar. Ancak, direkt olarak bu modülü kullanmak yerine, bu işi otomatik olarak yapan birçok araçtan birini kullanmak çok daha iyi; örneğin [node-pm](https://www.npmjs.com/package/node-pm) ya da [cluster-service](https://www.npmjs.com/package/cluster-service). - -#### StrongLoop süreç yöneticisi kullan - -Uygulamanızı StrongLoop süreç yöneticisine dağıtırsanız, uygulamanızın kodunu _değiştirmeden_ kümelemenin avantajından yararlanabilirsiniz. - -StrongLoop süreç yöneticisi bir uygulamayı koştuğunda, sistemdeki CPU çekirdeği sayısına eşit sayıda çalışanı olan bir kümede otomatik olarak çalıştırır. Uygulamayı durdurmadan slc komut satırı aracını kullanarak kümedeki çalışan süreçlerin sayısını manuel olarak değiştirebilirsiniz. - -Örnek olarak, uygulamanızı prod.foo.com'a dağıttığınızı ve StrongLoop süreç yöneticisinin de port 8701'de (varsayılan) dinlediğini varsayarsak, slc kullanarak kümenin büyüklüğünü sekize ayarlamak için: - -```sh -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8 -``` - -StrongLoop ile kümeleme hakkında daha fazla bilgi için, StrongLoop dökümantasyonuna bakınız: [Kümeleme](https://docs.strongloop.com/display/SLC/Clustering) - -#### PM2 kullan - -Uygulamanızı PM2 ile dağıtırsanız, uygulamanızın kodunu _değiştirmeden_ kümelemenin avantajından yararlanabilirsiniz. İlk önce [uygulamanızın durumsuz (stateless)](http://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) olmasını sağlamalısınız, yani süreçte herhangi bir lokal veri saklanmamalıdır (oturum, websocket vb. bağlantılar). - -PM2 ile bir uygulama koşulduğunda, seçtiğiniz örnek sayısıyla beraber bir kümede çalıştırmak için **küme modu**nu etkinleştirebilirsiniz, makinedeki mevcut CPU sayısıyla eşleştirilmesi gibi. Uygulamayı durdurmadan `pm2` komut satırı aracını kullanarak kümedeki süreç sayısını elle değiştirebilirsiniz. - -Küme modunu etkinleştirmek için, uygulamanızı bu şekilde başlatın: - -```sh -# 4 çalışan süreç başlat -$ pm2 start app.js -i 4 -# Mevcut CPU sayısını otomatik olarak tespit et ve o sayı kadar çalışan süreç başlat -$ pm2 start app.js -i max -``` - -Bu aynı zamanda `exec_mode` değerini `cluster` ve `instances` değerini de başlangıç çalışan sayısı olarak ayarlayarak bir PM2 süreç dosyası (`ecosystem.config.js` ya da benzeri) içinde de yapılandırılabilir - -Koşmaya başladıktan sonra, `app` isminde belirli bir uygulama aşağıdaki gibi ölçeklenebilir: - -```sh -# 3 tane daha çalışan ekle -$ pm2 scale app +3 -# Belirli bir çalışan sayınıa ölçeklendir -$ pm2 scale app 2 -``` - -PM2 ile kümeleme hakkında daha fazla bilgi için PM3 dökümantasyonuna bakınız: [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) - -### İstek sonuçlarını önbelleğe al - -Üretim ortamında performansı artırmak için bir başka strateji, isteklerin sonucunu önbelleğe almaktır, böylece uygulamanız aynı isteği tekrar tekrar sunmak için işlemi tekrarlamaz. - -Uygulamanızın hızını ve performansını büyük ölçüde iyileştirmek için [Varnish](https://www.varnish-cache.org/) veya [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (ayrıca bakınız [Nginx Caching](https://serversforhackers.com/nginx-caching/)) gibi bir önbelleğe alma sunucusu kullanın. - -### Bir yük dengeleyicisi kullan - -Bir uygulama ne kadar optimize edilmiş olursa olsun, tek bir örnek yalnızca sınırlı miktarda yük ve trafiği kaldırabilir. Bir uygulamayı ölçeklendirmenin bir yolu, birden çok örneğini çalıştırmak ve trafiği bir yük dengeleyici aracılığıyla dağıtmaktır. Bir yük dengeleyici kurmak, uygulamanızın performansını ve hızını artırabilir ve tek bir örnekle mümkün olandan daha fazla ölçeklenmesini sağlayabilir. - -Yük dengeleyici, genellikle birden çok uygulama örneği ve sunucusuna gelen ve giden trafiği düzenleyen bir ters proxy'dir. [Nginx](http://nginx.org/en/docs/http/load_balancing.html) veya [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts) kullanarak uygulamanız için bir yük dengeleyiciyi kolayca kurabilirsiniz. - -Yük dengeleyici kullanırken, belirli bir oturum kimliğiyle ilişkili isteklerin, onları oluşturan sürece bağlanmasını sağlamanız gerekebilir. Bu, _oturum yakınlığı (session affinity)_, veya _yapışkan oturumlar (sticky sessions)_ olarak bilinir, ve oturum verileri için Redis gibi bir veri deposunun kullanılması için yukarıdaki öneri ile ele alınabilir (uygulamanıza bağlı olarak). Tartışma için bakınız [Birden çok node kullanmak](http://socket.io/docs/using-multiple-nodes/). - -### Ters proxy kullan - -Bir ters proxy, bir web uygulamasının önünde oturur ve istekleri uygulamaya yeniden yönlendirmenin yanı sıra istekler üzerinde destekleyici işlemler gerçekleştirir. Diğer şeylerin yanı sıra hata sayfalarını, sıkıştırmayı, önbelleğe almayı, dosyaları sunmayı ve yük dengelemeyi de işleyebilir. - -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://www.nginx.com/) or [HAProxy](http://www.haproxy.org/) in production. - -Uygulama durumu (state) bilgisi gerektirmeyen görevleri bir ters proxy'ye devretmek, özel uygulama görevlerini gerçekleştirmek için Express'i serbest bırakır. Bu nedenle, üretim ortamında Express'i [Nginx](https://www.nginx.com/) veya [HAProxy](http://www.haproxy.org/) gibi bir ters proxy'nin arkasında koşmak tavsiye edilir. diff --git a/tr/advanced/best-practice-security.md b/tr/advanced/best-practice-security.md deleted file mode 100644 index a093b64644..0000000000 --- a/tr/advanced/best-practice-security.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -layout: page -title: Canlı Ortamda Express için En İyi Güvenlik Pratikleri -menu: advanced -lang: tr ---- - -# En İyi Canlı Ortam Pratikleri: Güvenlik - -## Genel Bakış - -_"canlı ortam"_ terimi, bir uygulama veya API'nin genel olarak son kullanıcıları veya tüketicileri için hazır olduğu yazılım yaşam döngüsündeki aşamayı ifade eder. Buna kıyasla, _"geliştirme"_ aşamasında aktif olarak kod yazıyor ve test ediyorsunuz, ve uygulama dış erişime açık değildir. Bunlara karşılık gelen sistem ortamları sırasıyla _canlı ortam (production)_ ve _geliştirme (development)_ ortamları olarak bilinir. - -Canlı ve geliştirme ortamları genel olarak farklı şekilde kurulurlar ve çok farklı gereksinimleri vardır. Geliştirme ortamında iyi olan bir şey canlı ortamda kabul edilebilir olmayabilir. Örneğin, geliştirme ortamında hata ayıklama için ayrıntılı hataların loglanmasını isteyebilirsiniz, ancak aynı şey canlı ortamda güvenlik açığı oluşturabilir. Ve geliştirme ortamında ölçeklenebilirlik, güvenilirlik ve performans hakkında endişe etmenize gerek yok iken, bu konular canlı ortamda kritikleşir. - -{% include note.html content="Express'te bir güvenlik açığı keşfettiğinizi düşünüyorsanız, lütfen bakınız -[Güvenlik Politikaları ve Prosedürleri](https://github.com/expressjs/express/blob/master/Security.md). -" %} - -Canlı ortamdaki Express uygulamaları için en iyi güvenlik pratikleri: - -- [Express'in kullanımdan kaldırılmış veya bakımı yapılmayan versiyonlarını kullanmayın](#expressin-kullanımdan-kaldırılmış-veya-bakımı-yapılmayan-versiyonlarını-kullanmayın) -- [TLS kullanın](#tls-kullanın) -- [Helmet kullanın](#helmet-kullanın) -- [Çerezleri güvenli kullanın](#çerezleri-güvenli-kullanın) -- [Otorizasyona karşı yapılan brute-force saldırılarını engelleyin](#otorizasyona-karşı-yapılan-brute-force-saldırılarını-engelleyin) -- [Bağımlılıklarınızın güvende olduğundan emin olun](#bağımlılıklarınızın-güvende-olduğundan-emin-olun) -- [Bilinen diğer güvenlik açıklarından kaçının](#bilinen-diğer-güvenlik-açıklarından-kaçının) -- [Ek hususlar](#ek-hususlar) - -## Express'in kullanımdan kaldırılmış veya bakımı yapılmayan versiyonlarını kullanmayın - -Express 2.x ve 3.x versiyonlarının bakımı artık yapılmıyor. Bu versiyonlardaki güvenlik ve performans sorunları çözülmeyecek. Bunları kullanmayın! 4. versiyona henüz geçmediyseniz, [taşıma rehberini](/{{ page.lang }}/guide/migrating-4.html) takip edin. - -Ayrıca [güvenlik güncellemeleri sayfası](/{{ page.lang }}/advanced/security-updates.html)'nda listelenen bakımı yapılmayan herhangi bir Express versiyonunu kullanmadığınızdan emin olun. Eğer kullanıyorsanız, stabil versiyonlardan birine geçin, tercihen en son versiyona. - -## TLS kullanın - -Uygulamanız hassas verilerle ilgileniyor veya bunları iletiyorsa, veri ve bağlantıyı güvende tutmak için [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) kullanın. Bu teknoloji, verileri istemciden sunucuya gönderilmeden önce şifreler ve böylelikle bazı yaygın (ve kolay) saldırıları önler. Ajax ve POST istekleri gözle görülür şekilde açık olmayabilir ve tarayıcılarda "gizli" görünebilir, ancak bunların ağ trafiği [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) ve [man-in-the-middle saldırılarına](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) karşı korumasızdır. - -Secure Socket Layer (SSL) şifrelemesine aşina olabilirsiniz. [TLS, SSL'nin bir sonraki geçişidir](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). Bir başka deyişle, daha önce SSL kullanıyorsanız TLS'e yükseltmeyi düşünün. Genel olarak, TLS kullanmak için Nginx öneririz. Nginx'te (ve diğer sunucularda) TLS'yi yapılandırmak için, bakınız [Önerilen Sunucu Yapılandırmaları (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). - -Ayrıca, [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/) tarafından sunulan ücretsiz, otomatik, ve açık bir sertifika yetkilisi (CA - Certificate Authority) olan [Let's Encrypt](https://letsencrypt.org/about/) ücretsiz bir TLS sertifikası alabileceğiniz araçtır. - -## Helmet kullanın - -[Helmet](https://www.npmjs.com/package/helmet), HTTP başlıklarını doğru ayarlayarak uygulamanızı bazı iyi bilinen web güvenlik açıklarına karşı koruyabilir. - -Helmet aslında güvenlikle ilgili HTTP yanıt başlıklarını ayarlayan, daha küçük ara yazılım (middleware) fonksiyonlarından oluşan bir koleksiyondur: - -* [csp](https://github.com/helmetjs/csp) siteler arası (cross-site) komut dosyası çalıştırma saldırılarını ve diğer siteler arası enjeksiyonları önlemeye yardımcı olmak için `Content-Security-Policy` başlığını ayarlar. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) `X-Powered-By` başlığını kaldırır. -* [hsts](https://github.com/helmetjs/hsts) sunucuya güvenli (SSL/TLS üzerinden HTTP) bağlantıları zorunlu kılan `Strict-Transport-Security` başlığını ayarlar. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) IE8+ için `X-Download-Options` başlığını ayarlar. -* [noCache](https://github.com/helmetjs/nocache) istemci-taraflı önbelleğe alma (caching) işlevini devre dışı bırakmak için `Cache-Control` ve Pragma başlıklarını ayarlar. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) tarayıcıların bildirilen içerik türünden farklı, bir sunucu yanıtına MIME-sniffing uygulanmasını önlemek için `X-Content-Type-Options` başlığını ayarlar. -* [frameguard](https://github.com/helmetjs/frameguard) [clickjacking](https://www.owasp.org/index.php/Clickjacking) koruması sağlamak için `X-Frame-Options` başlığını ayarlar. -* [xssFilter](https://github.com/helmetjs/x-xss-protection) siteler arası komut çalıştırma (Cross-site scripting (XSS)) filtresini en yeni tarayıcılarda etkinleştirmek için `X-XSS-Protection` başlığını ayarlar. - -Helmet'ı diğer herhangi bir modül gibi kurun: - -```sh -$ npm install --save helmet -``` - -Daha sonra kodunuzda kullanmak için: - -```js -// ... - -var helmet = require('helmet') -app.use(helmet()) - -// ... -``` - -### En azından, X-Powered-By başlığını devre dışı bırakın - -Eğer Helmet kullanmak istemiyorsanız, o zaman en azından `X-Powered-By` başlığını devre dışı bırakın. Saldırganlar, Express çalıştıran uygulamaları tespit etmek ve ardından özel olarak hedeflenen saldırılar başlatmak için bu başlığı (varsayılan olarak etkindir) kullanabilir. - -Bu yüzden, `app.disable()` metodunu kullanarak bu başlığı devre dışı bırakmak en iyi pratiktir: - -```js -app.disable('x-powered-by') -``` - -Eğer `helmet.js` kullanıyorsanız, bunu sizin için halleder. - -{% include note.html content="X-Powered-By başlığının devre dışı bırakılması, tecrübeli bir saldırganın bir uygulamanın Express çalıştırdığını belirlemesini önlemez. Bu, sıradan bir istismarı engelleyebilir, ancak bir uygulamanın Express çalıştırdığını belirlemenin başka yolları da var. "%} - -## Çerezleri güvenli kullanın - -Çerezlerin uygulamanızı istismarlara açmamasını sağlamak için, varsayılan oturum çerez adını kullanmayın ve çerez güvenlik seçeneklerini uygun şekilde ayarlayın. - -İki ana ara yazılım çerez oturum modülü var: - -* [express-session](https://www.npmjs.com/package/express-session), Express 3.x versiyonlarında yer alan `express-session` yerleşik (built-in) ara yazılımının yerini alır. -* [cookie-session](https://www.npmjs.com/package/cookie-session), Express 3.x versiyonlarında yer alan `express.cookieSession` yerleşik ara yazılımının yerini alır. - -Bu iki modülün arasındaki ana fark, çerez oturum verisinin nasıl kaydedildiğidir. [express-session](https://www.npmjs.com/package/express-session) ara yazılımı oturum verisini sunucuda tutar; sadece oturum ID'sini çerezde tutar, oturum verisini değil. Varsayılan olarak, iç-bellek depolamayı kullanır ve canlı ortam için tasarlanmamıştır. Canlı ortamda, ölçeklenebilir bir oturum depolamayı kurmanız gerekecektir; [uyumlu oturum depolarını](https://github.com/expressjs/session#compatible-session-stores)'nı görmek için bakınız. - -Buna kıyasla, [cookie-session](https://www.npmjs.com/package/cookie-session) ara yazılımı çerez-destekli depolamayı uygular: sadece bir oturum anahtarı yerine, tüm oturumu çerezde serileştirir. Bunu yalnızca oturum verileri nispeten küçük olduğunda ve ilkel (primitive) değerler (objeler yerine) olarak kolayca kodlandığında kullanın. Tarayıcıların çerez başına en az 4096 baytı desteklemesine rağmen, limiti aşmamanızdan emin olmak için domain başına 4093 baytı aşmayın. Ayrıca, çerez verilerinin istemciye açık olacağını unutmayın, bu yüzden verilerin güvenli veya gizli olması için herhangi bir neden var ise, express-session daha iyi bir seçenek olabilir. - -### Varsayılan oturum çerez adını kullanmayın - -Varsayılan oturum çerez adı uygulamanızı saldırılara açık bırakabilir. Ortaya çıkan güvenlik sorunu `X-Powered-By` sorununa benzer: potansiyel bir saldırgan, sunucunun parmak izini almak ve saldırıları buna göre hedeflemek için kullanabilir. - -Bu problemi önlemek için, jenerik çerez adlarını kullanın; örnek olarak [express-session](https://www.npmjs.com/package/express-session) ara yazılımının kullanımı: - -```js -var session = require('express-session') -app.set('trust proxy', 1) -app.use(session({ - secret: 's3Cur3', - name: 'sessionId' -})) -``` - -### Çerez güvenlik seçeneklerini ayarlayın - -Güvenliği artırmak için aşağıdaki çerez seçeneklerini ayarlayın: - -* `secure` - Tarayıcının çerezi yalnızca HTTPS üzerinden göndermesini sağlar. -* `httpOnly` - Çerezin JavaScript istemcisinden değil, yalnızca HTTP(S) üzerinden gönderilmesini sağlar ve böylelikle siteler arası komut dosyası çalıştırma saldırılarına karşı korumaya yardımcı olur. -* `domain` - çerezin alan adını belirtir; URL'nin istendiği sunucunun alan adıyla karşılaştırmak için kullanın. Eğer eşleşiyorsa, ardından yol (path) alanını kontrol edin. -* `path` - çerezin yolunu belirtir; bunu istek yoluyla karşılaştırmak için kullanın. Eğer bu ve alan adı eşleşiyorsa, istekte çerezi gönderebilirsiniz. -* `expires` - kalıcı çerezler için son kullanma tarihini ayarlamak için kullanın. - -[cookie-session](https://www.npmjs.com/package/cookie-session) ara yazılımını kullanan bir örnek: - -```js -var session = require('cookie-session') -var express = require('express') -var app = express() - -var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 saat -app.use(session({ - name: 'session', - keys: ['key1', 'key2'], - cookie: { - secure: true, - httpOnly: true, - domain: 'example.com', - path: 'foo/bar', - expires: expiryDate - } -})) -``` - -## Otorizasyona karşı yapılan brute-force saldırılarını engelleyin - -Özel verileri daha güvenli hale getirmek için giriş uç noktalarının (endpoint) korunduğundan emin olun. - -Basit ve güçlü bir teknik olarak iki ölçüm kullanarak yetkilendirme girişimlerini engellemektir: -1. Birincisi, aynı kullanıcı adı ve IP adresi ile art arda başarısız denemelerin sayısı. -2. İkincisi, uzun bir süre boyunca bir IP adresinden başarısız denemelerin sayısıdır. Örneğin, bir IP adresi bir günde 100 başarısız deneme yaparsa engelleyin. - -[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) paketi bu tekniği kolay ve hızlıca uygulamak için gerekli araçları sağlar. [brute-force korumasına bir örneği bu dökümantasyonda bulabilirsiniz](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection). - -## Bağımlılıklarınızın güvende olduğundan emin olun - -Uygulamanızın bağımlılıklarını yönetmek için npm kullanmak güçlü ve kullanışlıdır. Ancak kullandığınız paketler, uygulamanızı da etkileyebilecek kritik güvenlik açıkları içerebilir. Uygulamanızın güvenliği, bağımlılıklarınızdaki "en zayıf halka" kadar güçlüdür. - -npm@6'dan beri npm otomatik olarak her yükleme isteğini inceler. Ayrıca 'npm audit' komutunu kullanarak bağımlılık ağacınızı analiz edebilirsiniz. - -```sh -$ npm audit -``` - -Daha fazla güvenli kalmak istiyorsanız, [Snyk](https://snyk.io/) aracını gözden geçirebilirsiniz. - -Bağımlılıklarınızdaki bilinen tüm güvenlik açıkları için [Synk'in açık kaynak güvenlik açığı veritabanı](https://snyk.io/vuln/)'na karşı uygulamanızı kontrol eden bir [komut satırı aracı](https://www.npmjs.com/package/snyk) ve de [Github integrasyonu](https://snyk.io/docs/github) sunar. - -```sh -$ npm install -g snyk -$ cd your-app -``` - -Uygulamanızı güvenlik açıklarına karşı test etmek için bu komutu kullanın: - -```sh -$ snyk test -``` - -Bulunan güvenlik açıklarını düzeltmek için güncelleme veya yama uygulama sürecinde size yol gösteren bir sihirbazı açmak için bu komutu kullanın: - -```sh -$ snyk wizard -``` - -## Bilinen diğer güvenlik açıklarından kaçının - -Express'i veya uygulamanızın kullandığı diğer modülleri etkileyen [Snyk](https://snyk.io/vuln/) ve [Node Security Project](https://npmjs.com/advisories) tavsiyelerini takipte kalın. Genel olarak, bu veritabanları Node güvenliği hakkında bilgi ve araçlar için mükemmel kaynaklardır. - -Son olarak, Express uygulamaları - diğer web uygulamaları gibi - çeşitli web tabanlı saldırılara karşı savunmasız olabilir. [Web güvenlik açıkları](https://www.owasp.org/index.php/Top_10-2017_Top_10) hakkında kendinizi bilgilendirin ve onlardan kaçınmak için önlemler alın. - -## Ek hususlar - -İşte mükemmel [Node.js Güvenlik Kontrol Listesi](https://blog.risingstack.com/node-js-security-checklist/)'nden bazı ek öneriler. Bu önerilerle ilgili tüm ayrıntılar için o blog gönderisine bakın: - -* Siteler arası istek sahteciliği'ne (CSRF) karşı korumak için [csurf](https://www.npmjs.com/package/csurf) ara yazılımını kullanın. -* Siteler arası komut dosyası oluşturma (XSS) ve komut enjeksiyon saldırılarına karşı korumak için kullanıcı girişini her zaman filtreleyin ve sanitize edin. -* Parametreli sorgular veya hazırlanmış ifadeler kullanarak SQL enjeksiyon saldırılarına karşı savunma yapın. -* Uygulamanızdaki SQL enjeksion güvenlik açıklarını tespit etmek için açık kaynak olan [sqlmap](http://sqlmap.org/) aracını kullanın. -* Sertifikanızın geçerliliğini kontrol etmenin yanında SSL şifrelerinin ve anahtarlarının konfigürasyonunu test etmek için [nmap](https://nmap.org/) ve [sslyze](https://github.com/nabla-c0d3/sslyze) araçlarını kullanın. -* Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [Regular expression Denial of Service (ReDoS)](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacks. - -* RegExp kodlarınızın [Regular expression Denial of Service (ReDoS)](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) saldırılarına açık olmadığını sağlamak için [safe-regex](https://www.npmjs.com/package/safe-regex) paketini kullanın. diff --git a/tr/advanced/developing-template-engines.md b/tr/advanced/developing-template-engines.md deleted file mode 100644 index cfdd100c24..0000000000 --- a/tr/advanced/developing-template-engines.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -layout: page -title: Express için şablon motoru geliştirme -menu: advanced -lang: tr ---- -
      -# Developing template engines for Express - -Use the `app.engine(ext, callback)` method to create your own template engine. `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. - -The following code is an example of implementing a very simple template engine for rendering `.ntl` files. - -```js -var fs = require('fs') // this engine requires the fs module -app.engine('ntl', function (filePath, options, callback) { // define the template engine - fs.readFile(filePath, function (err, content) { - if (err) return callback(err) - // this is an extremely simple template engine - var rendered = content.toString().replace('#title#', '' + options.title + '') - .replace('#message#', '

      ' + options.message + '

      ') - return callback(null, rendered) - }) -}) -app.set('views', './views') // specify the views directory -app.set('view engine', 'ntl') // register the template engine -``` - -Your app will now be able to render `.ntl` files. Create a file named `index.ntl` in the `views` directory with the following content. - -```text -#title# -#message# -``` -Then, create the following route in your app. - -```js -app.get('/', function (req, res) { - res.render('index', { title: 'Hey', message: 'Hello there!' }) -}) -``` -When you make a request to the home page, `index.ntl` will be rendered as HTML. -
      diff --git a/tr/advanced/pm.md b/tr/advanced/pm.md deleted file mode 100644 index b9e484abc1..0000000000 --- a/tr/advanced/pm.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: page -title: Express uygulamaları için Süreç yöneticileri -menu: advanced -lang: tr -redirect_from: "/advanced/pm.html" ---- - -# Express uygulamaları için Süreç yöneticileri - -{% include community-caveat.html %} - -Canlı ortam için Express uygulamaları koştuğunuzda aşağıdaki nedenlerden ötürü bir _süreç yöneticisi_ kullanmak faydalı olacaktır: - -- Uygulama patladığında otomatik olarak tekrar başlatmak. -- Çalışma zamanı performansı ve kaynak tüketimi hakkında daha iyi bilgiler elde edinmek. -- Performansı iyileştirmek için ayarları dinamik olarak değiştirmek. -- Kümelemeyi (clustering) kontrol etmek. - -Süreç yöneticisi, bir nevi bir uygulama sunucusuna benzer: dağıtımı kolaylaştıran, yüksek kullanılabilirlik sağlayan ve uygulamayı çalışma zamanında (runtime) yönetmenizi sağlayan, uygulamalar için bir "kapsayıcı" (container)dır. - -Express ve diğer Node.js uygulamaları için en popüler süreç yöneticileri şunlardır: - -- **[Forever](https://github.com/foreverjs/forever){: target="_blank"}**: Bir komut dosyasının sürekli (sonsuza kadar) çalışmasını sağlamak için basit bir komut satırı arayüzü aracı. Forever'ın basit arayüzü, Node.js uygulamalarının ve komut dosyalarının küçük dağıtımlarını çalıştırmak için idealdir. -- **[PM2](https://github.com/Unitech/pm2){: target="_blank"}**: Gömülü bir yük dengeleyiciye (load balancer) sahip, Node.js uygulamaları için bir canlı ortam süreç yöneticisi. PM2, uygulamaları sonsuza kadar canlı tutmanıza olanak tanır, kesinti olmadan yeniden yükler, loglamayı, izleme (monitoring) ve kümelemeyi yönetmenize yardımcı olur. -- **[StrongLoop Process Manager (Strong-PM)](http://strong-pm.io/)**: Gömülü yük dengeleme (load balancer), izleme (monitoring) ve çoklu dağıtıma özelliklerine sahip, Node.js uygulamaları için bir canlı ortam süreç yöneticisi. Node.js uygulamalarını oluşturmak (build), paketlemek ve yerel (local) veya uzak bir sisteme dağıtmak için bir CLI içerir. -- **SystemD**: Modern Linux dağıtımlarındaki varsayılan süreç yöneticisi, bir Node uygulamasının servis olarak çalıştırılmasını kolaylaştırır. Daha fazla bilgi için bakınız ["Run node.js service with systemd" by Ralph Slooten (@axllent)](https://www.axllent.org/docs/view/nodejs-service-with-systemd/). diff --git a/tr/advanced/security-updates.md b/tr/advanced/security-updates.md deleted file mode 100644 index 35bc2ec620..0000000000 --- a/tr/advanced/security-updates.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -layout: page -title: Express Güvenlik Güncellemeleri -menu: advanced -lang: tr ---- -
      - -# Security updates - -
      -Node.js vulnerabilities directly affect Express. Therefore [keep a watch on Node.js vulnerabilities](http://blog.nodejs.org/vulnerability/) and make sure you are using the latest stable version of Node.js. -
      - -The list below enumerates the Express vulnerabilities that were fixed in the specified version update. - -**NOTE**: If you believe you have discovered a security vulnerability in Express, please see -[Security Policies and Procedures](https://github.com/expressjs/express/blob/master/Security.md). - -## 4.x - - * 4.15.2 - * The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. - * 4.11.1 - * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` - * 4.10.7 - * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 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 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. - * 4.8.0 - * Sparse arrays that have extremely high indexes in the query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - -## 3.x - -
      - **Express 3.x IS NO LONGER MAINTAINED** - - Known and unknown security issues in 3.x have not been addressed since the last update (1 August, 2015). Using the 3.x line should not be considered secure. -
      - - * 3.19.1 - * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` - * 3.19.0 - * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Fixed directory traversal vulnerabilities in `express.static`. - * 3.16.6 - * Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. - * 3.16.0 - * Sparse arrays that have extremely high indexes in query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - * 3.3.0 - * The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks. -
      diff --git a/tr/api.md b/tr/api.md deleted file mode 100644 index 46edc86ae0..0000000000 --- a/tr/api.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API Reference -lang: tr ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/tr/changelog/4x.md b/tr/changelog/4x.md deleted file mode 100644 index 3699a13c58..0000000000 --- a/tr/changelog/4x.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -layout: page -title: Express 4.x Sürüm Notları -menu: changelog -lang: tr ---- -
      -# Release Change Log - -## 4.15.3 - Release date: 2017-05-16 -{: id="4.15.3"} - -The 4.15.3 patch release including some minor bug fixes: - -
        -
      • - Fix error when `res.set` cannot add charset to `Content-Type`. -
      • - -
      • - Fix missing `` in HTML document. -
      • -
      - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). - -## 4.15.2 - Release date: 2017-03-06 -{: id="4.15.2"} - -The 4.15.2 patch release including a minor bug fix: - -
        -
      • - Fix regression parsing keys starting with `[` in the extended (default) query parser. -
      • -
      - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). - -## 4.15.1 - Release date: 2017-03-05 -{: id="4.15.1"} - -The 4.15.1 patch release including a minor bug fix: - -
        -
      • - Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. -
      • -
      - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). - -## 4.15.0 - Release date: 2017-03-01 -{: id="4.15.0"} - -The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: - -
        -
      • - Starting with this version, Express supports Node.js 7.x. -
      • - -
      • - The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. -
      • - -
      • - Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). -
      • - -
      • - Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. -
      • -
      - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). - -## 4.14.1 - Release date: 2017-01-28 -{: id="4.14.1"} - -The 4.14.1 patch release includes bug fixes and performance improvements, including: - -
        -
      • - Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. -
      • -
      - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). - -## 4.14.0 - Release date: 2016-06-16 -{: id="4.14.0"} - -The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: - -
        -
      • - Starting with this version, Express supports Node.js 6.x. -
      • - -
      • - Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). -
      • - -
      • - The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. - - - `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. - - - `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. - - - `res.sendFile` has also been updated to handle `Range` header and redirections better. -
      • - -
      • - The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. -
      • - -
      • - The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. -
      • - -
      • - The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). NOTE: This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. - - The possible value for the `sameSite` option are: - - - `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. - - `false`, which does not set the `SameSite` attribute. - - `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. - - `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. -
      • - -
      • - Absolute path checking on Windows, which was incorrect for some cases, has been fixed. -
      • - -
      • - IP address resolution with proxies has been greatly improved. -
      • - -
      • - The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. -
      • -
      - -For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). -
      diff --git a/tr/guide/behind-proxies.md b/tr/guide/behind-proxies.md deleted file mode 100644 index bdf352dc5f..0000000000 --- a/tr/guide/behind-proxies.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -layout: page -title: Proxy arkasında Express -menu: guide -lang: tr -redirect_from: "/guide/behind-proxies.html" ---- -# Proxy arkasında Express - -Bir proxy'nin arkasında bir Express uygulaması koşulduğunda, ([app.set()](/{{ page.lang }}/4x/api.html#app.set) kullanarak) `trust proxy` uygulama değişkenine aşağıdaki tabloda listelenen değerlerden birini verin. - -
      -`trust proxy` uygulama değişkeni ayarlanmadığında uygulama başarısız olmayacağına rağmen, `trust proxy` ayarlanmadıkça istemci IP adresini proxy IP adresiyle hatalı olarak kaydedecektir. -
      - - - - - - - - - - - - - - - - - - - - - -
      TipDeğer
      Boolean -`true` olduğunda, istemci IP adresi `X-Forwarded-*` başlığında en soldaki giriş olarak değerlendirilir. - -`false` olduğunda, uygulama direkt olarak Internete dönük olacak ve istemci IP adresi ise `req.connection.remoteAddress` alanından alınmış olacak. Bu varsayılan ayardır. -
      IP adresleri -Güvenilecek bir IP adresi, alt ağ, veya bir IP adresleri ve alt ağlar dizisi. Aşağıdaki liste önceden yapılandırılmış alt ağlar isimlerini gösteriyor: - -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` - -IP adreslerini aşağıdaki yöntemlerden herhangi biriyle ayarlayabilirsiniz: - -```js -app.set('trust proxy', 'loopback') // tek bir alt ağ tanımla -app.set('trust proxy', 'loopback, 123.123.123.123') // bir adres ve bir alt ağ tanımla -app.set('trust proxy', 'loopback, linklocal, uniquelocal') // birden çok alt ağları CVS olarak tanımla -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // bir dizi olarak birden çok alt ağ tanımla -``` - -Belirtildiğinde, IP adresleri veya alt ağlar adres belirleme işleminin dışında bırakılır ve uygulama sunucusuna en yakın güvenilmeyen IP adresi, istemcinin IP adresi olarak belirlenir. - -
      Sayı -İstemci olarak ön proxy sunucusundan `n`'ci atlayışına güvenin. -
      Fonksiyon -Özel güven implementasyonu. Bunu sadece ne yaptığınızı biliyorsanız kullanın. - - -```js -app.set('trust proxy', function (ip) { - if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // güvenilen IP'ler - else return false -}) -``` -
      - -`trust proxy` ayarını etkinleştirmenin etkileri aşağıdaki gibidir: - -
        -
      • [req.hostname](/{{ page.lang }}/api.html#req.hostname) alanının değeri, istemci veya proxy tarafından ayarlanabilen `X-Forwarded-Host` başlığındaki değerler kümesinden alınacak. -
      • -
      • `X-Forwarded-Proto` değeri; `https`, `http` veya geçersiz bir ad olduğunu uygulamaya belirtmesi için ters proxy tarafından ayarlanabilir. Bu değer, [req.protocol](/{{ page.lang }}/api.html#req.protocol) tarafından yansıtılır. -
      • -
      • [req.ip](/{{ page.lang }}/api.html#req.ip) ve [req.ips](/{{ page.lang }}/api.html#req.ips) alanlarının değerleri, `X-Forwarded-For` başlığındaki adres listesi ile doldurulur. -
      • -
      - -`trust proxy` ayarı [proxy-addr](https://www.npmjs.com/package/proxy-addr) paketi kullanılarak uygulanmıştır. Daha fazla bilgi için, dökümantasyonuna bakınız. diff --git a/tr/guide/database-integration.md b/tr/guide/database-integration.md deleted file mode 100644 index 711ebec33c..0000000000 --- a/tr/guide/database-integration.md +++ /dev/null @@ -1,490 +0,0 @@ ---- -layout: page -title: Express veritabanı integrasyonu -menu: guide -lang: tr -redirect_from: "/guide/database-integration.html" ---- -# Veritabanı integrasyonu - -Veritabanlarını Express uygulamalarına bağlama kabiliyeti eklemek, uygulamanızdaki veritabanı için uygun bir Node.js sürücüsünü yükleyerek yapılabilecek kadar kolaydır. Bu döküman, Express uygulamanıza veritabanı sistemleri için bazı popüler Node.js modüllerinin nasıl eklendiğini ve kullanıldığını kısaca anlatır: - -* [Cassandra](#cassandra) -* [Couchbase](#couchbase) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongodb) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgresql) -* [Redis](#redis) -* [SQL Server](#sql-server) -* [SQLite](#sqlite) -* [Elasticsearch](#elasticsearch) - -
      -Bu veritabanı sürücüleri mevcut olanların çoğunun arasındadır. Diğer seçenekler için, [npm](https://www.npmjs.com/) sitesinde arayınız. -
      - -## Cassandra - -**Module**: [cassandra-driver](https://github.com/datastax/nodejs-driver) - -### Yükleme - -```sh -$ npm install cassandra-driver -``` - -### Örnek - -```js -var cassandra = require('cassandra-driver') -var client = new cassandra.Client({ contactPoints: ['localhost'] }) - -client.execute('select key from system.local', function (err, result) { - if (err) throw err - console.log(result.rows[0]) -}) -``` - -## Couchbase - -**Module**: [couchnode](https://github.com/couchbase/couchnode) - -### Yükleme - -```sh -$ npm install couchbase -``` - -### Örnek - -```js -var couchbase = require('couchbase') -var bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') - -// bir dökümanı bir kovaya ekle -bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, result) { - if (err) { - console.log(err) - } else { - console.log(result) - } -}) - -// "shoe" alanının değeri 13 olan bütün dökümanları getir -var n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' -var query = N1qlQuery.fromString(n1ql) -bucket.query(query, [13], function (err, result) { - if (err) { - console.log(err) - } else { - console.log(result) - } -}) -``` - -## CouchDB - -**Module**: [nano](https://github.com/dscape/nano) - -### Yükleme - -```sh -$ npm install nano -``` - -### Örnek - -```js -var nano = require('nano')('http://localhost:5984') -nano.db.create('books') -var books = nano.db.use('books') - -// books veritabanına bir kitap ekle -books.insert({ name: 'The Art of war' }, null, function (err, body) { - if (err) { - console.log(err) - } else { - console.log(body) - } -}) - -// bütün kitapların bir listesini getir -books.list(function (err, body) { - if (err) { - console.log(err) - } else { - console.log(body.rows) - } -}) -``` - -## LevelDB - -**Module**: [levelup](https://github.com/rvagg/node-levelup) - -### Yükleme - -```sh -$ npm install level levelup leveldown -``` - -### Örnek - -```js -var levelup = require('levelup') -var db = levelup('./mydb') - -db.put('name', 'LevelUP', function (err) { - if (err) return console.log('Ooops!', err) - - db.get('name', function (err, value) { - if (err) return console.log('Ooops!', err) - - console.log('name=' + value) - }) -}) -``` - -## MySQL - -**Module**: [mysql](https://github.com/felixge/node-mysql/) - -### Yükleme - -```sh -$ npm install mysql -``` - -### Örnek - -```js -var mysql = require('mysql') -var connection = mysql.createConnection({ - host: 'localhost', - user: 'dbuser', - password: 's3kreee7', - database: 'my_db' -}) - -connection.connect() - -connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) { - if (err) throw err - - console.log('The solution is: ', rows[0].solution) -}) - -connection.end() -``` - -## MongoDB - -**Module**: [mongodb](https://github.com/mongodb/node-mongodb-native) - -### Yükleme - -```sh -$ npm install mongodb -``` - -### Örnek (v2.*) - -```js -var MongoClient = require('mongodb').MongoClient - -MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { - if (err) throw err - - db.collection('mammals').find().toArray(function (err, result) { - if (err) throw err - - console.log(result) - }) -}) -``` - -### Örnek (v3.*) - -```js -var MongoClient = require('mongodb').MongoClient - -MongoClient.connect('mongodb://localhost:27017/animals', function (err, client) { - if (err) throw err - - var db = client.db('animals') - - db.collection('mammals').find().toArray(function (err, result) { - if (err) throw err - - console.log(result) - }) -}) -``` - -MongoDB için bir nesne model sürücüsü istiyorsanız, bakınız [Mongoose](https://github.com/LearnBoost/mongoose). - -## Neo4j - -**Module**: [apoc](https://github.com/hacksparrow/apoc) - -### Yükleme - -```sh -$ npm install apoc -``` - -### Örnek - -```js -var apoc = require('apoc') - -apoc.query('match (n) return n').exec().then( - function (response) { - console.log(response) - }, - function (fail) { - console.log(fail) - } -) -``` - -## Oracle - -**Module**: [oracledb](https://github.com/oracle/node-oracledb) - -### Yükleme - - NOTE: [Yükleme önkoşulları için bakınız](https://github.com/oracle/node-oracledb#-installation). - -```sh -$ npm install oracledb -``` - -### Örnek - -```js -const oracledb = require('oracledb') -const config = { - user: '', - password: '', - connectString: 'localhost:1521/orcl' -} - -async function getEmployee (empId) { - let conn - - try { - conn = await oracledb.getConnection(config) - - const result = await conn.execute( - 'select * from employees where employee_id = :id', - [empId] - ) - - console.log(result.rows[0]) - } catch (err) { - console.log('Ouch!', err) - } finally { - if (conn) { // conn görevi çalıştı, kapatılmalı - await conn.close() - } - } -} - -getEmployee(101) -``` - -## PostgreSQL - -**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise) - -### Yükleme - -```sh -$ npm install pg-promise -``` - -### Örnek - -```js -var pgp = require('pg-promise')(/* seçenekler */) -var db = pgp('postgres://username:password@host:port/database') - -db.one('SELECT $1 AS value', 123) - .then(function (data) { - console.log('DATA:', data.value) - }) - .catch(function (error) { - console.log('ERROR:', error) - }) -``` - -## Redis - -**Module**: [redis](https://github.com/mranney/node_redis) - -### Yükleme - -```sh -$ npm install redis -``` - -### Örnek - -```js -var redis = require('redis') -var client = redis.createClient() - -client.on('error', function (err) { - console.log('Error ' + err) -}) - -client.set('string key', 'string val', redis.print) -client.hset('hash key', 'hashtest 1', 'some value', redis.print) -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print) - -client.hkeys('hash key', function (err, replies) { - console.log(replies.length + ' replies:') - - replies.forEach(function (reply, i) { - console.log(' ' + i + ': ' + reply) - }) - - client.quit() -}) -``` - -## SQL Server - -**Module**: [tedious](https://github.com/tediousjs/tedious) - -### Yükleme - -```sh -$ npm install tedious -``` - -### Örnek - -```js -var Connection = require('tedious').Connection -var Request = require('tedious').Request - -var config = { - server: 'localhost', - authentication: { - type: 'default', - options: { - userName: 'your_username', // güncelle - password: 'your_password' // güncelle - } - } -} - -var connection = new Connection(config) - -connection.on('connect', function (err) { - if (err) { - console.log(err) - } else { - executeStatement() - } -}) - -function executeStatement () { - request = new Request("select 123, 'hello world'", function (err, rowCount) { - if (err) { - console.log(err) - } else { - console.log(rowCount + ' rows') - } - connection.close() - }) - - request.on('row', function (columns) { - columns.forEach(function (column) { - if (column.value === null) { - console.log('NULL') - } else { - console.log(column.value) - } - }) - }) - - connection.execSql(request) -} -``` - -## SQLite - -**Module**: [sqlite3](https://github.com/mapbox/node-sqlite3) - -### Yükleme - -```sh -$ npm install sqlite3 -``` - -### Örnek - -```js -var sqlite3 = require('sqlite3').verbose() -var db = new sqlite3.Database(':memory:') - -db.serialize(function () { - db.run('CREATE TABLE lorem (info TEXT)') - var stmt = db.prepare('INSERT INTO lorem VALUES (?)') - - for (var i = 0; i < 10; i++) { - stmt.run('Ipsum ' + i) - } - - stmt.finalize() - - db.each('SELECT rowid AS id, info FROM lorem', function (err, row) { - console.log(row.id + ': ' + row.info) - }) -}) - -db.close() -``` - -## Elasticsearch - -**Module**: [elasticsearch](https://github.com/elastic/elasticsearch-js) - -### Yükleme - -```sh -$ npm install elasticsearch -``` - -### Örnek - -```js -var elasticsearch = require('elasticsearch') -var client = elasticsearch.Client({ - host: 'localhost:9200' -}) - -client.search({ - index: 'books', - type: 'book', - body: { - query: { - multi_match: { - query: 'express js', - fields: ['title', 'description'] - } - } - } -}).then(function (response) { - var hits = response.hits.hits -}, function (error) { - console.trace(error.message) -}) -``` \ No newline at end of file diff --git a/tr/guide/debugging.md b/tr/guide/debugging.md deleted file mode 100644 index e49be4e0c0..0000000000 --- a/tr/guide/debugging.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -layout: page -title: Express hata ayıklama -menu: guide -lang: tr -redirect_from: "/guide/debugging.html" ---- -# Express hata ayıklama - -Express, rota eşleştirmeleri, kullanımda olan ara yazılım fonksiyonları, uygulama modu, ve istek-yanıt döngüsü akışı ile ilgili bilgileri loglamak için dahili olarak [debug](https://www.npmjs.com/package/debug) mödülünü kullanmaktadır. - -
      -`debug`, `console.log` metodunun uzatılmış bir sürümü gibidir, ama `console.log` metodunun aksine, üretim kodunda `debug` ifadelerini yorum satırına almak zorunda değilsiniz. Loglama varsayılan olarak devre dışı bırakılmıştır ve şarta bağlı olarak `DEBUG` ortam değişkeni kullanılarak devreye alınabilir. -
      -Express uygulamasında kullanılan ütün dahili logları görmek için, uygulamanızı başlatırken `DEBUG` ortam değikenini `express:*` olarak güncelleyin. - -```sh -$ DEBUG=express:* node index.js -``` - -Windows'ta aynı komutun karşılığını kullanın. - -```sh -> set DEBUG=express:* & node index.js -``` -[express generator](/{{ page.lang }}/starter/generator.html) kullanılarak yaratılan varsayılan uygulamada bu komutu koşmak aşağıdakileri yazdıracak: - -```sh -$ 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 / <anonymous> +0ms - express:router:layer new / +0ms - express:router use / <anonymous> +0ms - express:router:layer new / +0ms - express:router use / <anonymous> +0ms - express:router:layer new / +0ms -``` - -Ve uygulamaya bir istek yapıldığında, Express kodunda belirtilen logları göreceksiniz: - -```sh - 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 -``` - -Sadece yönlendirme implementasyonundan logları görmek için, `DEBUG` değişkenini `express:router` olarak ayarlayın. Aynı şekilde, sadece uygulama implementasyonundan logları görmek için `DEBUG` değişkenini `express:application` olarak ayarlayın, ve benzeri. - -## `express` tarafından yaratılan uygulamalar - -`express` komutu tarafından yaratılan bir uygulama da `debug` modülünü kullanır ve hata ayıklama isim alanı, uygulamanın isiminin kapsamı içine alınır. - -Örneğin, `$ express sample-app` ile bir uygulama yarattığınızda, debug ifadelerini aşağıdaki komutla etkinleştirebilirsiniz: - -```sh -$ DEBUG=sample-app:* node ./bin/www -``` - -Virgül ile ayrılmış bir isimler listesini atayarak birden fazla debug isim alanı belirtebilirsiniz: - -```sh -$ DEBUG=http,mail,express:* node index.js -``` - -## Gelişmiş seçenekler - -Node.js üzerinden koşulduğunda hata ayıklama loglamasının davranışını değiştirecek birkaç ortam değişkeni ayarlayabilirsiniz: - -| İsim | Amaç | -|-----------|-------------------------------------------------| -| `DEBUG` | Spesifik hata ayıklama isim alanlarını devre dışı bırakma veya etkinleştirme. | -| `DEBUG_COLORS`| Hata ayıklama çıktısında renk kullanıp kullanmama.| -| `DEBUG_DEPTH` | Nesne inceleme derinliği.| -| `DEBUG_FD` | Hata ayıklama çıktısının yazılacağı dosya tanımlayıcı. | -| `DEBUG_SHOW_HIDDEN` | İncelenen nesnelerde gizli özellikleri gösterme. | - -__Not:__ `DEBUG_` ile başlayan ortam değişkenleri, `%o`/`%O` biçemleyicileriyle kullanılmak üzere bir Seçenekler nesnesine dönüştürülür. -Tam listeyi görmek için Node.js'in [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) dökümantasyonuna bakınız. - -## Kaynaklar - -`debug` ile ilgili daha fazla bilgi için bakınız [debug](https://www.npmjs.com/package/debug). diff --git a/tr/guide/error-handling.md b/tr/guide/error-handling.md deleted file mode 100644 index e2f89ff1ae..0000000000 --- a/tr/guide/error-handling.md +++ /dev/null @@ -1,248 +0,0 @@ ---- -layout: page -title: Express hata işleme -menu: guide -lang: tr -redirect_from: "/guide/error-handling.html" ---- -# Hata İşleme - -_Error Handling_, senkron ve asenkron olarak meydana gelen hataların Express tarafından nasıl yakalandığına ve işlendiğine değinir. Express varsayılan olarak bir hata işleyiciyle gelir, bu nedenle hata işlemeye başlamak için kendinizin yazmanıza gerek yoktur. - -## Hataları Yakalamak - -Express tarafından, rota işleyicileri ve ara yazılımları koşarken oluşan hataların yakalanmasının sağlanması önemlidir. -Rota işleyicilerinde ve ara yazılımlarda senkron kodda oluşan hataları yakalamak için ek birşey yapmaka gerek yoktur. Eğer senkron kod bir hata fırlatırsa, Express onu yakalayıp işleyecektir. Örneğin: - -```js -app.get('/', function (req, res) { - throw new Error('BROKEN') // Express bunu kendi kendine yakalayacak -}) -``` - -Rota işleyicileri ve ara yazılım tarafından çağrılan asenkron fonksiyonlardan dönen hataları Express'in yakalayp işleyeceği `next()` fonksiyonuna vermelisiniz. Örnek olarak: - -```js -app.get('/', function (req, res, next) { - fs.readFile('/file-does-not-exist', function (err, data) { - if (err) { - next(err) // Hataları Express'e ver - } else { - res.send(data) - } - }) -}) -``` - -Express 5 ile başlayarak, Promise döndüren rota işleyicileri ve ara yazılımlar ret verdiklerinde (reject) veya hata fırlattıklarında otomatik olarak `next(value)` fonksiyonunu çağıracaklar. Örneğin: - -```js -app.get('/user/:id', async function (req, res, next) { - var user = await getUserById(req.params.id) - res.send(user) -}) -``` - -`getUserById` bir hata fırlattığında veya ret verdiğinde, `next` fonksiyonu ya fırlatılan hatayla ya da ret verilen değer ile çağrılacaktır. Eğer herhangi bir ret değeri verilmediyse, `next` fonksiyonu Express yönlendiricisi tarafından sağlanan varsayılan Error objesiyle çağrılacak. - -Eğer `next()` fonksiyonuna herhangi birşey verdiğinizde (`'route'` karakter dizisi hariç), Express şimdiki isteği bir hata olarak sayıp hata işlemeyen yönlendirici ve ara yazılım fonksiyonlarını es geçecektir. - -Eğer bir dizideki geri çağırma fonksiyonu veri sağlamıyorsa, sadece hataları veriyorsa, kodu bu şekilde basitleştirebilirsiniz: - -```js -app.get('/', [ - function (req, res, next) { - fs.writeFile('/erişilemez-yol', 'data', next) - }, - function (req, res) { - res.send('OK') - } -]) -``` - -Yukarıdaki örnekte `next`, hata veya hatasız olarak çağrılan `fs.writeFile` için geri çağırma fonksiyonu olarak verlidi. Eğer hata yok ise ikinci işleyici çalışacak, aksi takdirde Express hatayı yakalayıp işler. - -Rota işleyicileri ve ara yazılımlar tarafından çağrılan asenkron kodda oluşan hataları yakalayıp işlemesi için Express'e geçmelisiniz. Örnek olarak: - -```js -app.get('/', function (req, res, next) { - setTimeout(function () { - try { - throw new Error('BROKEN') - } catch (err) { - next(err) - } - }, 100) -}) -``` - -Yukarıdaki örnek asenkron kodda hataları yakalamak için bir `try...catch` bloku kullanıyor. Eğer `try...catch` bloku olmaz ise, işleyici senkron kodun bir parçası olmadığı için Express hatayı yakalamayacak. - -`try..catch` blokunun yükünden kaçınmak için promise veya promise döndüren fonksiyonlar kullanın. Örnek olarak: - -```js -app.get('/', function (req, res, next) { - Promise.resolve().then(function () { - throw new Error('BROKEN') - }).catch(next) // Hatalar Express'e geçer -}) -``` - -Promise'lar otomatik olarak senkron hatalarını ve ret edilen promise'ları yakaladığından, sonuncu yakalama işleyicisi olarak `next` fonksiyonunu verebilirsiniz ve Express hataları yakalar, çünkü yakalama işleyicisine birinci argüman olarak hata verimiştir. - -Senkron hata yakalamaya güvenmek için asenkron kodu basite indirgeyerek bir işleyiciler zincirini de kullanabilirsiniz. Örnek olarak: - - -```js -app.get('/', [ - function (req, res, next) { - fs.readFile('/maybe-valid-file', 'utf-8', function (err, data) { - res.locals.data = data - next(err) - }) - }, - function (req, res) { - res.locals.data = res.locals.data.split(',')[1] - res.send(res.locals.data) - } -]) -``` - -Yukarıdaki örnek `readFile` çağrısından birkaç basit ifadeye sahip. `readFile` bir hata alırsa, bu hatayı Express'e verir, aksi takdirde hızlı bir şekilde zincirdeki bir sonraki işleyicide asenkron hata işleme dünyasına dönersiniz. Ve, yukarıdaki örnek veriyi işlemeyi gösterir. Bu işlem hata verirse, onu senkron hata işleyicisi yakalayacak. Eğer bu işlemleri `readFile` geri çağırma fonksiyonunun içinde yaptıysanız uygulama kapanabilir ve Express hata işleyicileri çalışmaz. - -Hangi yöntemi kullanırsanız kullanın, Express hata işleyicilerinin çağrılmasını ve uygulamanın hayatta kalmasını istiyorsanız, Express'in hatayı aldığından emin olmalısınız. - -## Varsayılan hata işleyicisi - -Express, uygulamada oluşabilecek herhangi bir hatayla ilgilenecek gömülü bir hata işleyicisiyle gelir. Bu varsayıla hata işleyici ara yazılım fonksiyonu, ara yazlım fonksiyon yığınının en sonuna eklenir. - -`next()` fonksiyonuna bir hata verip özel bir hata işleyicisinde işlemezseniz, bu hata gömülü hata işleyicisi tarafından işlenir; hata istemcide stack-trace ile beraber yazdırılır. Stack-trace üretim (production) ortamında dahil değildir. - -
      -Uygulamayı üretim modunda koşmak için `NODE_ENV` ortam değişkeninin değerini `production` olarak ayarlayın. -
      - -Bir hata yazdırıldığında, aşağıdaki bilgiler yanıta eklenir: - -* `res.statusCode` alanının değeri `err.status` alanından gelir (veya `err.statusCode`). Eğer bu değer 4xx veya 5xx'in aralığında değilse, 500 olarak ayarlanacak. -* `res.statusMessage` alanı statü koduna göre ayarlanır. -* Üretim modunda ise, gövde (body) statü kodu mesajının HTML'i olur, aksi takdirde ise `err.stack`. -* `err.headers` objesinde belirtilen herhangi bir başlık (header). - -`next()` fonksiyonunu yanıtı yazmaya başladıktan sonra bir hata ile çağırırsanız (örneğin, istemciye yanıtı aktarma esnasında bir hata ile karşılaşırsanız) varsayılan Express hata işleyicisi bağlantıyı kapatıp isteği başarısız kılar. - -Özel bir hata işleyicisi eklediğiniz zaman başlıklar (header) halihazırda istemciye gönderilmiş ise varsayılan Express hata işleyicisine yetki vermelisiniz: - -```js -function errorHandler (err, req, res, next) { - if (res.headersSent) { - return next(err) - } - res.status(500) - res.render('error', { error: err }) -} -``` - -Kodunuzda `next()` fonksiyonunu bir hata ile birden fazla kez çağırdığınızda varsayılan hata işleyicisi tetiklenebilir, özel hata işleyici ara yazılımı yerinde olsa bile. - -## Hata işleyicileri yazmak - -Hata işleyici ara yazılım fonksiyonlarını diğer ara yazılım fonksiyonları gibi tanımlayınız, bundan farklı olarak hata işleyici fonksiyonlar üç yerine dört argümana sahipler: `(err, req, res, next)`. Örneğin: - -```js -app.use(function (err, req, res, next) { - console.error(err.stack) - res.status(500).send('Birşeyler bozuldu') -}) -``` - -Hata işleyici ara yazılımları diğer `app.use()` ve rotaların çağrılarından sonra, en son tanımlanır; örnek olarak: - -```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') - -app.use(bodyParser.urlencoded({ - extended: true -})) -app.use(bodyParser.json()) -app.use(methodOverride()) -app.use(function (err, req, res, next) { - // iş mantığı -}) -``` - -Ara yazılımdaki yanıtlar HTML hata sayfası, basit bir mesaj veya bir JSON karakter dizisi gibi herhangi bir biçimde olabilir. - -Organizasyonel (ve daha üst-düzey çatı) amaçlar için, normal ara yazılım fonksiyonları gibi, birden fazla hata-işleyici ara yazılım fonksiyonu tanımlayabilirsiniz. Örnek olarak, `XHR` kullanılan ve `XHR` kullanılmayan istekler için bir hata işleyici tanımlamak gibi: - -```js -var bodyParser = require('body-parser') -var methodOverride = require('method-override') - -app.use(bodyParser.urlencoded({ - extended: true -})) -app.use(bodyParser.json()) -app.use(methodOverride()) -app.use(logErrors) -app.use(clientErrorHandler) -app.use(errorHandler) -``` - -Bu örnekte, jenerik `logErrors`, `stderr`'a istek ve hata bilgileri yazabilir, örneğin: - -```js -function logErrors (err, req, res, next) { - console.error(err.stack) - next(err) -} -``` - -Ayrıca bu örnekte, `clientErrorHandler`aşağıdaki gibi tanımlanır; bu durumda, hata açıkça bir sonrakine aktarılır. - -Bir hata işleme fonksiyonunda "next" _çağrılmadığında_, yanıtın yazılmasından (ve sonlandırılmasından) siz sorumlusunuz. Aksi takdirde o istekler "havada" kalır ve çöp toplama (garbage collection) için geçerli olmayacaktır. - -```js -function clientErrorHandler (err, req, res, next) { - if (req.xhr) { - res.status(500).send({ error: 'Birşeyler ters gitti' }) - } else { - next(err) - } -} -``` - -"Hepsini-yakala" `errorHandler` fonksiyonunu aşağıdaki gibi tanımlayın: - -```js -function errorHandler (err, req, res, next) { - res.status(500) - res.render('error', { error: err }) -} -``` - -Birden fazla geri çağırma fonksiyonu olan bir rota işleyiciniz var ise bir sonraki rota işleyicisine geçmek için `route` parametresini kullanabilirsiniz. Örnek: - -```js -app.get('/a_route_behind_paywall', - function checkIfPaidSubscriber (req, res, next) { - if (!req.user.hasPaid) { - // bu isteği işlemeye devam et - next('route') - } else { - next() - } - }, function getPaidContent (req, res, next) { - PaidContent.find(function (err, doc) { - if (err) return next(err) - res.json(doc) - }) - }) -``` - -Bu örnekte, `getPaidContent` işleyicisi es geçilecek ama `app` uygulaması `/a_route_behind_paywall` yolu için geriye kalan herhangi bir işleyici çalışmaya devam edecek. - -
      -`next()` ve `next(err)` fonksiyonlarına yapılacak çağrılar şimdiki işleyicinin tamamlandığını ve hangi durumda tamamlandıklarını belirtir. `next(err)` çağrısı, yukarıda gösterildiği gibi hata işlemek için kurulanlar hariç, zincirde geriye kalan bütün işleyicileri es geçer. -
      diff --git a/tr/guide/migrating-4.md b/tr/guide/migrating-4.md deleted file mode 100644 index 676783edce..0000000000 --- a/tr/guide/migrating-4.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -layout: page -title: Migrating to Express 4 -menu: guide -lang: tr ---- -
      -# Moving to Express 4 - -

      Overview

      - -Express 4 is a breaking change from Express 3. That means an existing Express 3 app will _not_ work if you update the Express version in its dependencies. - -This article covers: - - - -

      Changes in Express 4

      - -There are several significant changes in Express 4: - - - -See also: - -* [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) - -

      -Changes to Express core and middleware system -

      - -Express 4 no longer depends on Connect, and removes all built-in -middleware from its core, except for the `express.static` function. This means that -Express is now an independent routing and middleware web framework, and -Express versioning and releases are not affected by middleware updates. - -Without built-in middleware, you must explicitly add all the -middleware that is required to run your app. Simply follow these steps: - -1. Install the module: `npm install --save ` -2. In your app, require the module: `require('module-name')` -3. Use the module according to its documentation: `app.use( ... )` - -The following table lists Express 3 middleware and their counterparts in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Express 3Express 4
      express.bodyParserbody-parser + -multer
      express.compresscompression
      express.cookieSessioncookie-session
      express.cookieParsercookie-parser
      express.loggermorgan
      express.sessionexpress-session
      express.faviconserve-favicon
      express.responseTimeresponse-time
      express.errorHandlererrorhandler
      express.methodOverridemethod-override
      express.timeoutconnect-timeout
      express.vhostvhost
      express.csrfcsurf
      express.directoryserve-index
      express.staticserve-static
      - -Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. - -In most cases, you can simply replace the old version 3 middleware with -its Express 4 counterpart. For details, see the module documentation in -GitHub. - -

      app.use accepts parameters

      - -In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler. -For example: - -```js -app.use('/book/:id', function (req, res, next) { - console.log('ID:', req.params.id) - next() -}) -``` -

      -The routing system -

      - -Apps now implicitly load routing middleware, so you no longer have to -worry about the order in which middleware is loaded with respect to -the `router` middleware. - -The way you define routes is unchanged, but the routing system has two -new features to help organize your routes: - -{: .doclist } -* A new method, `app.route()`, to create chainable route handlers for a route path. -* A new class, `express.Router`, to create modular mountable route handlers. - -

      app.route() method

      - -The new `app.route()` method enables you to create chainable route handlers -for a route path. Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more -information about routes, see [`Router()` documentation](/{{ page.lang }}/4x/api.html#router). - -Here is an example of chained route handlers that are defined by using the `app.route()` function. - -```js -app.route('/book') - .get(function (req, res) { - res.send('Get a random book') - }) - .post(function (req, res) { - res.send('Add a book') - }) - .put(function (req, res) { - res.send('Update the book') - }) -``` - -

      express.Router class

      - -The other feature that helps to organize routes is a new class, -`express.Router`, that you can use 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 middleware in -it, defines some routes, and mounts it on a path on the main app. - -For example, create a router file named `birds.js` in the app directory, -with the following content: - -```js -var express = require('express') -var router = express.Router() - -// middleware specific to this router -router.use(function timeLog (req, res, next) { - console.log('Time: ', Date.now()) - next() -}) -// define the home page route -router.get('/', function (req, res) { - res.send('Birds home page') -}) -// define the about route -router.get('/about', function (req, res) { - res.send('About birds') -}) - -module.exports = router -``` - -Then, load the router module in the app: - -```js -var birds = require('./birds') - -// ... - -app.use('/birds', birds) -``` - -The app will now be able to handle requests to the `/birds` and -`/birds/about` paths, and will call the `timeLog` -middleware that is specific to the route. - -

      -Other changes -

      - -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. -
      - -

      Example app migration

      - -Here is an example of migrating an Express 3 application to Express 4. -The files of interest are `app.js` and `package.json`. - -

      -Version 3 app -

      - -

      app.js

      - -Consider an Express v.3 application with the following `app.js` file: - -```js -var express = require('express') -var routes = require('./routes') -var user = require('./routes/user') -var http = require('http') -var path = require('path') - -var app = express() - -// all environments -app.set('port', process.env.PORT || 3000) -app.set('views', path.join(__dirname, 'views')) -app.set('view engine', 'pug') -app.use(express.favicon()) -app.use(express.logger('dev')) -app.use(express.methodOverride()) -app.use(express.session({ secret: 'your secret here' })) -app.use(express.bodyParser()) -app.use(app.router) -app.use(express.static(path.join(__dirname, 'public'))) - -// development only -if (app.get('env') === 'development') { - app.use(express.errorHandler()) -} - -app.get('/', routes.index) -app.get('/users', user.list) - -http.createServer(app).listen(app.get('port'), function () { - console.log('Express server listening on port ' + app.get('port')) -}) -``` - -

      package.json

      - -The accompanying version 3 `package.json` file might look - something like this: - -```json -{ - "name": "application-name", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "node app.js" - }, - "dependencies": { - "express": "3.12.0", - "pug": "*" - } -} -``` - -

      -Process -

      - -Begin the migration process by installing the required middleware for the -Express 4 app and updating Express and Pug to their respective latest -version with the following command: - -```sh -$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save -``` - -Make the following changes to `app.js`: - -1. The built-in Express middleware functions `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` and - `express.errorHandler` are no longer available on the - `express` object. You must install their alternatives - manually and load them in the app. - -2. You no longer need to load the `app.router` function. - It is not a valid Express 4 app object, so remove the - `app.use(app.router);` code. - -3. Make sure that the middleware functions are loaded in the correct order - load `errorHandler` after loading the app routes. - -

      Version 4 app

      - -

      package.json

      - -Running the above `npm` command will update `package.json` as follows: - -```json -{ - "name": "application-name", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "node app.js" - }, - "dependencies": { - "body-parser": "^1.5.2", - "errorhandler": "^1.1.1", - "express": "^4.8.0", - "express-session": "^1.7.2", - "pug": "^2.0.0", - "method-override": "^2.1.2", - "morgan": "^1.2.2", - "multer": "^0.1.3", - "serve-favicon": "^2.0.1" - } -} -``` - -

      app.js

      - -Then, remove invalid code, load the required middleware, and make other -changes as necessary. The `app.js` file will look like this: - -```js -var http = require('http') -var express = require('express') -var routes = require('./routes') -var user = require('./routes/user') -var path = require('path') - -var favicon = require('serve-favicon') -var logger = require('morgan') -var methodOverride = require('method-override') -var session = require('express-session') -var bodyParser = require('body-parser') -var multer = require('multer') -var errorHandler = require('errorhandler') - -var app = express() - -// all environments -app.set('port', process.env.PORT || 3000) -app.set('views', path.join(__dirname, 'views')) -app.set('view engine', 'pug') -app.use(favicon(path.join(__dirname, '/public/favicon.ico'))) -app.use(logger('dev')) -app.use(methodOverride()) -app.use(session({ - resave: true, - saveUninitialized: true, - secret: 'uwotm8' -})) -app.use(bodyParser.json()) -app.use(bodyParser.urlencoded({ extended: true })) -app.use(multer()) -app.use(express.static(path.join(__dirname, 'public'))) - -app.get('/', routes.index) -app.get('/users', user.list) - -// error handling middleware should be loaded after the loading the routes -if (app.get('env') === 'development') { - app.use(errorHandler()) -} - -var server = http.createServer(app) -server.listen(app.get('port'), function () { - console.log('Express server listening on port ' + app.get('port')) -}) -``` - -
      -Unless you need to work directly with the `http` module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way: - -```js -app.listen(app.get('port'), function () { - console.log('Express server listening on port ' + app.get('port')) -}) -``` -
      - -

      Run the app

      - -The migration process is complete, and the app is now an -Express 4 app. To confirm, start the app by using the following command: - -```sh -$ node . -``` - -Load [http://localhost:3000](http://localhost:3000) - and see the home page being rendered by Express 4. - -

      Upgrading to the Express 4 app generator

      - -The command-line tool to generate an Express app is still - `express`, but to upgrade to the new version, you must uninstall - the Express 3 app generator and then install the new - `express-generator`. - -

      Installing

      - -If you already have the Express 3 app generator installed on your system, -you must uninstall it: - -```sh -$ npm uninstall -g express -``` -Depending on how your file and directory privileges are configured, -you might need to run this command with `sudo`. - -Now install the new generator: - -```sh -$ npm install -g express-generator -``` - -Depending on how your file and directory privileges are configured, -you might need to run this command with `sudo`. - -Now the `express` command on your system is updated to the -Express 4 generator. - -

      Changes to the app generator

      - -Command options and use largely remain the same, with the following exceptions: - -{: .doclist } -* Removed the `--sessions` option. -* Removed the `--jshtml` option. -* Added the `--hogan` option to support [Hogan.js](http://twitter.github.io/hogan.js/). - -

      Example

      - -Execute the following command to create an Express 4 app: - -```sh -$ express app4 -``` - -If you look at the contents of the `app4/app.js` file, you will notice -that all the middleware functions (except `express.static`) that are required for -the app are loaded as independent modules, and the `router` middleware -is no longer explicitly loaded in the app. - -You will also notice that the `app.js` file is now a Node.js module, in contrast to the standalone app that was generated by the old generator. - -After installing the dependencies, start the app by using the following command: - -```sh -$ npm start -``` - -If you look at the npm start script in the `package.json` file, -you will notice that the actual command that starts the app is -`node ./bin/www`, which used to be `node app.js` -in Express 3. - -Because the `app.js` file that was generated by the Express 4 generator -is now a Node.js module, it can no longer be started independently as an app -(unless you modify the code). The module must be loaded in a Node.js file -and started via the Node.js file. The Node.js file is `./bin/www` -in this case. - -Neither the `bin` directory nor the extensionless `www` -file is mandatory for creating an Express app or starting the app. They are -just suggestions made by the generator, so feel free to modify them to suit your -needs. - -To get rid of the `www` directory and keep things the "Express 3 way", -delete the line that says `module.exports = app;` at the end of the -`app.js` file, then paste the following code in its place: - -```js -app.set('port', process.env.PORT || 3000) - -var server = app.listen(app.get('port'), function () { - debug('Express server listening on port ' + server.address().port) -}) -``` - -Ensure that you load the `debug` module at the top of the `app.js` file by using the following code: - -```js -var debug = require('debug')('app4') -``` - -Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`. - -You have now moved the functionality of `./bin/www` back to -`app.js`. This change is not recommended, but the exercise helps you -to understand how the `./bin/www` file works, and why the `app.js` file -no longer starts on its own. -
      diff --git a/tr/guide/migrating-5.md b/tr/guide/migrating-5.md deleted file mode 100644 index 2668fd36c9..0000000000 --- a/tr/guide/migrating-5.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -layout: page -title: Migrating to Express 5 -menu: guide -lang: tr ---- -
      -# Moving to Express 5 - -

      Overview

      - -Express 5.0 is still in the alpha release stage, but here is a preview of the changes that will be in the release and how to migrate your Express 4 app to Express 5. - -Express 5 is not very different from Express 4: The changes to the API are not as significant as from 3.0 to 4.0. Although the basic API remains the same, there are still breaking changes; in other words an existing Express 4 program might not work if you update it to use Express 5. - -To install the latest alpha and to preview Express 5, enter the following command in your application root directory: - -```sh -$ npm install express@5.0.0-alpha.2 --save -``` - -You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported. - -

      Changes in Express 5

      - -Here is the list of changes (as of the alpha 2 release ) that will affect you as a user of Express. -See the [pull request](https://github.com/expressjs/express/pull/2237) for a list of all the planned features. - -**Removed methods and properties** - - - -**Changed** - - - -**Improvements** - - - -

      Removed methods and properties

      - -If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5. - -

      app.del()

      - -Express 5 no longer supports the `app.del()` function. If you use this function an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. - -Initially `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. - -

      app.param(fn)

      - -The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. - -

      Pluralized method names

      - -The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: - -`req.acceptsCharset()` is replaced by `req.acceptsCharsets()`. - -`req.acceptsEncoding()` is replaced by `req.acceptsEncodings()`. - -`req.acceptsLanguage()` is replaced by `req.acceptsLanguages()`. - -

      Leading colon (:) in the name for app.param(name, fn)

      - -A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon. - -This should not affect your code if you follow the Express 4 documentation of [app.param](/{{ page.lang }}/4x/api.html#app.param), as it makes no mention of the leading colon. - -

      req.param(name)

      - -This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object. - -

      res.json(obj, status)

      - -Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`. - -

      res.jsonp(obj, status)

      - -Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`. - -

      res.send(body, status)

      - -Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. - -

      res.send(status)

      - -Express 5 no longer supports the signature res.send(status), where _`status`_ is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. -If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature. - -

      res.sendfile()

      - -The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5. - -

      Changed

      - -

      app.router

      - -The `app.router` object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. - -

      req.host

      - -In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5 the port number is maintained. - -

      req.query

      - -In Express 4.7 and Express 5 onwards, the query parser option can accept `false` to disable query string parsing when you want to use your own function for query string parsing logic. - -

      Improvements

      - -

      res.render()

      - -This method now enforces asynchronous behavior for all view engines, avoiding bugs caused by view engines that had a synchronous implementation and that violated the recommended interface. -
      diff --git a/tr/guide/overriding-express-api.md b/tr/guide/overriding-express-api.md deleted file mode 100644 index 1ad1c2b18f..0000000000 --- a/tr/guide/overriding-express-api.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -layout: page -title: Express API'yı Ezmek -menu: guide -lang: tr ---- -
      - -# Express API'yı Ezmek - -Express API istek ve yanıt objelerindeki çeşitli özellik ve metotlardan oluşur. Bunlar prototip tarafından miras alınır. Express API'ın iki uzantı noktası vardır: - -1. `express.request` ve `express.response` alanlarındaki global prototipler. -2. `app.request` ve `app.response` alanlarındaki uygulamaya özel prototipler. - -Global prototipleri değiştirmek aynı işlemde yüklenilen bütün Express uygulamalarını etkiler. İstenirse, yeni bir uygulama yaratıldıktan sonra sadece uygulamaya özel prototipleri değiştirerek, uygulama bazlı değişiklikler yapılabilir. - -## Metotlar - -Mevcut metotların davranış ve imzasını özel bir fonksiyon atayarak kendi metotlarınızla mevcutları geçersiz kılabilirsiniz. - -Aşağıdaki örnek [res.sendStatus](/4x/api.html#res.sendStatus) metodunun davranışını geçersiz kılmayı gösterir: - -```js -app.response.sendStatus = function (statusCode, type, message) { - // kolaylık için kod kasıtlı olarak basit yapıldı - return this.contentType(type) - .status(statusCode) - .send(message) -} -``` - -Yukarıdaki implementasyon `res.sendStatus` metodunun orijinal imzasını tamamen değiştiriyor. Şimdi ise bir statü kodu, kodlama tipi, ve istemciye gönderilecek mesajı kabul ediyor. - -Geçersiz kılınan metot şimdi bu şekilde kullanılabilir: - -```js -res.sendStatus(404, 'application/json', '{"error":"resource not found"}') -``` - -## Özellikler - -Express API özellikleri şunlardan biridir: - -1. Atanan özellikler (örnek: `req.baseUrl`, `req.originalUrl`) -2. Alıcı (getter) olarak tanımlananlar (örnek: `req.secure`, `req.ip`) - -1 numaralı kategorideki özellikler şimdiki istek-yanıt döngüsü kapsamında `request` ve `response` objelerine dinamik olarak atandıklarından, değiştirilemez ve davranışları geçersiz kılınamaz. - -2 numaralı kategoridekiler ise Express API'ın uzantılarının API'ları kullanılarak değiştirilip geçersiz kılınabilir. - -Aşağıdaki kod `req.ip` alanının değerinin nasıl türetileceğini yeniden yazar. Şimdi, sadece `Client-IP` istek başlığının değerini döndürüyor. - -```js -Object.defineProperty(app.request, 'ip', { - configurable: true, - enumerable: true, - get: function () { return this.get('Client-IP') } -}) -``` -
      diff --git a/tr/guide/routing.md b/tr/guide/routing.md deleted file mode 100644 index 1ac06d53e1..0000000000 --- a/tr/guide/routing.md +++ /dev/null @@ -1,355 +0,0 @@ ---- -layout: page -title: Express yönlendirmesi -menu: guide -lang: tr ---- -
      -# Yönlendirme - -_Routing_ uygulama bitiş noktalarının tanımını (URI'ler) ve istemci isteklerine nasıl yanıt verdiklerini ifade eder. -Yönlendirme'ye giriş için, [Temel yönlendirme] sayfasına bakınız.(/{{ page.lang }}/starter/basic-routing.html). - -HTTP metod isimlerine karşılık gelen Express `app` objesinin metodlarını kullanarak yönlendirmeleri tanımlayabilirsiniz; örneğin, GET isteklerini işlemek için `app.get()` ve POST isteklerini işlemek için de `app.post()` kullanmak gibi. Tam liste için bakınız [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). Bütün HTTP metodlarını işlemek için [app.all()](/{{ page.lang }}/4x/api.html#app.all), ve geri çağırma fonksiyonu olarak da ara yazılım tanımlamak için [app.use()](/{{ page.lang }}/4x/api.html#app.use) kullanabilirsiniz (Daha fazla detay için bakınız [Ara yazılım kullanmak](/{{ page.lang }}/guide/using-middleware.html)). - -Bu yönlendirme metodları, uygulamanın belirtilen bir rotaya (bitiş noktası) ve HTTP metoduna aldığı isteklerde çağrılan bir geri çağırma fonksiyonu belirtirler (bazen "işleyici fonksiyonlar" olarak isimlendirilirler). Başka bir deyişle, uygulama, belirtilen rota(lar) ve metod(lar) ile eşleşen istekleri "dinler", ve bir eşleşme algıladığında, ilgili geri çağırma fonksiyonunu çağırır. - -Aslında yönlendirme metodları birden fazla geri çağırma fonksiyonunu argüman olarak alabilir. Birden fazla geri çağırma fonksiyonu olduğunda, bir sonraki fonksiyona kontrolü vermek için geri çağırma fonksiyonuna `next`' argümanını verip, geri çağırma fonksiyonunun içinde `next()` metodunu çağırmak önemlidir. - -Aşağıdaki kod çok temel bir rota örneğidir. - -```js -var express = require('express') -var app = express() - -// anasayfaya bir GET isteği yapıldığında "merhaba dünya" ile yanıt verir -app.get('/', function (req, res) { - res.send('merhaba dünya') -}) -``` - -

      Rota metodları

      - -Bir rota metodu, HTTP metodlarının birinden türetilir ve `express` sınıfının bir örneğine eklenir. - -Aşağıdaki kod uygulamanın köküne GET ve POST metodları için tanımlanan rotalara bir örnektir. - -```js -// GET metodu rotası -app.get('/', function (req, res) { - res.send('anasayfaya GET isteği') -}) - -// POST metodu rotası -app.post('/', function (req, res) { - res.send('anasayfaya POST isteği') -}) -``` - -Express, HTTP metodlarına karşılık gelen bu yönlendirme metodlarını destekler: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search`, ve `connect`. - -
      -Geçersiz JavaScript değişken adlarına denk gelen metodları yönlendirmek için köşeli parantez notasyonunu kullanınız. Örneğin, -`app['m-search']('/', function ...` -
      - -Hiçbir HTTP metodundan türemeyen özel bir yönlendirme metodu olan `app.all()` mevcut. bu metod, tüm istek metodları için bir yolda ara katman yazılım(middleware) fonksiyonlarını yüklemek için kullanılır. - -Bir sonraki örnekte, "/secret" rotasına yapılan isteklerde, GET, POST, PUT, DELETE veya [http modülü](https://nodejs.org/api/http.html#http_http_methods)'nde desteklenen herhangi bir HTTP istek metodu farketmeksizin bu işleyici çalıştırılacak. - -```js -app.all('/secret', function (req, res, next) { - console.log('Gizli bölümlere erişiliyor...') - next() // bir sonraki işleyiciye kontrolü verir -}) -``` - -

      Rota yolları

      - -Rota yolları, bir istek metoduyla birlikte, isteklerin yapılabileceği bitiş noktalarını tanımlar. Rota yolları karakter dizini, karakter dizin modeli veya düzenli ifadeler(reqular expression) olabilir. - -`?`, `+`, `*`, ve `()` karakterleri düzenli ifade karşılıklarının alt kümeleridir. Tire (`-`) ve nokta (`.`) karakter-dizisi tabanlı yollar tarafından oldukları gibi değerlendirilir. - -Eğer dolar karakterini (`$`) bir karakter dizini yolunda kullanma ihtiyacınız olursa, `([` ve `])` karakterlerinin içinde kullanınız. Örneğin, "`/data/$book`" istekleri için dizin yolu bu şekilde olur: "`/data/([\$])book`". - -
      - Express, rota yollarını eşleştirmek için [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) kullanır; rota tanımlamadaki bütün olasılıkları öğrenmek için path-to-regexp dökümantasyonuna bakınız. Basit Express rotalarını test etmek için [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) kullanışlı bir araçtır, ancak bu araç model eşleştirmeyi desteklememektedir. -
      - -
      -Sorgu dizeleri rota yolunun bir parçası değillerdir. -
      - -Karakter dizininlerine dayalı bazı rota yolları örnekleri. - -Bu rota yolu, istekleri kök rotaya eşleştirecek, `/`. - -```js -app.get('/', function (req, res) { - res.send('root') -}) -``` - -Bu rota yolu istekleri `/about` ile eşleştirecek - -```js -app.get('/about', function (req, res) { - res.send('about') -}) -``` - -Bu rota yolu istekleri `/random.text` ile eşleştirecek - -```js -app.get('/random.text', function (req, res) { - res.send('random.text') -}) -``` - -Aşağıda, dizin modellerine dayalı rota yollarının bazı örnekleri verilmiştir. - -Bu rota yolu, `acd` ve `abcd` ile eşleşecek. - -```js -app.get('/ab?cd', function (req, res) { - res.send('ab?cd') -}) -``` - -Bu rota yolu, `abcd`, `abbcd`, `abbbcd` vb. ile eşleşecek. - -```js -app.get('/ab+cd', function (req, res) { - res.send('ab+cd') -}) -``` - -Bu rota yolu, `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd` vb. ile eşleşecek. - -```js -app.get('/ab*cd', function (req, res) { - res.send('ab*cd') -}) -``` - -Bu rota yolu, `/abe` ve `/abcde` ile eşleşecek. - -```js -app.get('/ab(cd)?e', function (req, res) { - res.send('ab(cd)?e') -}) -``` - -Düzenli ifadelere dayalı rota yolları örnekleri: - -Bu rota yolu, rota isminde "a" karakteri olan herhangi bir şey ile eşleşecek. - -```js -app.get(/a/, function (req, res) { - res.send('/a/') -}) -``` - -Bu rota yolu `butterfly` ve `dragonfly` ile eşleşir, ancak `butterflyman`, `dragonflyman` vb. ile değil. - -```js -app.get(/.*fly$/, function (req, res) { - res.send('/.*fly$/') -}) -``` - -

      Rota parametreleri

      - -Rota parametreleri, URL'deki konumlarında belirtilen değerleri yakalamak için kullanılan adlandırılmış URL bölümleridir. Yakalanan değerler, yolda belirtilen rota parameterlerinin ilgili isimlerini alarak `req.params` objesinde tutulur. - -``` -Rota yolu: /users/:userId/books/:bookId -İStek URL'i: http://localhost:3000/users/34/books/8989 -req.params: { "userId": "34", "bookId": "8989" } -``` - -Parametreli rota tanımlamak için, aşağıda gösterildiği gibi rota parametrelerini rotanın yolunda belirtmeniz yeterlidir. - -```js -app.get('/users/:userId/books/:bookId', function (req, res) { - res.send(req.params) -}) -``` - -
      -Rota parametrelerinin isimleri sadece "kelime karakterleri" içermelidir ([A-Za-z0-9_]). -
      - -Tire (`-`) ve nokta (`.`) oldukları gibi değerlendirildikleri için, kullanışlı amaçlar için rota parametrelerinde kullanılabilirler. - -``` -Rota yolu: /flights/:from-:to -İtek URL'i: http://localhost:3000/flights/LAX-SFO -req.params: { "from": "LAX", "to": "SFO" } -``` - -``` -Rota yolu: /plantae/:genus.:species -İstek URL'i: http://localhost:3000/plantae/Prunus.persica -req.params: { "genus": "Prunus", "species": "persica" } -``` - -Bir rota parametresiyle eşleşen dizin üzerinde daha fazla kontrole sahip olmak için, parantez içinde (`()`) düzenli ifade ekleyebilirsiniz: - -``` -Rota yolu: /user/:userId(\d+) -İstek URL'i: http://localhost:3000/user/42 -req.params: {"userId": "42"} -``` - -
      -Düzenli ifadeler genellikle tam bir dizenin parçaları oldukları için, \ karakterlerinden ek olarak ters eğik çizgi ile kaçtığınızdan emin olun, örneğin \\d+. -
      - -
      -Express 4.x'te, düzenli ifadelerdeki * karakteri normal durumlardaki gibi değerlendirilmiyor. Geçici çözüm olarak, * karakteri yerine{0,} karakterini kullanınız. Bu muhtemelen Express 5'te düzeltilecektir. -
      - -

      Rota işleyicileri

      - -Bir isteği işlemek için, [ara-katman](/{{ page.lang }}/guide/using-middleware.html) gibi davranan birden fazla geri çağırma fonksiyonu sağlayabilirsiniz. Bunun tek istisnası, bu geri çağırmalar, arda kalan rota metodlarını atlatmak için `next('route')` metodunu çağırabilir. Bir rotaya ön koşullar uygulamak için bu mekanizmayı kullanabilirsiniz, ve sonra geçerli rotaya devam etmek için bir neden yoksa kontrolü sonraki rotalara aktarabilirsiniz. - - -Rota işleyicileri, aşağıdaki örneklerde gösterildiği gibi bir fonksiyon, fonksiyonlar dizisi veya her ikisinin birleşimi biçiminde olabilir. - -Bir geri çağırma fonksiyonu, bir rotayı işleyebilir. Örneğin: - -```js -app.get('/example/a', function (req, res) { - res.send('A\'dan merhaba') -}) -``` - -Birden fazla geri çağırma fonksiyonu bir rotayı işleyebilir (`next` objesini belirttiğinizden emin olun). Örneğin: - -```js -app.get('/example/b', function (req, res, next) { - console.log('yanıt bir sonraki fonksiyon tarafından gönderilecek') - next() -}, function (req, res) { - res.send('B\'den merhaba') -}) -``` -Geri çağırma fonksiyonları dizini bir rotayı işleyebilir. Örneğin: - -```js -var cb0 = function (req, res, next) { - console.log('Geri çağırma 0') - next() -} - -var cb1 = function (req, res, next) { - console.log('Geri çağırma 1') - next() -} - -var cb2 = function (req, res) { - res.send('C\'den merhaba') -} - -app.get('/example/c', [cb0, cb1, cb2]) -``` - -Bağımsız fonksiyonlar ve fonksiyon dizilerinin bir kombinasyonu bir rotayı işleyebilir. Örneğin: - -```js -var cb0 = function (req, res, next) { - console.log('Geri çağırma 0') - next() -} - -var cb1 = function (req, res, next) { - console.log('Geri çağırma 1') - next() -} - -app.get('/example/d', [cb0, cb1], function (req, res, next) { - console.log('yanıt bir sonraki fonksiyon tarafından gönderilecek') - next() -}, function (req, res) { - res.send('D\'den merhaba') -}) -``` - -

      Yanıt metodları

      - -Aşağıdaki tabloda yanıt nesnesindeki (`res`) metodlar istemciye yanıt gönderebilir ve istek-yanıt döngüsünü sonlandırabilir. Bu metodlardan hiçbiri bir rota işleyiciden çağrılmazsa, istemci isteği asılı kalır. - -| Metod | Açıklama -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Bir dosyanın indirilmesini iste. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | Yanıt sürecini sonlandır. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | JSON yanıtı gönder. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | JSONP destekli bir JSON yanıtı gönder -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Bir isteği yeniden yönlendir. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Bir görünüm şablonu görüntüle. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Çeşitli tiplerde yanıt gönder. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Dosyayı sekizli akış olarak gönder. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Yanıt durum kodunu ayarla ve karakter dize temsilini yanıt gövdesi olarak gönder. - -

      app.route()

      - -Bir rota yolu için `app.route()` kullanarak zincirlenebilir rota işleyicileri oluşturabilirsiniz. -Yol tek bir konumda belirtildiğinden, fazlalık ve yazım hatalarını azaltmak için modüler rotalar oluşturmak yararlıdır. Rotalar hakkında daha fazla bilgi için, bakınız: [Router() dökümantasyonu](/{{ page.lang }}/4x/api.html#router). - -Burada `app.route()` kullanılarak tanımlanan zincirleme rota işleyicilerine bir örnek verilmiştir. - -```js -app.route('/book') - .get(function (req, res) { - res.send('Rastgele bir kitap getir') - }) - .post(function (req, res) { - res.send('Bir kitap ekle') - }) - .put(function (req, res) { - res.send('Kitabı güncelle') - }) -``` - -

      express.Router

      - -Modüler, monte edilebilir rota işleyicileri oluşturmak için `express.Router` sınıfını kullanın. Bir `Router` sınıfı örneği tam bir ara katman yazılım ve yönlendirme sistemidir; bu nedenle, sıklıkla "mini-uygulama" olarak bilinir. - -Aşağıdaki örnek, bir yönlendiriciyi modül olarak oluşturur, içine bir ara katman yazılımı fonksiyonu yükler, bazı rotaları tanımlar ve yönlendirici modülünü ana uygulamadaki bir yola bağlar. - -Uygulama dizininde aşağıdaki içeriğe sahip `birds.js` adlı bir yönlendirici dosyası oluşturun: - -```js -var express = require('express') -var router = express.Router() - -// bu yönlendiriciye özel ara katman yazılım -router.use(function timeLog (req, res, next) { - console.log('Time: ', Date.now()) - next() -}) -// anasayfa rotası tanımla -router.get('/', function (req, res) { - res.send('Birds home page') -}) -// define the about route -router.get('/about', function (req, res) { - res.send('About birds') -}) - -module.exports = router -``` - -Daha sonra, yönlendirici modülünü uygulamada yükle: - -```js -var birds = require('./birds') - -// ... - -app.use('/birds', birds) -``` - -Uygulama artık `/birds` ve `/birds/about` isteklerini işleyebileceği gibi, rotaya özgü `timeLog` ara katman yazılımı fonksiyonunu da çağırabilecektir. -
      diff --git a/tr/guide/using-middleware.md b/tr/guide/using-middleware.md deleted file mode 100644 index 1763878f7b..0000000000 --- a/tr/guide/using-middleware.md +++ /dev/null @@ -1,280 +0,0 @@ ---- -layout: page -title: Express ara yazılımı kullanmak -menu: guide -lang: tr ---- -
      -# Ara yazılım kullanmak - -Express, kendine özgü minimal bir işlevselliği olan bir yönlendirme ve ara yazılım web çatısıdır: Bir Express uygulaması aslında bir dizi ara yazılım fonksiyon çağrısıdır. - -_Middleware_ fonksiyonları, uygulamanın istek-yanıt döngüsündeki [istek objesi](/{{ page.lang }}/4x/api.html#req) (`req`), [yanıt objesi](/{{ page.lang }}/4x/api.html#res) (`res`), ve bir sonraki ara yazılım fonksiyonuna erişebilen fonksiyonlardır. Bir sonraki ara yazılım fonksiyonu çoğunlukla `next` isimli bir değişken ile tanımlanır. - -Ara yazılım fonksiyonları aşağıdaki görevleri yapabilir: - -* Herhangi bir kodu koşma -* İstek ve yanıt objelerine değişiklik yapma -* İstek-yanıt döngüsünü bitirme -* Kümedeki bir sonraki ara yazılım fonksiyonunu çağırma - -Şimdiki ara yazılım fonksiyonu istek-yanıt döngüsünü bitirmezse, bir sonraki ara yazılım fonksiyonuna kontrol vermek için `next()` metodunu çağırmalı. Aksi takdirde istek boşta asılı kalacaktır. - -Bir Express uygulaması aşağıdaki ara yazılım türlerini kullanabilir: - - - [Uygulama-düzeyi ara yazılım](#middleware.application) - - [Rota-düzeyi ara yazılım](#middleware.router) - - [Hata-işleme ara yazılım](#middleware.error-handling) - - [Gömülü ara yazılım](#middleware.built-in) - - [Üçüncü-parti ara yazılım](#middleware.third-party) - - -Uygulama-düzeyi ve yönlendirici-düzeyi ara yazılımı bir opsiyonlu hedef yol ile yükleyebilirsiniz. -Hedef bir yolda, bir ara katman yazılımı alt kümesi oluşturacak bir ara yazılım fonksiyonlar dizisi de yükleyebilirsiniz. - -

      Uygulama-düzeyi ara yazılımı

      - -Uygulama-düzeyi ara yazılımı `app.use()` ve `app.METHOD()` fonksiyonları kullanarak bir [uygulama objesi](/{{ page.lang }}/4x/api.html#app) örneğine bağlanır; `METHOD` ise, küçük harflerle, ara yazılım fonksiyonunun işlediği isteğin HTTP metodunun ismidir (örneğin GET, PUT, veya POST). - -Bu örnek, hedef yolu bulunmayan bir ara yazılım fonksiyonunu gösteriyor. Fonksiyon uygulama her istek aldığında çalışır. - -```js -var app = express() - -app.use(function (req, res, next) { - console.log('Time:', Date.now()) - next() -}) -``` - -Bu örnek, `/user/:id` yoluna yerleştirilmiş bir ara yazılım fonksiyonu gösterir. Bu fonksiyon `/user/:id` yoluna yapılan herhangi bir HTTP isteğinde çalışır. - -```js -app.use('/user/:id', function (req, res, next) { - console.log('Request Type:', req.method) - next() -}) -``` - -Bu örnek bir rotayı ve işleyici fonksiyonunu gösterir (ara yazılım sistemi). Fonksiyon `/user/:id` yoluna yapılan GET isteklerini karşılıyor. - -```js -app.get('/user/:id', function (req, res, next) { - res.send('USER') -}) -``` - -Bu örnek, hedef bir yol ile, yerleştirilmiş bir noktada bir dizi ara yazılım fonksiyonları yükler. -`/user/:id` yoluna yapılan herhangi bir tipte HTTP isteğinin istek bilgilerini yazdıran bir ara yazılım alt kümesini gösterir. - -```js -app.use('/user/:id', function (req, res, next) { - console.log('Request URL:', req.originalUrl) - next() -}, function (req, res, next) { - console.log('Request Type:', req.method) - next() -}) -``` - -Rota işleyicileri bir yol için birden fazla rota tanımlamaya olanak sağlar. Aşağıdaki örnek `/user/:id` yoluna yapılan GET istekleri için iki rota tanımlıyor. İkinci rota herhangi bir problem yaratmayacak, ancak ilk rota istek-yanıt döngüsünü bitirdiği için ikinci rota hiç bir zaman çağrılmayacak. - -Bu örnek `/user/:id` yoluna yapılan GET isteklerini işleyen ara yazılım alt kümesini gösterir. - -```js -app.get('/user/:id', function (req, res, next) { - console.log('ID:', req.params.id) - next() -}, function (req, res, next) { - res.send('User Info') -}) - -// kullanıcı ID'sini yazdıran, /user/:id yolunun işleyicisi -app.get('/user/:id', function (req, res, next) { - res.end(req.params.id) -}) -``` - -Geriye kalan ara yazılım fonksiyonlarını yönlendirici ara yazılım kümesinden es geçmek için, `next('route')` metodunu çağırarak bir sonraki rotaya kontrolu verin. -**NOT**: `next('route')` metodu sadece `app.METHOD()` veya `router.METHOD()` fonksiyonlarını kullanarak yüklenen ara yazılım fonksiyonları için geçerlidir. - -Bu örnek `/user/:id` yolu için yapılan GET isteklerini işleyen bir ara yazılım alt-kümesini gösterir. - -```js -app.get('/user/:id', function (req, res, next) { - // kullanıcı ID'si 0 ise, bir sonraki rotaya geç - if (req.params.id === '0') next('route') - // aksi takdirde kontrolü bu kümedeki bir sonraki ara yazılım fonksiyonuna ver - else next() -}, function (req, res, next) { - // normal bir sayfa göster - res.render('regular') -}) - -// özel bir sayfa gösteren, /user/:id yolunun işleyicisi -app.get('/user/:id', function (req, res, next) { - res.render('special') -}) -``` - -

      Yönlendirici-düzeyi ara yazılım

      - -Yönlendirici-düzeyi ara yazılımı, uygulama-düzeyi ara yazılımı ile aynı şekilde çalışır; ama `express.Router()` sınıfının bir örneğine bağlıdır. - -```js -var router = express.Router() -``` -`router.use()` ve `router.METHOD()` fonksiyonlarını kullanarak yönlendirici-düzeyi ara yazılımı yükle. - -Aşağıdaki örnek kod, yukarıda uygulama-düzeyi ara yazılım için gösterilen ara yazılım sistemini, yönlendirici-düzeyi ara yazılım kullanarak kopyalar: - -```js -var app = express() -var router = express.Router() - -// hedef yolu olmayan bir ara yazılım fonksiyonu. Bu kod yönlendiriciye yapılan her istekte çalışır -router.use(function (req, res, next) { - console.log('Time:', Date.now()) - next() -}) - -// /user/:id yolu için yapılan herhangi bir HTTP tipi isteğinin istek bilgilerini gösteren bir ara yazılım alt-kümesi -router.use('/user/:id', function (req, res, next) { - console.log('Request URL:', req.originalUrl) - next() -}, function (req, res, next) { - console.log('Request Type:', req.method) - next() -}) - -// /user/:id yoluna yapılan GET isteklerini işleyen bir ara yazılım alt-kümesi -router.get('/user/:id', function (req, res, next) { - // kullanıcı ID'si 0 ise, bir sonraki yönlendiriciye geç - if (req.params.id === '0') next('route') - // aksi takdirde kontrolü bu kümedeki bir sonraki ara yazılıma ver - else next() -}, function (req, res, next) { - // normal bir sayfa göster - res.render('regular') -}) - -// özel bir sayfa gösteren /user/:id yolu işleyicisi -router.get('/user/:id', function (req, res, next) { - console.log(req.params.id) - res.render('special') -}) - -// yönlendiriciyi uygulamaya yerleştir -app.use('/', router) -``` - -Yönlendiricinin kalan ara yazılım fonksiyonlarını geçmek için, yönlendirici örneğinden kontrolü almak için `next('router')` metodunu çağırın. - -Bu örnek, `/user/:id` yoluna yapılan GET isteklerini işleyen bir ara yazılım alt-kümesini gösterir. - -```js -var app = express() -var router = express.Router() - -// yönlendiriciyi bir kontrol ile doğrula ve gerektiğinde bir sonraki yönlendiriciye geçerek kurtul -router.use(function (req, res, next) { - if (!req.headers['x-auth']) return next('router') - next() -}) - -router.get('/', function (req, res) { - res.send('hello, user!') -}) - -// geçen herhangi bir şey için yönlendiriciyı ve 401'i kullan -app.use('/admin', router, function (req, res) { - res.sendStatus(401) -}) -``` - -

      Hata-işleyici ara yazılım

      - -
      -Hata-işleyici ara yazılımı her zaman _dört_ argüman alır. Bir hata-işleyici ara yazılım fonksiyonunu tanımlayabilmek için dört argüman sağlamalısınız. `next` objesini kullanmaya ihtiyacınız yoksa bile, metod imzasını koruyabilmek için tanımlamalısınız. Aksi takdirde, `next` objesi normal bir ara yazılım gibi değerlendirilecek ve hataları işlemede başarısız olacaktır. -
      - -Hata-işleme ara yazılım fonksiyonlarını diğer ara yazılım fonksiyonları gibi tanımla, ancak istisna olarak üç argüman yerine 4 ile, özellikle `(err, req, res, next)` imzasıyla: - - -```js -app.use(function (err, req, res, next) { - console.error(err.stack) - res.status(500).send('Bir şeyler bozuk!') -}) -``` - -Hata-işleyici ara yazılım hakkında daha fazla detay için bakınız [Hata-işleme](/{{ page.lang }}/guide/error-handling.html). - -

      Gömülü ara yazılım

      - -4.x sürümünden başlayarak, Express [Connect](https://github.com/senchalabs/connect) ara yazılımına bağımlı değil. -`express.static` hariç, Express ile daha önce dahil edilen tüm ara katman yazılımı fonksiyonları artık ayrı modüllerde. Lütfen bakınız [ara yazılım fonksiyonları listesi](https://github.com/senchalabs/connect#middleware). - -Express'teki tek gömülü ara yazılım fonksiyonu `express.static` fonksiyonudur. Bu fonksiyon [serve-static](https://github.com/expressjs/serve-static)'e dayanır, ve HTML dosyaları, görüntüler vb. gibi statik dosyaları sunmaktan sorumludur. - -Fonksiyon imzası böyledir: - -```js -express.static(root, [options]) -``` - -`root` argümanı statik dosyaların sunulacağı kök dizini belirtir. - -`options` argümanı ve bu ara yazılım fonksiyonu hakkında daha detaylı bilgi için, bakınız [express.static](/en/4x/api.html#express.static). - -Bu örnek `express.static` ara yazılım fonksiyonunu ayrıntılı bir seçenekler objesiyle kullanımını gösterir: - -```js -var options = { - dotfiles: 'ignore', - etag: false, - extensions: ['htm', 'html'], - index: false, - maxAge: '1d', - redirect: false, - setHeaders: function (res, path, stat) { - res.set('x-timestamp', Date.now()) - } -} - -app.use(express.static('public', options)) -``` - -Her bir uygulama için birden fazla statik dizine sahip olabilirsiniz: - -```js -app.use(express.static('public')) -app.use(express.static('uploads')) -app.use(express.static('files')) -``` - -`serve-static` fonksiyonu ve seçenekleri hakkında daha detaylı bilgi için, [serve-static](https://github.com/expressjs/serve-static) dökümantasyonuna bakınız. - -

      Üçüncü-parti ara yazılım

      - -Express uygulamalarına işlevsellik katmak için üçüncü-parti ara yazılım kullan. - -Gerekli işlevsellik için Node.js modülünü indir, ve daha sonra uygulamana uygulama-düzeyinde veya yönlendirici-düzeyinde yükle. - -Aşağıdaki örnek `cookie-parser` çerez-ayrıştırma ara yazılım fonksiyonunu indirme ve yüklemeyi gösterir. - -```sh -$ npm install cookie-parser -``` - -```js -var express = require('express') -var app = express() -var cookieParser = require('cookie-parser') - -// çerez-ayrıştırıcı ara yazılımı yükle -app.use(cookieParser()) -``` - -Express ile yaygın olarak kullanılan üçüncü-parti ara yazılım fonksiyonlarının kısmi bir listesi için, bakınız: [Üçüncü-parti ara yazılım](../resources/middleware.html). -
      diff --git a/tr/guide/using-template-engines.md b/tr/guide/using-template-engines.md deleted file mode 100644 index 5f73176856..0000000000 --- a/tr/guide/using-template-engines.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -layout: page -title: Express ile şablon motorları kullanmak -menu: guide -lang: tr -redirect_from: "/guide/using-template-engines.html" ---- -# Express ile şablon motorları kullanmak - -_Şablon motoru_, uygulamanızda statik şablon dosyaları kullanmanızı sağlar. Çalışma zamanında, şablon motoru bir şablon dosyasındaki değişkenleri alıp gerçek değerleyler değiştirir, ve şablonu bir HTML dosyasına dönüştürüp istemciye gönderir. Bu yaklaşım bir HTML sayfasını tasarlamayı kolaylaştırır. - -Express ile çalışan bazı popüler şablon motorları: [Pug](https://pugjs.org/api/getting-started.html), [Mustache](https://www.npmjs.com/package/mustache), ve [EJS](https://www.npmjs.com/package/ejs). [Express uygulama üreteci (generator)](/{{ page.lang }}/starter/generator.html) varsayılan olarak [Jade](https://www.npmjs.com/package/jade) kullanıyor, ancak aynı zamanda diğerlerini de destekler. - -Express ile kullanabileceğiniz şablon motorları listesi için bakınız [Şablon Motorları (Express wiki)](https://github.com/expressjs/express/wiki#template-engines). -Ayrıca bakınız: [JavaScript Şablonlama Motorlarını Karşılaştırma:: Jade, Mustache, Dust ve Daha fazla](https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/). - -
      -**Not**: Jade, [Pug](https://www.npmjs.com/package/pug) olarak değiştirildi. Uygulamanızda Jade kullanmaya devam edebilirsiniz, ve problem olmadan çalışacaktır. Ancak şablon motorunun en son güncellemelerini almak istiyorsanız, uygulamanızda Jade'i Pug ile değiştirmelisiniz. -
      - -Şablon dosyalarını işlemek için, aşağıdaki [uygulama ayarları özelliklerini](/{{ page.lang }}/4x/api.html#app.set) ayarlayın, üretici (generator) tarafından yaratılan varsayılan uygulamada `app.js` dosyasında ayarlayın: - -* `views`, şablon dosyalarının bulunduğu dizindir. Örnek: `app.set('views', './views')`. -Bu varsayılan olarak uygulamanın kök dizindeki `views` dizinine denk gelir. - -* `view engine`, kullanılacak şablon motorudur. Örnek olarak, Pug şablon motorunu kullanmak için: `app.set('view engine', 'pug')`. - -Daha sonra ise, ilgili şablon motorunun npm paketini yükleyin; örneğin Pug yüklemek için: - -```sh -$ npm install pug --save -``` - -
      -Jade ve Pug gibi Express-uyumlu şablon motorları, şablon kodunu işlemek için `res.render()` tarafından çağrılan `__express(filePath, options, callback)` isimli bir fonksiyon dışa aktarır. - -Bazı şablon motorları bu anlayışı takip etmez. [Consolidate.js](https://www.npmjs.org/package/consolidate) kütüphanesi bu anlayışı bütün popüler Node.js şablon motorlarını eşleyerek (mapping) takip eder, ve dolayısıyla Express içinde sorunsuz çalışır. -
      - -Görünüm motoru ayarlandıktan sonra, uygulamanızda motoru tanımlamanıza veya şablon motoru modülünü yüklemenize gerek yok; Aşağıda gösterildiği gibi (yukarıdaki örnek için) Express, modülü kendi içinde yükler. - -```js -app.set('view engine', 'pug') -``` - -Aşağıdaki içerikle, `views` dizininde `index.pug` adlı bir Pug şablon dosyası yarat: - -```pug -html - head - title= title - body - h1= message -``` - -Ardından, `index.pug` dosyasını işlemek için bir rota yaratın. `view engine` özelliği ayarlanmadıysa, `view` dosyasının uzantısını belirtmelisiniz. Aksi takdirde belirtmenize gerek yok. - -```js -app.get('/', function (req, res) { - res.render('index', { title: 'Hey', message: 'Hello there!' }) -}) -``` - -Ana sayfaya bir istek yaptığınızda, `index.pug` dosyası HTML olarak gösterilecek. - -Not: Görünüm motoru önbelleği şablonun çıktısını önbelleğine almaz, sadece şablonun temelini alır. Önbellek açık olsa bile, görünüm her istekle beraber yeniden işlenir. - -Şablon motorlarının Express'te nasıl çalıştıkları ile ilgili daha fazla bilgi için bakınız: ["Express için şablon motorları geliştirme"](/{{ page.lang }}/advanced/developing-template-engines.html). diff --git a/tr/guide/writing-middleware.md b/tr/guide/writing-middleware.md deleted file mode 100644 index c949a82a75..0000000000 --- a/tr/guide/writing-middleware.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -layout: page -title: Express uygulamalarında kullanılacak ara yazılım yazmak -menu: guide -lang: tr -redirect_from: "/guide/writing-middleware.html" ---- -# Express uygulamalarında kullanılacak ara yazılım yazmak - -

      Genel bakış

      - -_Ara yazılım_ fonksiyonları uygulamanın istek-yanıt döngüsünde (`req`) [istek objesi](/{{ page.lang }}/4x/api.html#req), (`res`) [yanıt objesi](/{{ page.lang }}/4x/api.html#res), ve `next` metoduna sahip fonksiyonlardır. Express yönlendiricisinde bir fonksiyon olan `next`çağrıldığında şimdiki ara yazılımın ardından gelen ara yazılımı çalıştırır. - -Ara yazılım fonksiyonları aşağıdaki görevleri yerine getirebilir: - -* Herhangi bir kodu çalıştırma. -* İstek ve yanıt objelerine değişiklik yapma. -* İstek-yanıt döngüsünü sonlandırma. -* Yığındaki bir sonraki ara yazılımı çağırma. - -Eğer şimdiki ara yazılım fonksiyonu istek-yanıt döngüsünü sonlandırmazsa, bir sonraki ara yazılım fonksiyonuna kontrolü vermek için `next` fonksiyounu çağrılmalı. Aksi takdirde, istek havada kalır. - -Aşağıdaki şekil bir ara yazılım fonksiyon çağrısının öğelerini gösterir: - - - - -
      - - -
      Ara yazılım fonsiyonunu uyglandığı HTTP metodu.
      - -
      Ara yazılım fonksiyonunun uygulandığı yol (rota).
      - -
      Ara yazılım fonksiyonu.
      - -
      Ara yazılım için geri çağırma argümanı, ortak anlayışa göre "next" olarak adlandırıldı.
      - -
      Ara yazılım fonksiyonuna HTTP yanıtı argümanı, ortak anlayışa göre "res" olarak adlandırıldı.
      - -
      Ara yazılım fonksiyonuna HTTP isteği argümanı, ortak anlayışa göre "req" olarak adlandırıldı.
      -
      - -Express 5 ile başlayarak, Promise döndüren ara yazılım fonksiyonları reddettiklerinde veya hata fırlattıklarında `next(value)` fonksiyonunu çağırırlar. `next`, fırlatılan hata veya ret edilen değer ile çağrılacak. - -

      Örnek

      - -Aşağıdaki basit bir "Merhaba Dünya" Ekspres uygulaması örneği. Bu yazının kalanında uygulamaya üç ara yazılım fonksiyonu tanımlanıp eklenecektir: basit bir log mesajı yazdıran `myLogger`, HTTP isteğinin zaman damgasını (timestamp) gösteren `requestTime`, ve gelen çerezleri doğrulayan `validateCookies`. - -```js -var express = require('express') -var app = express() - -app.get('/', function (req, res) { - res.send('Merhaba Dünya!') -}) - -app.listen(3000) -``` - -

      myLogger ara yazlım fonksiyonu

      -İşte "myLogger" adında basit bir ara yazılım fonksiyonu. Uygulamaya gelen bir istek bu fonksiyondan geçtiğinde sadece "LOGGED" yazdırır. Bu ara yazılım fonksiyonu, `myLogger` adında bir değişkene atanmıştır. - -```js -var myLogger = function (req, res, next) { - console.log('LOGGED') - next() -} -``` - -
      -Yukarıdaki örnekte `next()` çağrısına dikkat edin. Bu fonksiyonu çağırmak, uygulamadaki bir sonraki ara yazılım fonksiyonunu çağırır. `next()` fonskiyonu Express API veya Node.js'in bir parçası değil, ara yazılım fonksiyonuna geçilen üçüncü argümandır. `next()` fonksiyonu herhangi bir şekilde adlandırılabilir, ancak orta anlayışa göre her zaman "next" olarak adlandırıldı. Karışıklıktan kaçınmak için her zaman bu şekilde kullanın. -
      - -Ara yazılım fonksiyonunu yüklemek için, ara yazılım fonksiyonunu belirterek `app.use()` metodunu çağırın. -Örneğin, aşağıdaki kod (/) kök yoluna yönlendirme yapılmadan önce `myLogger` ara yazılım fonksiyonunu yükler. - -```js -var express = require('express') -var app = express() - -var myLogger = function (req, res, next) { - console.log('LOGGED') - next() -} - -app.use(myLogger) - -app.get('/', function (req, res) { - res.send('Hello World!') -}) - -app.listen(3000) -``` - -Uygulama ne zaman bir istek aldığında, "LOGGED" mesajını terminale yazdırır. - -Ara yazılımları yükleme sırası önemlidir: ilk olarak yüklenen ara yazılım fonksiyonları yine ilk olarak çalışacaklardır. - -`myLogger` kök yoluna yönlendirme yapıldıktan sonra yüklenirse, istek hiç ulaşmaz ve uygulama "LOGGED" mesajını yazdırmaz, çünkü kök yolu rota işleyicisi istek-yanıt döngüsünü sonlandırır. - -`myLogger` ara yazılım fonksiyonu basit bir şekilde bir mesaj yazdırır, ve daha sonra `next()` metodunu çağırarak isteği yığındaki bir sonraki ara yazılım fonksiyonuna geçer. - -

      requestTime ara yazılım fonksiyonu

      - -Bir sonraki örnekte, "requestTime" adında bir ara yazılım fonksiyonu yaratıp `requestTime` adında bir özelliği istek objesine ekleyeceğiz. - -```js -var requestTime = function (req, res, next) { - req.requestTime = Date.now() - next() -} -``` - -Uygulama şimdi `requestTime` ara yazılım fonksiyonunu kullanıyor. Ayrıca, kök yol rotasının geri çağırma fonksiyonu, ara yazılımın `req` istek objesine eklediği özelliği kullanıyor. - -```js -var express = require('express') -var app = express() - -var requestTime = function (req, res, next) { - req.requestTime = Date.now() - next() -} - -app.use(requestTime) - -app.get('/', function (req, res) { - var responseText = 'Hello World!
      ' - responseText += 'Requested at: ' + req.requestTime + '' - res.send(responseText) -}) - -app.listen(3000) -``` - -Uygulamanın kök yoluna bir istek yaptığınızda, uygulama şimdi tarayıcıda isteğinizin zaman damgasını yazdırıyor. - -

      validateCookies ara yazılım fonksiyonu

      - -Son olarak, gelen çerezleri doğrulayan ve çerezler geçersiz olduğunda 400 yanıtı gönderen bir ara yazılım fonksiyonu yaratacağız. - -Harici bir asenkron servisiyle çerezleri doğrulayan bir fonksiyonu örneği. - -```js -async function cookieValidator (cookies) { - try { - await externallyValidateCookie(cookies.testCookie) - } catch { - throw new Error('Geçersiz çerezler') - } -} -``` - -Burada `req` objesinden gelen çerezleri ayrıştırmak ve onları bizim `cookieValidator` fonksiyonuna geçmek için [`cookie-parser`](/resources/middleware/cookie-parser.html) ara yazılım fonksiyonunu kullanıyoruz. `validateCookies` ara yazılımı, ret durumunda otomatik olarak bizim hata işleyicisini tetikleyen bir Promise döndürür. - -```js -var express = require('express') -var cookieParser = require('cookie-parser') -var cookieValidator = require('./cookieValidator') - -var app = express() - -async function validateCookies (req, res, next) { - await cookieValidator(req.cookies) - next() -} - -app.use(cookieParser()) - -app.use(validateCookies) - -// hata işleyicisi -app.use(function (err, req, res, next) { - res.status(400).send(err.message) -}) - -app.listen(3000) -``` - -
      -`next()` fonksiyonunun `await cookieValidator(req.cookies)` çağrısından sonra çağrıldığına bakınız. Bu, `cookieValidator` çözümlendiğinde yığındaki bir sonraki ara yazılımının çağrılmasını sağlar. `next()` fonksiyonuna `'route'` veya `'router'` karakter dizinleri dışında herhangi bir şey geçerseniz Express şimdiki isteği bir hata olarak değerlendirip arda kalan hata olmayan yönlendirme ve ara yazılım fonksiyonlarını es geçer. -
      - -İstek objesine, yanıt objesine, yığındaki bir sonraki ara yazılım fonksiyonuna, ve bütün Node.js API'sine erişme imkanına sahip olduğunuzdan, ara yazılım fonksiyonlarının imkanları sınırsızdır. - -Express ara yazılımı ile ilgili daha fazla bilgi için, bakınız: [Express ara yazılımı kullanmak](/{{ page.lang }}/guide/using-middleware.html). - -

      Yapılandırılabilir ara yazılım

      - -Ara yazılımınızın yapılandırılabilir olmasını istiyorsanız, seçenekler objesi veya diğer parametreleri kabul eden ve girdi parametrelerine göre ara yazılım implementasyonunu döndüren bir fonksiyon dışarıya aktarın. - -Dosya: `my-middleware.js` - -```js -module.exports = function (options) { - return function (req, res, next) { - // "options" objesine göre ara yazılım fonksiyonunu yaz - next() - } -} -``` - -Bu ara yazılım şimdi aşağıdaki gibi kullanılabilir. - -```js -var mw = require('./my-middleware.js') - -app.use(mw({ option1: '1', option2: '2' })) -``` - -Yapılandırılabilir ara yazılım örnekleri için bakınız: [cookie-session](https://github.com/expressjs/cookie-session) ve [compression](https://github.com/expressjs/compression). diff --git a/tr/index.md b/tr/index.md deleted file mode 100644 index 4038203677..0000000000 --- a/tr/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -layout: home -title: Express - Node.js Web Uygulama Çatısı -menu: home -lang: tr ---- -
      - {% include header/header-{{ page.lang }}.html %} -
      -
      -
      - - Node.js için hızlı, kolay, sade web çatısı -
      -
      $ npm install express --save
      -
      -
      - -
      -
      - -
      - -
      -
      -

      Web Uygulamaları

      - Express, Web ve Mobil uygulamalar için sağlam özellikler sağlayan sade ve esnek bir Node.js web uygulama çatısıdır. -
      - -
      -

      API'ler

      - Sınırsız HTTP yardımcı araç ve katmanlar sayesinde sağlam bir API oluşturmak hızlı ve kolaydır. -
      - -
      -

      Performans

      Express, bildiğiniz ve sevdiğiniz Node.js özelliklerini gizlemeden ince bir temel web uygulaması özellikleri katmanı sağlar. -
      - -
      -

      Çatılar

      Birçok popüler çatı Express tabanlıdır. -
      -
      - -
      - -
      - {% include announcement/announcement-{{ page.lang }}.md %} -
      diff --git a/tr/resources/community.md b/tr/resources/community.md deleted file mode 100644 index cf72db9d33..0000000000 --- a/tr/resources/community.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -layout: page -title: Express community -menu: resources -lang: tr ---- -
      -# Community - -## Mailing List - -Join over 2000 Express users or browse over 5000 -discussions in the [Google Group](https://groups.google.com/group/express-js). - -## Gitter - -The [expressjs/express chatroom](https://gitter.im/expressjs/express) is great place -for developers interested in the everyday discussions related to Express. - -## IRC channel - -Hundreds of developers idle in #express on freenode every day. -If you have questions about the framework, jump in for quick -feedback. - -## Issues - -If you've come across what you think is a bug, or just want to make -a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues). - -## Technical committee - -The Express technical committee meets online every two weeks to discuss development and maintenance of Express, and other issues relevant to the Express project. -Each meeting is typically announced in an [expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to the Google Hangout, which is -open to all observers. - -The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). - -Members of the Express technical committee are: - -- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey -- [@crandmck](https://github.com/crandmck) - Rand McKinney -- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson -- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa -- [@jonathanong](https://github.com/jonathanong) - jongleberry -- [@LinusU](https://github.com/LinusU) - Linus Unnebäck -- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce -- [@troygoode](https://github.com/troygoode) - Troy Goode - -## Examples - -View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples) -in the repository covering everything from API design and authentication to template engine integration. - -## Other modules - -Our vibrant community has created a large variety of extensions, -[middleware modules](/{{ page.lang }}/resources/middleware.html) and -[higher-level frameworks](frameworks.html). - -Additionally, the Express community maintains modules in these two GitHub orgs: - -- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). -- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. - -See also the [Express wiki](https://github.com/expressjs/express/wiki). -
      diff --git a/tr/resources/companies-using-express.md b/tr/resources/companies-using-express.md deleted file mode 100644 index 7bb919db5c..0000000000 --- a/tr/resources/companies-using-express.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -layout: page -title: Companies using Express -menu: resources -lang: tr ---- -
      -# Companies using Express in production - - -
      diff --git a/tr/resources/contributing.md b/tr/resources/contributing.md deleted file mode 100644 index 3e14430e6e..0000000000 --- a/tr/resources/contributing.md +++ /dev/null @@ -1,196 +0,0 @@ ---- -layout: page -title: Contributing to Express -menu: resources -lang: tr ---- -
      -# Contributing to Express - -Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [Node.js Foundation](https://nodejs.org/foundation/). -These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. - -* [Technical committee](#technical-committee) -* [Community contributing guide](#community-contributing-guide) -* [Collaborator's guide](#collaborators-guide) -* [Security policies and procedures](#security-policies-and-procedures) - -## Technical committee - -The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). - -## Community contributing guide - -> NOTE: This is copied from the [Contributing Guide in the repo](https://github.com/expressjs/express/blob/master/Contributing.md). - -The goal of this guide is to create a contribution process that: - -* Encourages new contributions. -* Encourages contributors to remain involved. -* Avoids unnecessary processes and bureaucracy whenever possible. -* Creates a transparent decision making process which makes it clear how -contributors can be involved in decision making. - -This document is based on much prior art in the Node.js community, io.js, -and the Node.js project. - -Vocabulary: - -* A **Contributor** is any individual creating or commenting on an issue or pull request. -* A **Committer** is a subset of contributors who have been given write access to the repository. -* A **TC (Technical Committee)** is a group of committers representing the required technical -expertise to resolve rare disputes. - -### Logging issues - -Log an issue for any question or problem you might have. When in doubt, log an issue, -any additional policies about what to include will be provided in the responses. The only -exception is security dislosures which should be sent privately. - -Committers may direct you to another repository, ask for additional clarifications, and -add appropriate metadata before the issue is addressed. - -Please be courteous, respectful, and every participant is expected to follow the -project's Code of Conduct. - -### Contributions - -Any change to resources in this repository must be through pull requests. This applies to all changes -to documentation, code, binary files, etc. Even long term committers and TC members must use -pull requests. - -No pull request can be merged without being reviewed. - -For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that -contributors in other timezones have time to review. Consideration should also be given to -weekends and other holiday periods to ensure active committers all have reasonable time to -become involved in the discussion and review process if they wish. - -The default for each contribution is that it is accepted once no committer has an objection. -During 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. There is no additional "sign off" -process for contributions to land. Once all issues brought by committers are addressed it can -be landed by any committer. - -In the case of an objection being raised in a pull request by another committer, all involved -committers should seek to arrive at a consensus by way of addressing concerns being expressed -by discussion, compromise on the proposed change, or withdrawal of the proposed change. - -If a contribution is controversial and committers cannot agree about how to get it to land -or if it should land then it should be escalated to the TC. TC members should regularly -discuss pending contributions in order to find a resolution. It is expected that only a -small minority of issues be brought to the TC for resolution and that discussion and -compromise among committers be the default resolution mechanism. - -### Becoming a committer - -All contributors who land a non-trivial contribution should be on-boarded in a timely manner, -and added as a committer, and be given write access to the repository. - -Committers are expected to follow this policy and continue to send pull requests, go through -proper review, and have other committers merge their pull requests. - -### TC process - -The TC uses a "consensus seeking" process for issues that are escalated to the TC. -The group tries to find a resolution that has no open objections among TC members. -If a consensus cannot be reached that has no objections then a majority wins vote -is called. It is also expected that the majority of decisions made by the TC are via -a consensus seeking process and that voting is only used as a last-resort. - -Resolution may involve returning the issue to committers with suggestions on how to -move forward towards a consensus. It is not expected that a meeting of the TC -will resolve all issues on its agenda during that meeting and may prefer to continue -the discussion happening among the committers. - -Members can be added to the TC at any time. Any committer 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. Members who do not participate consistently at the level of -a majority of the other members are expected to resign. - -## Collaborator's guide - -> NOTE: This is copied from the [Collaborator guide in the Express repository](https://github.com/expressjs/express/blob/master/Collaborator-Guide.md). - -### Website Issues - -Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. - -### PRs and code contributions - -* Tests must pass. -* Follow existing coding style. -* If you fix a bug, add a test. - -### Branches - -* Use the `master` branch for bug fixes or minor work that is intended for the current release stream -* Use the correspondingly named branch, e.g. `5.0`, for anything intended for a future release of Express - -### Steps for contributing - -* [Create an issue](https://github.com/expressjs/express/issues/new) for the bug you want to fix or the feature that you want to add. -* Create your own [fork](https://github.com/expressjs/express) on github, then checkout your fork. -* Write your code in your local copy. It's good practice to create a branch for each new issue you work on, although not compulsory. -* To run the test suite, first install the dependencies by running `npm install`, then run `npm test`. -* If the tests pass, you can commit your changes to your fork and then create a pull request from there. Make sure to reference your issue from the pull request comments by including the issue number e.g. #123. - -### Issues which are questions - -We will typically close any vague issues or questions that are specific to some app you are writing. Please double check the docs and other references before being trigger happy with posting a question issue. - -Things that will help get your question issue looked at: - -* Full and runnable JS code. -* Clear description of the problem or unexpected behavior. -* Clear description of the expected result. -* Steps you have taken to debug it yourself. - -If you post a question and do not outline the above items or make it easy for us to understand and reproduce your issue, it will be closed. - -## Security Policies and Procedures - -> NOTE: This is copied from [Security Policies and Procedures in the Express repository](https://github.com/expressjs/express/blob/master/Security.md). - -This document outlines security procedures and general policies for the Express -project. - - * [Reporting a Bug](#reporting-a-bug) - * [Disclosure Policy](#disclosure-policy) - * [Comments on this Policy](#comments-on-this-policy) - -### Reporting a Bug - -The Express team and community take all security bugs in Express seriously. -Thank you for improving the security of Express. We appreciate your efforts and -responsible disclosure and will make every effort to acknowledge your -contributions. - -Report security bugs by emailing the lead maintainer in the Readme.md file. - -The lead maintainer will acknowledge your email within 48 hours, and will send a -more detailed response within 48 hours indicating the next steps in handling -your report. After the initial reply to your report, the security team will -endeavor to keep you informed of the progress towards a fix and full -announcement, and may ask for additional information or guidance. - -Report security bugs in third-party modules to the person or team maintaining -the module. You can also report a vulnerability through the -[Node Security Project](https://nodesecurity.io/report). - -### Disclosure Policy - -When the security team receives a security bug report, they will assign it to a -primary handler. This person will coordinate the fix and release process, -involving the following steps: - - * Confirm the problem and determine the affected versions. - * Audit code to find any potential similar problems. - * Prepare fixes for all releases still under maintenance. These fixes will be - released as fast as possible to npm. - -### Comments on this Policy - -If you have suggestions on how this process could be improved please submit a -pull request. -
      diff --git a/tr/resources/frameworks.md b/tr/resources/frameworks.md deleted file mode 100644 index ff9b16e1b7..0000000000 --- a/tr/resources/frameworks.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -layout: page -title: Frameworks built on Express -menu: frameworks -lang: tr ---- -
      -# Frameworks built on Express - -Several popular Node.js frameworks are built on Express: - -- **[Feathers](http://feathersjs.com)**: Build prototypes in minutes and production ready real-time apps in days. -- **[ItemsAPI](https://www.itemsapi.com/)**: Search backend for web and mobile applications built on Express and Elasticsearch. -- **[KeystoneJS](http://keystonejs.com/)**: Website and API Application Framework / CMS with an auto-generated React.js Admin UI. -- **[Kraken](http://krakenjs.com/)**: Secure and scalable layer that extends Express by providing structure and convention. -- **[LEAN-STACK](http://lean-stack.io)**: The Pure JavaScript Stack. -- **[LoopBack](http://loopback.io)**: Highly-extensible, open-source Node.js framework for quickly creating dynamic end-to-end REST APIs. -- **[MEAN](http://mean.io/)**: Opinionated fullstack JavaScript framework that simplifies and accelerates web application development. -- **[Sails](http://sailsjs.org/)**: MVC framework for Node.js for building practical, production-ready apps. -- **[Bottr](http://bottr.co/)**: Framework that simplifies building chatbot applications. -- **[Hydra-Express](https://github.com/flywheelsports/fwsp-hydra-express)**: Hydra-Express is a light-weight library which facilitates building Node.js Microservices using ExpressJS. -- **[Blueprint](http://github.com/onehilltech/blueprint)**: Highly-configurable MVC framework for composing production-ready services from reusable components -- **[Locomotive](http://locomotivejs.org/)**: Powerful MVC web framework for Node.js from the maker of Passport.js -
      diff --git a/tr/resources/glossary.md b/tr/resources/glossary.md deleted file mode 100644 index af88c26586..0000000000 --- a/tr/resources/glossary.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -layout: page -title: Express glossary -menu: resources -lang: tr ---- -
      -# Glossary - -### application - -In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/{{ page.lang }}/api.html#express). - -### API - -Application programming interface. Spell out the abbreviation when it is first used. - -### Express - -A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable. - -### libuv - -A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js. - -### middleware - -A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: - - * `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware. - * `app.use(mw)` is called _adding the middleware to the global processing stack_. - * `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_. - -### Node.js - -A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". - -### open-source, open source - -When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Note: Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. - -### request - -An HTTP request. A client submits an HTTP request message to a server, which returns a response. 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 - -An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body. - -### route - -Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route. - -### router - -See [router](/{{ page.lang }}/api.html#router) in the API reference. -
      diff --git a/tr/resources/learning.md b/tr/resources/learning.md deleted file mode 100644 index 544d5e7a33..0000000000 --- a/tr/resources/learning.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -layout: page -title: Ek öğrenme -menu: resources -lang: tr ---- -
      - -# Ek öğrenme - -
      Disclaimer: Unendorsed community content.
      - -## Books - -Here are a few of the many books on Express: - -- **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, April 2016. - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Getting MEAN with Mongo, Express, Angular, and Node, Second Edition](http://www.manning.com/sholmes2/)**, -Manning Publications, April 2017. - - **[Pro Express.js: Master Express.js: The Node.js Framework For Your Web Development](http://www.apress.com/9781484200384)**, -Apress, December 2014. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Node-tricks Blog: Express category](http://node-tricks.com/category/express/) -- [Baboon Blog: Express category](http://www.baboon.ir/tutorials/expressjs/) (Persian language) -- [Techforgeek Blog: Express category](http://techforgeek.com/expressjs/) -- [RoseHosting.com Blog: Express tag](https://www.rosehosting.com/blog/tag/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. -
      diff --git a/tr/resources/middleware.md b/tr/resources/middleware.md deleted file mode 100644 index e23883c422..0000000000 --- a/tr/resources/middleware.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -layout: page -title: Express middleware -menu: resources -lang: tr ---- -
      -## Express middleware - -The Express middleware modules listed here are maintained by the -[Expressjs team](https://github.com/orgs/expressjs/people). - -|Middleware module | Description | Replaces built-in function (Express 3)| -|---------------------------|---------------------|----------------------| -| [body-parser](/resources/middleware/body-parser.html) | Parse HTTP request body. See also: [body](https://github.com/raynos/body), [co-body](https://github.com/visionmedia/co-body), and [raw-body](https://github.com/stream-utils/raw-body). | express.bodyParser | -| [compression](/resources/middleware/compression.html) | Compress HTTP responses. | express.compress | -| [connect-rid](/resources/middleware/connect-rid.html) | Generate unique request ID. | NA | -| [cookie-parser](/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies) and [keygrip](https://github.com/jed/keygrip). | express.cookieParser| -| [cookie-session](/resources/middleware/cookie-session.html) | Establish cookie-based sessions.| express.cookieSession | -| [cors](/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options.| NA -| [csurf](/resources/middleware/csurf.html) | Protect from CSRF exploits.|express.csrf | -| [errorhandler](/resources/middleware/errorhandler.html) |Development error-handling/debugging. |express.errorHandler | -| [method-override](/resources/middleware/method-override.html) |Override HTTP methods using header. |express.methodOverride | -| [morgan](/resources/middleware/morgan.html) | HTTP request logger. | express.logger | -| [multer](/resources/middleware/multer.html) | Handle multi-part form data. | express.bodyParser | -| [response-time](/resources/middleware/response-time.html) | Record HTTP response time. |express.responseTime | -| [serve-favicon](/resources/middleware/serve-favicon.html) | Serve a favicon. |express.favicon | -| [serve-index](/resources/middleware/serve-index.html) | Serve directory listing for a given path.| express.directory | -| [serve-static](/resources/middleware/serve-static.html) |Serve static files. |express.static | -| [session](/resources/middleware/session.html) | Establish server-based sessions (development only). | express.session | -| [timeout](/resources/middleware/timeout.html) | Set a timeout period for HTTP request processing.|express.timeout | -| [vhost](/resources/middleware/vhost.html) |Create virtual domains.|express.vhost| - - - -## Additional middleware modules - -These are some additional popular middleware modules. - -|Middleware module | Description | -|---------------------------|---------------------| -| [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus) | Optimize image serving. Switches images to `.webp` or `.jxr`, if possible.| -| [express-debug](https://github.com/devoidfury/express-debug) | Development tool that adds information about template variables (locals), current session, and so on.| -| [express-partial-response](https://github.com/nemtsov/express-partial-response) | Filters out parts of JSON responses based on the `fields` query-string; by using Google API's Partial Response.| -| [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn) | Use a CDN for static assets, with multiple host support.| -| [express-slash](https://github.com/ericf/express-slash) | Handles routes with and without trailing slashes.| -| [express-stormpath](https://github.com/stormpath/stormpath-express) | User storage, authentication, authorization, SSO, and data security.| -| [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize) | Redirects HTTP requests containing uppercase to a canonical lowercase form.| -| [helmet](https://github.com/helmetjs/helmet) |Helps secure your apps by setting various HTTP headers.| -| [join-io](https://github.com/coderaiser/join-io) | Joins files on the fly to reduce the requests count.| -| [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [http://passportjs.org/](http://passportjs.org/) for more information.| -| [static-expiry](https://github.com/paulwalker/connect-static-expiry) | Fingerprint URLs or caching headers for static assets.| -| [view-helpers](https://github.com/madhums/node-view-helpers) | Common helper methods for views.| -| [sriracha-admin](https://github.com/hdngr/siracha) | Dynamically generate an admin site for Mongoose. | - -For more middleware modules, see [http-framework](https://github.com/Raynos/http-framework/wiki/Modules). -
      diff --git a/tr/resources/utils.md b/tr/resources/utils.md deleted file mode 100644 index 34717d66f2..0000000000 --- a/tr/resources/utils.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: page -title: Express utilities -menu: resources -lang: tr ---- -
      -## 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-match](https://www.npmjs.com/package/path-match) | Thin wrapper around [path-to-regexp](https://github.com/component/path-to-regexp) to make extracting parameter names easier.| -| [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. | -| [routington](https://www.npmjs.com/package/routington) | Trie-based URL router for defining and matching URLs. | -| [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.| -| [templation](https://www.npmjs.com/package/templation) | View system similar to `res.render()` inspired by [co-views](https://github.com/visionmedia/co-views) and [consolidate.js](https://github.com/visionmedia/consolidate.js/). | - - -For additional low-level HTTP-related modules, see [jshttp](http://jshttp.github.io/) . -
      diff --git a/tr/starter/basic-routing.md b/tr/starter/basic-routing.md deleted file mode 100644 index 727d9252b8..0000000000 --- a/tr/starter/basic-routing.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -layout: page -title: Express yol atama -menu: starter -lang: tr ---- -# Basit yol atama - -Yol atama, bir uygulamanın belrili bir adreste belirli bir HTTP methodu ile (GET, POST gibi) gelen isteğe ne şekilde cevap vereceğine karşılık gelir. - -Her yol, girilen adres eşleştiğinde bir veya daha fazla fonksiyon tarafından işlenebilir. - -Yol tanımları aşağıdaki şekilde yapılanmıştır: - -```js -app.METHOD(PATH, HANDLER) -``` - -Burada: - -- `app`, `express`'in bir örneği. -- `METHOD`, [HTTP istek methodu](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods), küçük harflerle. -- `PATH`, sunucuda bulunan yol. -- `HANDLER`, adres bu yol ile eşleştiğinde çalıştırılan fonksiyon. - -
      -Bu konu `express` ve `app` örneklerinin bulunduğunu ve sunucunun çalıştığını varsayar. Eğer bir uygulama oluşturup çalıştırmak hakkında bir bilginiz yoksa, [Merhaba Dünya örneği](/{{ page.lang }}/starter/hello-world.html) sayfasını ziyaret edin. -
      - -Aşağıdaki örnekler nasıl basit bir şekilde yol tanımlayabileceğinizi gösterir. - -Anasayfada `Merhaba Dünya!` ile cevap verin: - -```js -app.get('/', function (req, res) { - res.send('Merhaba Dünya!') -}) -``` - -Kök dizine (`/`) gelen POST isteğine bir cevap verin: - -```js -app.post('/', function (req, res) { - res.send('POST isteği geldi!') -}) -``` - -`/user` yoluna gelen PUT isteği: - -```js -app.put('/user', function (req, res) { - res.send('/user adresinde bir PUT isteği') -}) -``` - -`/user` yoluna gelen DELETE isteği: - -```js -app.delete('/user', function (req, res) { - res.send('/user adresinde bir DELETE isteği') -}) -``` - -Yol atama ile ilgili daha fazla detay için, [yol atama](/{{ page.lang }}/guide/routing.html) sayfasını ziyaret edin. - -### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/tr/starter/faq.md b/tr/starter/faq.md deleted file mode 100644 index 00fd0d5d0b..0000000000 --- a/tr/starter/faq.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -layout: page -title: Express Sıkça Sorulan Sorular -menu: starter -lang: tr ---- -# Sıkça Sorulan Sorular - -## Uygulamamın yapısı nasıl olmalı? - -Bu soruya verilebilecek kesin bir cevap yoktur. Cevap, uygulamanızın boyutuna ve uygulamaya dahil ekibe göre değişir. En üst seviyede esneklik için Express uygulama yapısı için herhangi bir varsayım yapmaz. - -Yollar ve diğer uygulamaya özel mantık istediğiniz yapıda, istediğiniz kadar dosyanın içinde barınabilir. Örnek olarak şunlara göz atabilirsiniz: - -* [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) -* [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc) - -Ayrıca, bu dizaynlardan bazılarını basitleştiren, üçüncü parti bir Express uzantısı bulunmaktadır: - -* [Resourceful routing](https://github.com/expressjs/express-resource) - -## Nasıl model tanımlarım? - -Express'te veritabanı kavramı bulunmamaktadır. Bu konsept diğer üçüncü parti modüllerine bırakılmıştır, bu sayede neredeyse herhangi bir veritabanına bağlantı sağlayabilirsiniz. - -Model üzerine Express tabanlı bir framework için [LoopBack](http://loopback.io) adresini ziyaret edin. - -## Kimlik doğrulamasını nasıl sağlarım? - -Kimlik doğrulama Express'in bulundurmayı tercih etmediği başka bir konu. İstediğiniz herhangi bir kimlik doğrulama planını kullanabilirsiniz. Basit kullanıcı adı / şifre planı için [bu örneğe](https://github.com/expressjs/express/tree/master/examples/auth) göz atın. - -## Express hangi görünüm (view) motorlarını destekliyor? - -Express `(path, locals, callback)` kalıbını sağlayan herhangi bir görünüm motorunu destekler. Şablon motoru arayüzlerini ve önbelleklemeyi normalleştirmek için, [consolidate.js](https://github.com/visionmedia/consolidate.js)'e göz atın. Listelenmeyen görünüm motorları da Express'in yapısına uygun olabilir. - -Daha fazla bilgi için, [Express ile görünüm motorlarını kullanmak](/{{page.lang}}/guide/using-template-engines.html). - -## 404 cevapları ile nasıl başa çıkarım? - -Express'te 404 cevapları bir hatanın sonucu olarak ortaya çıkmaz, bu yüzden hata işleyici ara katman bunları yakalamaz. Bunun sebebi 404 cevabı sadece yapılacak ekstra işin eksik olduğunu belirtir; başka bir sözle, Express tüm ara katman fonksiyonlarını ve yolları çalıştırdı, ve bunların hiçbirinin cevap döndürmediğini fark etti. Tek yapmanız gereken, bu yığının (tüm fonksiyonların) en sonuna 404'ü işleyen bir ara katman fonksiyonu yazmak: - -```js -app.use(function (req, res, next) { - res.status(404).send('Üzgünüm, dosyayı bulamadım!') -}) -``` - -Yolları dinamik olarak `express.Router()`'ın bir örneği üzerine tanımlayın, böylece tanımlarınızın yerine ara katman fonksiyonları geçmez. - -## Hata işleyici fonksiyonları nasıl kullanabilirim? - -Hata ile ilgili ara katman fonksiyonları da tıpkı diğer ara katman fonksiyonları gibi tanımlanır. Aradaki tek fark üç argüman yerine şu şekilde dört argüman kullanılmasıdır `(err, req, res, next)`: - -```js -app.use(function (err, req, res, next) { - console.error(err.stack) - res.status(500).send('Bir hata oluştu!') -}) -``` - -Daha fazla bilgi için, [Hata işleme](/{{ page.lang }}/guide/error-handling.html). - -## Yalın HTML dosyalarını nasıl işlerim? - -Yalın HTML için `res.render()` fonksiyonun kullanmak zorunda değilsiniz. Eğer dosyanız belirli ise, `res.sendFile()` fonksiyonunu kullanın. Eğer bir dizinden birden çok içerik sunuyorsanız, `express.static()` ara katman fonksiyonunu kullanın. - -### [Önceki: Statik Dosyalar ](/{{ page.lang }}/starter/static-files.html) diff --git a/tr/starter/generator.md b/tr/starter/generator.md deleted file mode 100644 index 03894e121e..0000000000 --- a/tr/starter/generator.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -layout: page -title: Express uygulama oluşturucu -menu: starter -lang: tr ---- -# Express uygulama oluşturucu - -Çabukça bir uygulama iskeleti oluşturmak için, `express-generator` aracını kullanın. - -`express-generator` paketi `express` komut-satır aracını kurar. Bunu yapmak için aşağıdaki komutu çalıştırın: - -```sh -$ npm install express-generator -g -``` - -Komut seçeneklerini `-h` opsiyonu ile görüntüleyin: - -```sh -$ express -h - - Usage: express [options] [dir] - - Options: - - -h, --help output usage information - --version output the version number - -e, --ejs add ejs engine support - --hbs add handlebars engine support - --pug add pug engine support - -H, --hogan add hogan.js engine support - --no-view generate without view engine - -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) - -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css) - --git add .gitignore - -f, --force force on non-empty directory -``` - -aşağıdaki örnek, _myapp_ adında bir Express uygulaması yaratır. Uygulama _myapp_ dizininde barınacak ve görünüm (view) motoru Pug olarak ayarlanacaktır. - -```sh -$ express --view=pug myapp - - create : myapp - create : myapp/package.json - create : myapp/app.js - create : myapp/public - create : myapp/public/javascripts - create : myapp/public/images - create : myapp/routes - create : myapp/routes/index.js - create : myapp/routes/users.js - create : myapp/public/stylesheets - create : myapp/public/stylesheets/style.css - create : myapp/views - create : myapp/views/index.pug - create : myapp/views/layout.pug - create : myapp/views/error.pug - create : myapp/bin - create : myapp/bin/www -``` - -Daha sonrasında bağımlılıkları kurun: - -```sh -$ cd myapp -$ npm install -``` - -MacOS veya Linux için uygulamayı bu komut ile çalıştırın: - -```sh -$ DEBUG=myapp:* npm start -``` - -Windows için bu komutu kullanın: - -```sh -> set DEBUG=myapp:* & npm start -``` - -Uygulamaya erişmek için tarayıcınızda `http://localhost:3000/` adresini ziyaret edin. - -Oluşturulan uygulamanın dizini aşağıdaki yapıda olacaktır: - -```sh -. -├── app.js -├── bin -│ └── www -├── package.json -├── public -│ ├── images -│ ├── javascripts -│ └── stylesheets -│ └── style.css -├── routes -│ ├── index.js -│ └── users.js -└── views - ├── error.pug - ├── index.pug - └── layout.pug - -7 directories, 9 files -``` - -
      -Burada oluşturulan dizin yapısı, Express uygulamasını yapılandırabileceğiniz birçok seçenekten sadece birisidir. İhtiyacınıza en uygun şekilde bu yapıyı kullanabilir ya da düzenleyebilirsiniz. -
      - -### [Önceki: Merhaba Dünya ](/{{ page.lang }}/starter/hello-world.html)    [Sonraki: Basit Yol Atama](/{{ page.lang }}/starter/basic-routing.html) diff --git a/tr/starter/hello-world.md b/tr/starter/hello-world.md deleted file mode 100644 index 71ffa9b1f0..0000000000 --- a/tr/starter/hello-world.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -layout: page -title: Express "Merhaba Dünya" örneği -menu: starter -lang: tr ---- - -# Merhaba Dünya Örneği - -
      -Aşağıda verilmiş olan, Express ile oluşturabileceğiniz en basit uygulamadır. Bu, birçok JavaScript dosyası, Jade şablonları ve çeşitli alt dizinler içeren [Express generator](/{{ page.lang }}/starter/generator.html) ile oluşturacağınız projelerin aksine tek dosyadan oluşan bir projedir. -
      - - -
      
      -const express = require('express')
      -const app = express()
      -const port = 3000
      -
      -app.get('/', (req, res) => {
      -  res.send('Merhaba Dünya!')
      -})
      -
      -app.listen(port, () => {
      -  console.log(`Example app listening at http://localhost:${port}`)
      -})
      -
      - -Bu uygulama bir sunucu çalıştırır ve gelen bağlantılar için 3000 portunu dinler. (`/`) kök dizinine gelen isteklere "Hello World!" ile yanıt verir. Bunun haricindeki tüm adreslere, **404 Not Found** hatası verecektir. - -Yukarıdaki örnek gerçekten de çalışmakta olan bir sunucudur: Yukarıda verilen adrese tıklayın. Gerçek zamanlı günlüklerle sunucunun bir cevap verdiğini göreceksiniz, ve yukarıda yapacağınız her değişiklik eş zamanlı olarak çalıştırılacaktır. Bu özellik arkada bir Node sistemine bağlı olup, tarayıcınızda bu sisteme bir arayüz sağlayan [RunKit](https://runkit.com) sayesinde bulunmaktadır. - - -
      -RunKit bir üçüncü parti uygulamasıdır ve Express projesi ile bir bağı yoktur. -
      - -### Bilgisayarınızda Çalıştırmak - -İlk olarak `myapp` adında bir dizin oluşturun, o dizine geçin ve `npm init` komutunu çalıştırın. Sonra `express`i [bu sayfada](/{{ page.lang }}/starter/installing.html) gösterildiği gibi bir bağımlılık olarak kurun. - -`myapp` dizininde `app.js` adında bir dosya oluşturun ve yukarıdaki kodu bu dosyaya kopyalayın. - -
      -`req` (request/istek) ve `res` (response/cevap) objeleri Node'da bulunanlar ile birebir aynıdır, bu yüzden -`req.pipe()`, `req.on('data', callback)`, gibi komutları Express dahil olmadan kullanabilirsiniz. -
      - -Uygulamayı aşağıdaki komutla çalıştırın: - -```sh -$ node app.js -``` - -Sonucu görmek için sunucunuzda `http://localhost:3000/` adresini ziyaret edin. - -### [Önceki: Kurulum ](/{{ page.lang }}/starter/installing.html)    [Sonraki: Express Oluşturucu ](/{{ page.lang }}/starter/generator.html) - diff --git a/tr/starter/installing.md b/tr/starter/installing.md deleted file mode 100644 index e4870e2992..0000000000 --- a/tr/starter/installing.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -layout: page -title: Express Kurulumu -menu: starter -lang: tr ---- - -# Kurulum - -[Node.js](https://nodejs.org/)'in kurulu olduğunu varsayarak, uygulamanızı -barındıracak bir dizin oluşturun ve o dizine geçiş yapın. - -```sh -$ mkdir myapp -$ cd myapp -``` - -Uygulamanız için `package.json` dosyasını oluşturmak için `npm init` komutunu -çalıştırın. -`package.json` dosyasının nasıl çalıştığı hakkında daha fazla bilgi edinmek için [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json) adresini kullanın. - -```sh -$ npm init -``` - -Bu komut size uygulamanızın adı ve versiyonu gibi bir kaç soru yöneltecektir. -Şimdilik, çoğu soru için ENTER tuşuna basıp varsayılan ayarları uygulayabilirsiniz, aşağıdaki hariç: - - -```sh -entry point: (index.js) -``` - -`app.js` ya da ana dosyanıza vermek istediğiniz ismi girin. Eğer ana dosyanızın `index.js` olmasını istiyorsanız, ENTER tuşu ile varsayılanı uygulayabilirsiniz. - -Şimdi Express'i `myapp` dizinine kurun ve bağımlı uygulamalar listesine ekleyin. Örneğin: - - -```sh -$ npm install express --save -``` - -Express'i geçici olarak kurmak ve bağımlı uygulamalar listesine eklememek istiyorsanız: - -```sh -$ npm install express --no-save -``` - -
      -npm 5.0+ versiyonları için npm install komutu, kurulacak modülü varsayılan olarak `package.json` içindeki bağımlılıklar listesine ekler; daha eski npm versiyonları için `--save` ayrıca belirtilmelidir. Daha sonrasında, uygulama dizininde `npm install` komutunu çalıştırmak, bağımlılık listesindeki uygulamaları otomatik olarak yükler. -
      - -### [Sonraki: Merhaba Dünya ](/{{ page.lang }}/starter/hello-world.html) diff --git a/tr/starter/static-files.md b/tr/starter/static-files.md deleted file mode 100644 index ece1781bc9..0000000000 --- a/tr/starter/static-files.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: page -title: Express ile statik dosyalar -menu: starter -lang: tr ---- -# Express ile statik dosyaları sunmak - -Görseller, CSS dosyaları ve JavaScript dosyaları gibi statik dosyaları sunmak için, Express'te bulunan `express.static` ara katmanını kullanın. - -Fonksiyonun yapısı şu şekildedir: - -```js -express.static(root, [options]) -``` - -`root` argümanı statik dosyaların bulunduğu ana dizine karşılık gelir. -`options` argümanı hakkında detaylı bilgi için, [express.static](/{{page.lang}}/4x/api.html#express.static) sayfasını ziyaret edin. - -Örneğin, `public` dizininde bulunan görselleri, CSS dosyalarını ve JavaScript dosyalarını sunmak için bunu kullanın: - -```js -app.use(express.static('public')) -``` - -Artık `public` dizininde bulunan statik dosyaları görebilirsiniz: - -```plain-text -http://localhost:3000/images/kitten.jpg -http://localhost:3000/css/style.css -http://localhost:3000/js/app.js -http://localhost:3000/images/bg.png -http://localhost:3000/hello.html -``` - -
      -Express statik dosyaların yerlerine ana dizine bağlı olarak bakar. Bu yüzden statik dosyaları barındıran ana dizin URL'de bulunmaz. -
      - -Birden fazla statik dosya dizini kullanmak için `express.static` fonksiyonun birden fazla kullanabilirsiniz. - -```js -app.use(express.static('public')) -app.use(express.static('files')) -``` - -Express statik dosyalara `express.static` ile tanımladığınız sırayla bakar. - -
      NOT: En iyi sonuç için, statik dosyaları sunarken performansı artırmak için [reverse proxy](/{{page.lang}}/advanced/ önbelleği kullanın. -
      - -`express.static` ile sunulan dosyalar için sanal bir yol (statik dizinin aslında gerçekte bulunmadığı) yaratmak için, statik dizine aşağıdaki gibi bir [path tanımlayın](/{{ page.lang }}/4x/api.html#app.use). - - -```js -app.use('/static', express.static('public')) -``` - -Artık `public` dizinindeki dosyalara `/static` önekiyle ulaşabilirsiniz. - -```plain-text -http://localhost:3000/static/images/kitten.jpg -http://localhost:3000/static/css/style.css -http://localhost:3000/static/js/app.js -http://localhost:3000/static/images/bg.png -http://localhost:3000/static/hello.html -``` - -`express.static` fonksiyonu ile tanımladığınız yollar `node` processini çalıştırdığınız dizine bağlıdır. Bu yüzden, eğer express uygulamasını başka bir dizinden çalıştırıyorsanız, statik dizini tam adres olarak tanımlamanız daha güvenli olur. - -```js -const path = require('path') -app.use('/static', express.static(path.join(__dirname, 'public'))) -``` - -`serve-static` hakkında daha fazla bilgi almak için, [serve-static](/resources/middleware/serve-static.html) sayfasına göz atın. - -### [Önceki: Basit Yol Atama ](/{{ page.lang }}/starter/basic-routing.html)    [Sonraki: Sıkça Sorulan Sorular ](/{{ page.lang }}/starter/faq.html) diff --git a/uk/3x/api.md b/uk/3x/api.md deleted file mode 100644 index 6c09786d9d..0000000000 --- a/uk/3x/api.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: 3x-api -title: Express 3.x - Довідник API -menu: api -lang: uk ---- -
      - -
      - **Express версій 3.x БІЛЬШЕ НЕ ПІДТРИМУЄТЬСЯ** - - Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. -
      - -

      3.x API

      - - - {% include api/en/3x/express.md %} - - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} - - - {% include api/en/3x/res.md %} - - - {% include api/en/3x/middleware.md %} - -
      diff --git a/uk/4x/api.md b/uk/4x/api.md deleted file mode 100644 index f16f908193..0000000000 --- a/uk/4x/api.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - Довідник API -menu: api -lang: uk ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/uk/CHANGELOG.md b/uk/CHANGELOG.md deleted file mode 100644 index c027e846e4..0000000000 --- a/uk/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -18.03.2016 Додано сторінки для наступних лінків: -* http://expressjs.com/uk/starter/static-files.html (у головному меню) -* http://expressjs.com/uk/guide/writing-middleware.html (у головному меню) -* http://expressjs.com/uk/guide/migrating-5.html (у головному меню) -* http://expressjs.com/uk/advanced/best-practice-security.html (у головному меню) -* http://expressjs.com/uk/advanced/best-practice-performance.html (у головному меню) - diff --git a/uk/advanced/best-practice-performance.md b/uk/advanced/best-practice-performance.md deleted file mode 100644 index b6d75636b0..0000000000 --- a/uk/advanced/best-practice-performance.md +++ /dev/null @@ -1,440 +0,0 @@ ---- -layout: page -title: Кращі практики експлуатації при використанні Express -menu: advanced -lang: uk ---- - -# Кращі практики експлуатації: продуктивність та надійність - -## Огляд - -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](#code) (the dev part). -* [Things to do in your environment / setup](#env) (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 -* Don't use synchronous functions -* Use middleware to serve static files -* Do logging correctly -* Handle exceptions properly - -### 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: - -```js -var compression = require('compression') -var express = require('express') -var 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](#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](http://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. - -If you are using Node.js 4.0+ or io.js 2.1.0+, 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 actually use this in production, but rather to ensure that your code is ready for production. See the [Weekly update for io.js 2.1.0](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0) for more information. - -### Use middleware to serve static files - -In development, you can use [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) to serve static files. But don't do this in production, because this function has to read from the file system for every file request, so it will encounter significant latency and affect the overall performance of the app. Note that `res.sendFile()` is _not_ implemented with the [sendfile](http://linux.die.net/man/2/sendfile) system call, which would make it far more efficient. - -Instead, use [serve-static](https://www.npmjs.com/package/serve-static) middleware (or something equivalent), that is optimized for serving files for Express apps. - -An even better option is to use a reverse proxy to serve static files; see [Use a reverse proxy](#proxy) 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.err()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console_console_1) 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.err()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.err()` 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 [Winston](https://www.npmjs.com/package/winston) or [Bunyan](https://www.npmjs.com/package/bunyan). For a detailed comparison of these two libraries, see the StrongLoop blog post [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/). - - - -### 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](#restart) 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](#try-catch) -* [Use promises](#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://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop blog) - -#### 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#process_event_uncaughtexception) and there is a [proposal](https://github.com/nodejs/node-v0.x-archive/issues/2582) to remove it from the core. 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 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. - -Use a tool such as [JSHint](http://jshint.com/) or [JSLint](http://www.jslint.com/) to help you find implicit exceptions like [reference errors on undefined variables](http://www.jshint.com/docs/options/#undef). - -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(() => { - var jsonStr = req.query.params - try { - var 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 - -Promises will handle any exceptions (both explicit and implicit) in asynchronous code blocks that use `then()`. Just add `.catch(next)` to the end of promise chains. For example: - -```js -app.get('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) -}) - -app.use((err, req, res, next) => { - // handle error -}) -``` - -Now all errors asynchronous and synchronous get propagated to the error middleware. - -However, there are two caveats: - -1. All your asynchronous code must return promises (except emitters). If a particular library does not return promises, convert the base object by using a helper function like [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html). -2. Event emitters (like streams) can still cause uncaught exceptions. So make sure you are handling the error event properly; for example: - -```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) - -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) -``` - -For more information about error-handling by using promises, see: - -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) - - - -## 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" -* Ensure your app automatically restarts -* Run your app in a cluster -* Cache request results -* Use a load balancer -* Use a reverse proxy - -### 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](http://apmblog.dynatrace.com/2015/07/22/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 or Upstart). 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 Upstart, use the `env` keyword in your job file. For example: - -
      
      -# /etc/init/env.conf
      - env NODE_ENV=production
      -
      - -For more information, see the [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables). - -With systemd, use the `Environment` directive in your unit file. For example: - -
      
      -# /etc/systemd/system/myservice.service
      -Environment=NODE_ENV=production
      -
      - -For more information, see [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html). - -If you are using StrongLoop Process Manager, you can also [set the environment variable when you install StrongLoop PM as a service](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables). - -### 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](#exceptions) 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 (StrongLoop PM and pm2). - -The most popular process managers for Node are as follows: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -For a feature-by-feature comparison of the three process managers, see [http://strong-pm.io/compare/](http://strong-pm.io/compare/). For a more detailed introduction to all three, see [Process managers for Express apps](/{{ page.lang }}/advanced/pm.html). - -Using any of these process managers will suffice to keep your application up, even if it does crash from time to time. - -However, StrongLoop PM has lots of features that specifically target production deployment. You can use it and the related StrongLoop tools to: - -* Build and package your app locally, then deploy it securely to your production system. -* Automatically restart your app if it crashes for any reason. -* Manage your clusters remotely. -* View CPU profiles and heap snapshots to optimize performance and diagnose memory leaks. -* View performance metrics for your application. -* Easily scale to multiple hosts with integrated control for Nginx load balancer. - -As explained below, when you install StrongLoop PM as an operating system service using your init system, it will automatically restart when the system restarts. Thus, it will keep your application processes and clusters alive forever. - -#### 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 two main init systems in use today are [systemd](https://wiki.debian.org/systemd) and [Upstart](http://upstart.ubuntu.com/). - -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 variables: -Environment=NODE_ENV=production - -# Allow many incoming connections -LimitNOFILE=infinity - -# Allow core dumps for debugging -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)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). - -##### StrongLoop PM as a systemd service - -You can easily install StrongLoop Process Manager as a systemd service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. - -To install StrongLoop PM as a systemd service: - -
      
      -$ sudo sl-pm-install --systemd
      -
      - -Then start the service with: - -
      
      -$ sudo /usr/bin/systemctl start strong-pm
      -
      - -For more information, see [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10). - -##### Upstart - -Upstart is a system tool available on many Linux distributions for starting tasks and services during system startup, stopping them during shutdown, and supervising them. You can configure your Express app or process manager as a service and then Upstart will automatically restart it when it crashes. - -An Upstart service is defined in a job configuration file (also called a "job") with filename ending in `.conf`. The following example shows how to create a job called "myapp" for an app named "myapp" with the main file located at `/projects/myapp/index.js`. - -Create a file named `myapp.conf` at `/etc/init/` with the following content (replace the bold text with values for your system and app): - -
      
      -# When to start the process
      -start on runlevel [2345]
      -
      -# When to stop the process
      -stop on runlevel [016]
      -
      -# Increase file descriptor limit to be able to handle more requests
      -limit nofile 50000 50000
      -
      -# Use production mode
      -env NODE_ENV=production
      -
      -# Run as www-data
      -setuid www-data
      -setgid www-data
      -
      -# Run from inside the app dir
      -chdir /projects/myapp
      -
      -# The process to start
      -exec /usr/local/bin/node /projects/myapp/index.js
      -
      -# Restart the process if it is down
      -respawn
      -
      -# Limit restart attempt to 10 times within 10 seconds
      -respawn limit 10 10
      -
      - -NOTE: This script requires Upstart 1.4 or newer, supported on Ubuntu 12.04-14.10. - -Since the job is configured to run when the system starts, your app will be started along with the operating system, and automatically restarted if the app crashes or the system goes down. - -Apart from automatically restarting the app, Upstart enables you to use these commands: - -* `start myapp` – Start the app -* `restart myapp` – Restart the app -* `stop myapp` – Stop the app. - -For more information on Upstart, see [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook). - -##### StrongLoop PM as an Upstart service - -You can easily install StrongLoop Process Manager as an Upstart service. After you do, when the server restarts, it will automatically restart StrongLoop PM, which will then restart all the apps it is managing. - -To install StrongLoop PM as an Upstart 1.4 service: - -
      
      -$ sudo sl-pm-install
      -
      - -Then run the service with: - -
      
      -$ sudo /sbin/initctl start strong-pm
      -
      - -NOTE: On systems that don't support Upstart 1.4, the commands are slightly different. See [Setting up a production host (StrongLoop documentation)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10) for more information. - -### 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](http://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/dist/latest-v4.x/docs/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. However, rather than using this module directly, it's far better to use one of the many tools out there that does it for you automatically; for example [node-pm](https://www.npmjs.com/package/node-pm) or [cluster-service](https://www.npmjs.com/package/cluster-service). - -#### Using StrongLoop PM - -If you deploy your application to StrongLoop Process Manager (PM), then you can take advantage of clustering _without_ modifying your application code. - -When StrongLoop Process Manager (PM) runs an application, it automatically runs it in a cluster with a number of workers equal to the number of CPU cores on the system. You can manually change the number of worker processes in the cluster using the slc command line tool without stopping the app. - -For example, assuming you've deployed your app to prod.foo.com and StrongLoop PM is listening on port 8701 (the default), then to set the cluster size to eight using slc: - -
      
      -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
      -
      - -For more information on clustering with StrongLoop PM, see [Clustering](https://docs.strongloop.com/display/SLC/Clustering) in StrongLoop 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-cache.org/) or [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) (see also [Nginx Caching](https://serversforhackers.com/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](http://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](http://socket.io/docs/using-multiple-nodes/). - -#### Using StrongLoop PM with an Nginx load balancer - -[StrongLoop Process Manager](http://strong-pm.io/) integrates with an Nginx Controller, making it easy to configure multi-host production environment configurations. For more information, see [Scaling to multiple servers](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers) (StrongLoop documentation). - - -### 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://www.nginx.com/) or [HAProxy](http://www.haproxy.org/) in production. diff --git a/uk/advanced/best-practice-security.md b/uk/advanced/best-practice-security.md deleted file mode 100644 index cae5e0d479..0000000000 --- a/uk/advanced/best-practice-security.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -layout: page -title: Кращі практики безпеки для Express в експлуатації -menu: advanced -lang: uk ---- - -# Кращі практики експлуатації: Безпека - -## Огляд - -The term _"production"_ refers to the stage in the software lifecycle when an application or API is generally available to its end-users or consumers. In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively. - -Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production. - -This article discusses some security best practices for Express applications deployed to production. - -**NOTE**: If you believe you have discovered a security vulnerability in Express, please see -[Security Policies and Procedures](https://github.com/expressjs/express/blob/master/Security.md). - -## Don't use deprecated or vulnerable versions of Express - -Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html). - -Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/{{ page.lang }}/advanced/security-updates.html). If you are, update to one of the stable releases, preferably the latest. - -## Use TLS - -If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). - -You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_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://letsencrypt.org/isrg/). - -## Use Helmet - -[Helmet](https://www.npmjs.com/package/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. - -Helmet is actually just a collection of nine smaller middleware functions that set security-related HTTP headers: - -* [csp](https://github.com/helmetjs/csp) sets the `Content-Security-Policy` header to help prevent cross-site scripting attacks and other cross-site injections. -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) removes the `X-Powered-By` header. -* [hsts](https://github.com/helmetjs/hsts) sets `Strict-Transport-Security` header that enforces secure (HTTP over SSL/TLS) connections to the server. -* [ieNoOpen](https://github.com/helmetjs/ienoopen) sets `X-Download-Options` for IE8+. -* [noCache](https://github.com/helmetjs/nocache) sets `Cache-Control` and Pragma headers to disable client-side caching. -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) sets `X-Content-Type-Options` to prevent browsers from MIME-sniffing a response away from the declared content-type. -* [frameguard](https://github.com/helmetjs/frameguard) sets the `X-Frame-Options` header to provide [clickjacking](https://www.owasp.org/index.php/Clickjacking) protection. -* [xssFilter](https://github.com/helmetjs/x-xss-protection) sets `X-XSS-Protection` to enable the Cross-site scripting (XSS) filter in most recent web browsers. - -Install Helmet like any other module: - -
      
      -$ npm install --save helmet
      -
      - -Then to use it in your code: - -
      
      -...
      -var helmet = require('helmet');
      -app.use(helmet());
      -...
      -
      - -### At a minimum, disable X-Powered-By header - -If you don't want to use Helmet, then at least disable the `X-Powered-By` header. Attackers can use this header (which is enabled by default) to detect apps running Express and then launch specifically-targeted attacks. - -So, best practice is to to turn off the header with the `app.disable()` method: - -
      
      -app.disable('x-powered-by');
      -
      - -If you use `helmet.js`, it takes care of this for you. - -## Use cookies securely - -To ensure cookies don't open your app to exploits, don't use the default session cookie name and set cookie security options appropriately. - -There are two main middleware cookie session modules: - -* [express-session](https://www.npmjs.com/package/express-session) that replaces `express.session` middleware built-in to Express 3.x. -* [cookie-session](https://www.npmjs.com/package/cookie-session) that replaces `express.cookieSession` middleware built-in to Express 3.x. - -The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. 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). - -In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then express-session may be a better choice. - -### Don't use the default session cookie name - -Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. - -To avoid this problem, use generic cookie names; for example using [express-session](https://www.npmjs.com/package/express-session) middleware: - -
      
      -var session = require('express-session');
      -app.set('trust proxy', 1) // trust first proxy
      -app.use( session({
      -   secret : 's3Cur3',
      -   name : 'sessionId',
      -  })
      -);
      -
      - -### Set cookie security options - -Set the following cookie options to enhance security: - -* `secure` - Ensures the browser only sends the cookie over HTTPS. -* `httpOnly` - Ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks. -* `domain` - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next. -* `path` - indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request. -* `expires` - use to set expiration date for persistent cookies. - -Here is an example using [cookie-session](https://www.npmjs.com/package/cookie-session) middleware: - -
      
      -var session = require('cookie-session');
      -var express = require('express');
      -var app = express();
      -
      -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
      -app.use(session({
      -  name: 'session',
      -  keys: ['key1', 'key2'],
      -  cookie: { secure: true,
      -            httpOnly: true,
      -            domain: 'example.com',
      -            path: 'foo/bar',
      -            expires: expiryDate
      -          }
      -  })
      -);
      -
      - -## Ensure your dependencies are secure - -Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. - -Since npm@6, npm automatically reviews every install request. Also you can use 'npm audit' to analyze your dependency tree. - -```sh -$ 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: - -```sh -$ npm install -g snyk -$ cd your-app -``` - -Use this command to test your application for vulnerabilities: - -```sh -$ snyk test -``` - -Use this command to open a wizard that walks you through the process of applying updates or patches to fix the vulnerabilities that were found: - -```sh -$ snyk wizard -``` - -## Additional considerations - -Here are some further recommendations from the excellent [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Refer to that blog post for all the details on these recommendations: - -* Implement rate-limiting to prevent brute-force attacks against authentication. One way to do this is to use [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) to enforce a rate-limiting policy. Alternatively, you can use middleware such as [express-limiter](https://www.npmjs.com/package/express-limiter), but doing so will require you to modify your code somewhat. -* Use [csurf](https://www.npmjs.com/package/csurf) middleware to protect against cross-site request forgery (CSRF). -* 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 [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. - -## Avoid other known vulnerabilities - -Keep an eye out for [Node Security Project](https://npmjs.com/advisories) advisories that may affect Express or other modules that your app uses. In general, the Node Security Project is an excellent resource 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/index.php/Top_10_2013-Top_10) and take precautions to avoid them. diff --git a/uk/advanced/developing-template-engines.md b/uk/advanced/developing-template-engines.md deleted file mode 100755 index ed32a01e90..0000000000 --- a/uk/advanced/developing-template-engines.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: page -title: Розробка шаблонізаторів для Express -menu: advanced -lang: uk ---- - -# Розробка шаблонізаторів для Express - -Use the `app.engine(ext, callback)` method to create your own template engine. `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. - -The following code is an example of implementing a very simple template engine for rendering `.ntl` files. - -
      
      -var fs = require('fs'); // this engine requires the fs module
      -app.engine('ntl', function (filePath, options, callback) { // define the template engine
      -  fs.readFile(filePath, function (err, content) {
      -    if (err) return callback(new Error(err));
      -    // this is an extremely simple template engine
      -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
      -    .replace('#message#', '

      '+ options.message +'

      '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
      - -Your app will now be able to render `.ntl` files. Create a file named `index.ntl` in the `views` directory with the following content. - -
      
      -#title#
      -#message#
      -
      -Then, create the following route in your app. - -
      
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -When you make a request to the home page, `index.ntl` will be rendered as HTML. diff --git a/uk/advanced/pm.md b/uk/advanced/pm.md deleted file mode 100755 index abb9a225cf..0000000000 --- a/uk/advanced/pm.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -layout: page -title: Менеджери процесів для Express застосунків -menu: advanced -lang: uk ---- - -# Менеджери процесів для Express застосунків - -When you run Express apps for production, it is helpful to use a _process manager_ to achieve the following tasks: - -- Restart the app automatically if it crashes. -- Gain insights into runtime performance and resource consumption. -- Modify settings dynamically to improve performance. -- Control clustering. - -A process manager is somewhat like an application server: it's a "container" for applications that facilitates deployment, -provides high availability, and enables you to manage the application at runtime. - -The most popular process managers for Express and other Node.js applications are as follows: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -Using any of these three tools can be very helpful, however StrongLoop Process Manager is the only tool that provides a comprehensive runtime and deployment solution that addresses the entire Node.js application life cycle, with tooling for every step before and after production, in a unified interface. - -Here's a brief look at each of these tools. -For a detailed comparison, see [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) is a production process manager for Node.js applications. StrongLoop PM has built-in load balancing, monitoring, and multi-host deployment, and a graphical console. -You can use StrongLoop PM for the following tasks: - -- Build, package, and deploy your Node.js application to a local or remote system. -- View CPU profiles and heap snapshots to optimize performance and diagnose memory leaks. -- Keep processes and clusters alive forever. -- View performance metrics on your application. -- Easily manage multi-host deployments with Nginx integration. -- Unify multiple StrongLoop PMs to a distributed microservices runtime that is managed from Arc. - -You can work with StrongLoop PM by using a powerful command-line interface tool called `slc`, or a graphical tool called Arc. Arc is open source, with professional support provided by StrongLoop. - -For more information, see [http://strong-pm.io/](http://strong-pm.io/). - -Full documentation: - -- [Operating Node apps (StrongLoop documentation)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Installation -
      
      -$ [sudo] npm install -g strongloop
      -
      - -### Basic use -
      
      -$ cd my-app
      -$ slc start
      -
      - -View the status of Process Manager and all deployed apps: - -
      
      -$ slc ctl
      -Service ID: 1
      -Service Name: my-app
      -Environment variables:
      -  No environment variables defined
      -Instances:
      -    Version  Agent version  Cluster size
      -     4.1.13      1.5.14           4
      -Processes:
      -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
      -    1.1.57692  57692   0
      -    1.1.57693  57693   1     0.0.0.0:3001
      -    1.1.57694  57694   2     0.0.0.0:3001
      -    1.1.57695  57695   3     0.0.0.0:3001
      -    1.1.57696  57696   4     0.0.0.0:3001
      -
      - -List all the apps (services) under management: - -
      
      -$ slc ctl ls
      -Id          Name         Scale
      - 1          my-app       1
      -
      - -Stop an app: - -
      
      -$ slc ctl stop my-app
      -
      - -Restart an app: - -
      
      -$ slc ctl restart my-app
      -
      - -You can also "soft restart," which gives worker processes a grace period to close existing connections, then restarts the current application: - -
      
      -$ slc ctl soft-restart my-app
      -
      - -To remove an app from management: - -
      
      -$ slc ctl remove my-app
      -
      - -## PM2 - -PM2 is a production process manager for Node.js applications, that has a built-in load balancer. PM2 allows you to keep applications alive forever and reload them without downtime, and will facilitate common system admin tasks. PM2 also enables you to manage application logging, monitoring, and clustering. - -For more information, see [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Installation - -
      
      -$ [sudo] npm install pm2 -g
      -
      - -### Basic use - -When you start an app by using the `pm2` command, you must specify the path of the app. However, when you stop, restart, or delete an app, you can specify just the name or the id of the app. - -
      
      -$ pm2 start npm --name my-app -- start
      -[PM2] restartProcessId process id 0
      -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
      -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
      -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
      -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
      -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
      - Use the `pm2 show ` command to get more details about an app.
      -
      - -When you start an app by using the `pm2` command, the app is immediately sent to the background. You can control the background app from the command line by using various `pm2` commands. - -After an app is started by using the `pm2` command, it is registered in PM2's list of processes with an ID. You can therefore manage apps with the same name from different directories on the system, by using their IDs. - -Note that if more than one app with the same name is running, `pm2` commands affect all of them. So use IDs instead of names to manage individual apps. - -List all running processes: - -
      
      -$ pm2 list
      -
      - -Stop an app: - -
      
      -$ pm2 stop 0
      -
      - -Restart an app: - -
      
      -$ pm2 restart 0
      -
      - -To view detailed information about an app: - -
      
      -$ pm2 show 0
      -
      - -To remove an app from PM2's registry: - -
      
      -$ pm2 delete 0
      -
      - - -## Forever - -Forever is a simple command-line interface tool for ensuring that a given script runs continuously (forever). Forever's simple interface makes it ideal for running smaller deployments of Node.js apps and scripts. - -For more information, see [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Installation - -
      
      -$ [sudo] npm install forever -g
      -
      - -### Basic use - -To start a script, use the `forever start` command and specify the path of the script: - -
      
      -$ forever start script.js
      -
      - -This command will run the script in daemon mode (in the background). - -To run the script so that it is attached to the terminal, omit `start`: - -
      
      -$ forever script.js
      -
      - -It is a good idea to log output from the Forever tool and the script by using the logging options `-l`, `-o`, and `-e`, as shown this example: - -
      
      -$ forever start -l forever.log -o out.log -e err.log script.js
      -
      - -To view the list of scripts that were started by Forever: - -
      
      -$ forever list
      -
      - -To stop a script that was started by Forever use the `forever stop` command and specify the process index (as listed by the `forever list` command). - -
      
      -$ forever stop 1
      -
      - -Alternatively, specify the path of the file: - -
      
      -$ forever stop script.js
      -
      - -To stop all the scripts that were started by Forever: - -
      
      -$ forever stopall
      -
      - -Forever has many more options, and it also provides a programmatic API. diff --git a/uk/advanced/security-updates.md b/uk/advanced/security-updates.md deleted file mode 100755 index 6c7dc214aa..0000000000 --- a/uk/advanced/security-updates.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -layout: page -title: Оновлення безпеки Express -menu: advanced -lang: uk ---- - -# Оновлення безпеки - -
      -Node.js vulnerabilities directly affect Express. Therefore [keep a watch on Node.js vulnerabilities](http://blog.nodejs.org/vulnerability/) and make sure you are using the latest stable version of Node.js. -
      - -The list below enumerates the Express vulnerabilities that were fixed in the specified version update. - -**NOTE**: If you believe you have discovered a security vulnerability in Express, please see -[Security Policies and Procedures](https://github.com/expressjs/express/blob/master/Security.md). - -## 4.x - - * 4.11.1 - * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` - * 4.10.7 - * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 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 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. - * 4.8.0 - * Sparse arrays that have extremely high indexes in the query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - -## 3.x - -
      - **Express 3.x IS NO LONGER MAINTAINED** - - Known and unknown security issues in 3.x have not been addressed since the last update (1 August, 2015). Using the 3.x line should not be considered secure. -
      - - * 3.19.1 - * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` - * 3.19.0 - * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). - * 3.16.10 - * Fixed directory traversal vulnerabilities in `express.static`. - * 3.16.6 - * Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. - * 3.16.0 - * Sparse arrays that have extremely high indexes in query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - * 3.3.0 - * The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks. diff --git a/uk/api.md b/uk/api.md deleted file mode 100644 index 1d96eee04f..0000000000 --- a/uk/api.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API Reference -lang: uk ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/uk/guide/behind-proxies.md b/uk/guide/behind-proxies.md deleted file mode 100755 index 33ad963f91..0000000000 --- a/uk/guide/behind-proxies.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -layout: page -title: Express позаду проксі -menu: guide -lang: uk ---- - -# Express позаду проксі - -When running an Express app behind a proxy, set (by using [app.set()](/{{ page.lang }}/4x/api.html#app.set)) the application variable `trust proxy` to one of the values listed in the following table. - -
      -Although the app will not fail to run if the application variable `trust proxy` is not set, it will incorrectly register the proxy's IP address as the client IP address unless `trust proxy` is configured. -
      - - - - - - - - - - - - - - - - - - - - - -
      TypeValue
      Boolean -If `true`, the client's IP address is understood as the left-most entry in the `X-Forwarded-*` header. - -If `false`, the app is understood as directly facing the Internet and the client's IP address is derived from `req.connection.remoteAddress`. This is the default setting. -
      IP addresses -An IP address, subnet, or an array of IP addresses and subnets to trust. The following list shows the pre-configured subnet names: - -* loopback - `127.0.0.1/8`, `::1/128` -* linklocal - `169.254.0.0/16`, `fe80::/10` -* uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` - -You can set IP addresses in any of the following ways: - -
      app.set('trust proxy', 'loopback') // specify a single subnet
      -app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
      -app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
      -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
      - -When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address. -
      Number -Trust the `n`th hop from the front-facing proxy server as the client. -
      Function -Custom trust implementation. Use this only if you know what you are doing. -
      app.set('trust proxy', function (ip) {
      -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
      -  else return false;
      -});
      -
      - -Setting a non-`false` `trust proxy` value results in three important changes: - -
        -
      • The value of [req.hostname](/{{ page.lang }}/api.html#req.hostname) is derived from the value set in the `X-Forwarded-Host` header, which can be set by the client or by the proxy. -
      • -
      • `X-Forwarded-Proto` can be set by the reverse proxy to tell the app whether it is `https` or `http` or even an invalid name. This value is reflected by [req.protocol](/{{ page.lang }}/api.html#req.protocol). -
      • -
      • The [req.ip](/{{ page.lang }}/api.html#req.ip) and [req.ips](/{{ page.lang }}/api.html#req.ips) values are populated with the list of addresses from `X-Forwarded-For`. -
      • -
      - -The `trust proxy` setting is implemented using the [proxy-addr](https://www.npmjs.com/package/proxy-addr) package. For more information, see its documentation. diff --git a/uk/guide/database-integration.md b/uk/guide/database-integration.md deleted file mode 100644 index de92a8e7cc..0000000000 --- a/uk/guide/database-integration.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -layout: page -title: Інтеграція з базами даних Express -menu: guide -lang: uk ---- - -# Інтеграція з базами даних - -Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app: - -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) - -
      -These database drivers are among many that are available. For other options, -search on the [npm](https://www.npmjs.com/) site. -
      - - - -## Cassandra - -**Module**: [cassandra-driver](https://github.com/datastax/nodejs-driver) -**Installation** - -
      
      -$ npm install cassandra-driver
      -
      - -**Example** - -
      
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      -
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      - - - -## CouchDB - -**Module**: [nano](https://github.com/dscape/nano) -**Installation** - -
      
      -$ npm install nano
      -
      - -**Example** - -
      
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      -
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      -  }
      -});
      -
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      - - - -## LevelDB - -**Module**: [levelup](https://github.com/rvagg/node-levelup) -**Installation** - -
      
      -$ npm install level levelup leveldown
      -
      - -**Example** - -
      
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      -
      -db.put('name', 'LevelUP', function (err) {
      -
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      -
      -});
      -
      - - - -## MySQL - -**Module**: [mysql](https://github.com/felixge/node-mysql/) -**Installation** - -
      
      -$ npm install mysql
      -
      - -**Example** - -
      
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      -
      -connection.connect();
      -
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      -
      -connection.end();
      -
      - - - -## MongoDB - -**Module**: [mongodb](https://github.com/mongodb/node-mongodb-native) -**Installation** - -
      
      -$ npm install mongodb
      -
      - -**Example** - -
      
      -var MongoClient = require('mongodb').MongoClient;
      -
      -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
      -  if (err) {
      -    throw err;
      -  }
      -  db.collection('mammals').find().toArray(function(err, result) {
      -    if (err) {
      -      throw err;
      -    }
      -    console.log(result);
      -  });
      -});
      -
      - -If you want an object model driver for MongoDB, look at [Mongoose](https://github.com/LearnBoost/mongoose). - - - -## Neo4j - -**Module**: [apoc](https://github.com/hacksparrow/apoc) -**Installation** - -
      
      -$ npm install apoc
      -
      - -**Example** - -
      
      -var apoc = require('apoc');
      -
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      -  }
      -);
      -
      - - - -## PostgreSQL - -**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise) -**Installation** - -
      
      -$ npm install pg-promise
      -
      - -**Example** - -
      
      -var pgp = require("pg-promise")(/*options*/);
      -var db = pgp("postgres://username:password@host:port/database");
      -
      -db.one("SELECT $1 AS value", 123)
      -    .then(function (data) {
      -        console.log("DATA:", data.value);
      -    })
      -    .catch(function (error) {
      -        console.log("ERROR:", error);
      -    });
      -
      - - - -## Redis - -**Module**: [redis](https://github.com/mranney/node_redis) -**Installation** - -
      
      -$ npm install redis
      -
      - -**Example** - -
      
      -var client = require('redis').createClient();
      -
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      -
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      -
      -client.hkeys('hash key', function (err, replies) {
      -
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      -
      -  client.quit();
      -
      -});
      -
      - - - -## SQLite - -**Module**: [sqlite3](https://github.com/mapbox/node-sqlite3) -**Installation** - -
      
      -$ npm install sqlite3
      -
      - -**Example** - -
      
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      -
      -db.serialize(function() {
      -
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      -
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      -  }
      -
      -  stmt.finalize();
      -
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      -
      -db.close();
      -
      - - - -## ElasticSearch - -**Module**: [elasticsearch](https://github.com/elastic/elasticsearch-js) -**Installation** - -
      
      -$ npm install elasticsearch
      -
      - -**Example** - -
      
      -var elasticsearch = require('elasticsearch');
      -var client = elasticsearch.Client({
      -  host: 'localhost:9200'
      -});
      -
      -client.search({
      -  index: 'books',
      -  type: 'book',
      -  body: {
      -    query: {
      -      multi_match: {
      -        query: 'express js',
      -        fields: ['title', 'description']
      -      }
      -    }
      -  }
      -}).then(function(response) {
      -  var hits = response.hits.hits;
      -}, function(error) {
      -  console.trace(error.message);
      -});
      -
      diff --git a/uk/guide/debugging.md b/uk/guide/debugging.md deleted file mode 100755 index 0e3a12015e..0000000000 --- a/uk/guide/debugging.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -layout: page -title: Зневадження в Express -menu: guide -lang: uk ---- - -# Зневадження в Express - -Express uses the [debug](https://www.npmjs.com/package/debug) module -internally to log information about route matches, middleware functions that are in use, application mode, -and the flow of the request-response cycle. - -
      -`debug` is like an augmented version of `console.log`, but unlike `console.log`, you don't have to -comment out `debug` logs in production code. Logging is turned off by default and can be conditionally turned on by using the `DEBUG` environment variable. -
      - -To see all the internal logs used in Express, set the `DEBUG` environment variable to -`express:*` when launching your app. - -
      
      -$ DEBUG=express:* node index.js
      -
      - -On Windows, use the corresponding command. - -
      
      -> set DEBUG=express:* & node index.js
      -
      - -Running this command on the default app generated by the [express generator](/{{ page.lang }}/starter/generator.html) prints the following output: - -
      
      -$ 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 / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      -  express:router:layer new / +0ms
      -
      - -When a request is then made to the app, you will see the logs specified in the Express code: - -
      
      -  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
      -
      - -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` - -An application generated by the `express` command also uses the `debug` module and its debug namespace is scoped to the name of the application. - -For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: - -
      
      -$ DEBUG=sample-app:* node ./bin/www
      -
      - -You can specify more than one debug namespace by assigning a comma-separated list of names: - -
      
      -$ DEBUG=http,mail,express:* node index.js
      -
      - -For more information about `debug`, see the [debug](https://www.npmjs.com/package/debug). diff --git a/uk/guide/error-handling.md b/uk/guide/error-handling.md deleted file mode 100755 index 85c9cd56a5..0000000000 --- a/uk/guide/error-handling.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -layout: page -title: Обробка помилок в Express -menu: guide -lang: uk ---- - -# Обробка помилок - -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)`. For example: - -
      
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      - -You define error-handling middleware last, after other `app.use()` and routes calls; for example: - -
      
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      -  // logic
      -});
      -
      - -Responses from within a middleware function can be in any format that you prefer, such as an HTML error page, a simple message, or a JSON string. - -For organizational (and higher-level framework) purposes, you can define -several error-handling middleware functions, much like you would with -regular middleware functions. For example, if you wanted to define an error-handler -for requests made by using `XHR`, and those without, you might use the following commands: - -
      
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      - -In this example, the generic `logErrors` might write request and -error information to `stderr`, for example: - -
      
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      - -Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one: - -
      
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      -  } else {
      -    next(err);
      -  }
      -}
      -
      - -The "catch-all" `errorHandler` function might be implemented as follows: - -
      
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      - -If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being in error and will skip any remaining non-error handling routing and middleware functions. If you want to handle that error in some way, you'll have to create an error-handling route as described in the next section. - -If you have a route handler with multiple callback functions you can use the `route` parameter to skip to the next route handler. For example: - -
      
      -app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      -
      -      // continue handling this request
      -      next('route');
      -    }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      - -In this example, the `getPaidContent` handler will be skipped but any remaining handlers in `app` for `/a_route_behind_paywall` would continue to be executed. - -
      -Calls to `next()` and `next(err)` indicate that the current handler is complete and in what state. `next(err)` will skip all remaining handlers in the chain except for those that are set up to handle errors as described above. -
      - -## The Default Error Handler - -Express comes with an in-built error handler, which takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack. - -If you pass an error to `next()` and you do not handle it in -an error handler, it will be handled by the built-in error handler; the error will be written to the client with the -stack trace. The stack trace is not included in the production environment. - -
      -Set the environment variable `NODE_ENV` to `production`, to run the app in production mode. -
      - -If you call `next()` with an error after you have started writing the -response (for example, if you encounter an error while streaming the -response to the client) the Express default error handler closes the -connection and fails the request. - -So when you add a custom error handler, you will want to delegate to -the default error handling mechanisms in Express, when the headers -have already been sent to the client: - -
      
      -function errorHandler(err, req, res, next) {
      -  if (res.headersSent) {
      -    return next(err);
      -  }
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      diff --git a/uk/guide/migrating-4.md b/uk/guide/migrating-4.md deleted file mode 100755 index 039a4caab5..0000000000 --- a/uk/guide/migrating-4.md +++ /dev/null @@ -1,600 +0,0 @@ ---- -layout: page -title: Перехід на Express 4 -menu: guide -lang: uk ---- - -# Перехід на Express 4 - -

      Overview

      - -Express 4 is a breaking change from Express 3, so. That means an existing Express 3 app will not work if you update the Express version in its dependencies. - -This article covers: - - - -

      Changes in Express 4

      - -There are several significant changes in Express 4: - - - -See also: - -* [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) - -

      -Changes to Express core and middleware system -

      - -Express 4 no longer depends on Connect, and removes all built-in -middleware from its core, except for the `express.static` function. This means that -Express is now an independent routing and middleware web framework, and -Express versioning and releases are not affected by middleware updates. - -Without built-in middleware, you must explicitly add all the -middleware that is required to run your app. Simply follow these steps: - -1. Install the module: `npm install --save ` -2. In your app, require the module: `require('module-name')` -3. Use the module according to its documentation: `app.use( ... )` - -The following table lists Express 3 middleware and their counterparts in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Express 3Express 4
      express.bodyParserbody-parser + -multer
      express.compresscompression
      express.cookieSessioncookie-session
      express.cookieParsercookie-parser
      express.loggermorgan
      express.sessionexpress-session
      express.faviconserve-favicon
      express.responseTimeresponse-time
      express.errorHandlererrorhandler
      express.methodOverridemethod-override
      express.timeoutconnect-timeout
      express.vhostvhost
      express.csrfcsurf
      express.directoryserve-index
      express.staticserve-static
      - -Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. - -In most cases, you can simply replace the old version 3 middleware with -its Express 4 counterpart. For details, see the module documentation in -GitHub. - -

      app.use accepts parameters

      - -In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler. -For example: - -
      
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -});
      -
      -

      -The routing system -

      - -Apps now implicitly load routing middleware, so you no longer have to -worry about the order in which middleware is loaded with respect to -the `router` middleware. - -The way you define routes is unchanged, but the routing system has two -new features to help organize your routes: - -{: .doclist } -* A new method, `app.route()`, to create chainable route handlers for a route path. -* A new class, `express.Router`, to create modular mountable route handlers. - -

      app.route() method

      - -The new `app.route()` method enables you to create chainable route handlers -for a route path. Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more -information about routes, see [`Router()` documentation](/{{ page.lang }}/4x/api.html#router). - -Here is an example of chained route handlers that are defined by using the `app.route()` function. - -
      
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      - -

      express.Router class

      - -The other feature that helps to organize routes is a new class, -`express.Router`, that you can use 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 middleware in -it, defines some routes, and mounts it on a path on the main app. - -For example, create a router file named `birds.js` in the app directory, -with the following content: - -
      
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      -
      -module.exports = router;
      -
      - -Then, load the router module in the app: - -
      
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      - -The app will now be able to handle requests to the `/birds` and -`/birds/about` paths, and will call the `timeLog` -middleware that is specific to the route. - -

      -Other changes -

      - -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. -
      - -

      Example app migration

      - -Here is an example of migrating an Express 3 application to Express 4. -The files of interest are `app.js` and `package.json`. - -

      -Version 3 app -

      - -

      app.js

      - -Consider an Express v.3 application with the following `app.js` file: - -
      
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -// development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      -}
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      - -

      package.json

      - -The accompanying version 3 `package.json` file might look - something like this: - -
      
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "express": "3.12.0",
      -    "pug": "*"
      -  }
      -}
      -
      - -

      -Process -

      - -Begin the migration process by installing the required middleware for the -Express 4 app and updating Express and Pug to their respective latest -version with the following command: - -
      
      -$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      - -Make the following changes to `app.js`: - -1. The built-in Express middleware functions `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` and - `express.errorHandler` are no longer available on the - `express` object. You must install their alternatives - manually and load them in the app. - -2. You no longer need to load the `app.router` function. - It is not a valid Express 4 app object, so remove the - `app.use(app.router);` code. - -3. Make sure that the middleware functions are loaded in the correct order - load `errorHandler` after loading the app routes. - -

      Version 4 app

      - -

      package.json

      - -Running the above `npm` command will update `package.json` as follows: - -
      
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "body-parser": "^1.5.2",
      -    "errorhandler": "^1.1.1",
      -    "express": "^4.8.0",
      -    "express-session": "^1.7.2",
      -    "pug": "^2.0.0-beta6",
      -    "method-override": "^2.1.2",
      -    "morgan": "^1.2.2",
      -    "multer": "^0.1.3",
      -    "serve-favicon": "^2.0.1"
      -  }
      -}
      -
      - -

      app.js

      - -Then, remove invalid code, load the required middleware, and make other -changes as necessary. The `app.js` file will look like this: - -
      
      -var http = require('http');
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      -
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -// error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      -}
      -
      -var server = http.createServer(app);
      -server.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      - -
      -Unless you need to work directly with the `http` module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way: -
      app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      - -

      Run the app

      - -The migration process is complete, and the app is now an -Express 4 app. To confirm, start the app by using the following command: - -
      
      -$ node .
      -
      - -Load [http://localhost:3000](http://localhost:3000) - and see the home page being rendered by Express 4. - -

      Upgrading to the Express 4 app generator

      - -The command-line tool to generate an Express app is still - `express`, but to upgrade to the new version, you must uninstall - the Express 3 app generator and then install the new - `express-generator`. - -

      Installing

      - -If you already have the Express 3 app generator installed on your system, -you must uninstall it: - -
      
      -$ npm uninstall -g express
      -
      -Depending on how your file and directory privileges are configured, -you might need to run this command with `sudo`. - -Now install the new generator: - -
      
      -$ npm install -g express-generator
      -
      - -Depending on how your file and directory privileges are configured, -you might need to run this command with `sudo`. - -Now the `express` command on your system is updated to the -Express 4 generator. - -

      Changes to the app generator

      - -Command options and use largely remain the same, with the following exceptions: - -{: .doclist } -* Removed the `--sessions` option. -* Removed the `--jshtml` option. -* Added the `--hogan` option to support [Hogan.js](http://twitter.github.io/hogan.js/). - -

      Example

      - -Execute the following command to create an Express 4 app: - -
      
      -$ express app4
      -
      - -If you look at the contents of the `app4/app.js` file, you will notice -that all the middleware functions (except `express.static`) that are required for -the app are loaded as independent modules, and the `router` middleware -is no longer explicitly loaded in the app. - -You will also notice that the `app.js` file is now a Node.js module, in contrast to the standalone app that was generated by the old generator. - -After installing the dependencies, start the app by using the following command: - -
      
      -$ npm start
      -
      - -If you look at the npm start script in the `package.json` file, -you will notice that the actual command that starts the app is -`node ./bin/www`, which used to be `node app.js` -in Express 3. - -Because the `app.js` file that was generated by the Express 4 generator -is now a Node.js module, it can no longer be started independently as an app -(unless you modify the code). The module must be loaded in a Node.js file -and started via the Node.js file. The Node.js file is `./bin/www` -in this case. - -Neither the `bin` directory nor the extensionless `www` -file is mandatory for creating an Express app or starting the app. They are -just suggestions made by the generator, so feel free to modify them to suit your -needs. - -To get rid of the `www` directory and keep things the "Express 3 way", -delete the line that says `module.exports = app;` at the end of the -`app.js` file, then paste the following code in its place: - -
      
      -app.set('port', process.env.PORT || 3000);
      -
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      - -Ensure that you load the `debug` module at the top of the `app.js` file by using the following code: - -
      
      -var debug = require('debug')('app4');
      -
      - -Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`. - -You have now moved the functionality of `./bin/www` back to -`app.js`. This change is not recommended, but the exercise helps you -to understand how the `./bin/www` file works, and why the `app.js` file -no longer starts on its own. diff --git a/uk/guide/migrating-5.md b/uk/guide/migrating-5.md deleted file mode 100755 index dc9968d8d7..0000000000 --- a/uk/guide/migrating-5.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -layout: page -title: Перехід на Express 5 -menu: guide -lang: uk ---- - -# Перехід на Express 5 - -

      Overview

      - -Express 5.0 is still in the alpha release stage, but here is a preview of the changes that will be in the release and how to migrate your Express 4 app to Express 5. - -Express 5 is not very different from Express 4: The changes to the API are not as significant as from 3.0 to 4.0. Although the basic API remains the same, there are still breaking changes; in other words an existing Express 4 program might not work if you update it to use Express 5. - -To install the latest alpha and to preview Express 5, enter the following command in your application root directory: - -
      
      -$ npm install express@5.0.0-alpha.2 --save
      -
      - -You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported. - -

      Changes in Express 5

      - -Here is the list of changes (as of the alpha 2 release ) that will affect you as a user of Express. -See the [pull request](https://github.com/expressjs/express/pull/2237) for a list of all the planned features. - -**Removed methods and properties** - - - -**Changed** - - - -**Improvements** - - - -

      Removed methods and properties

      - -If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5. - -

      app.del()

      - -Express 5 no longer supports the `app.del()` function. If you use this function an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. - -Initially `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. - -

      app.param(fn)

      - -The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. - -

      Pluralized method names

      - -The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: - -`req.acceptsCharset()` is replaced by `req.acceptsCharsets()`. - -`req.acceptsEncoding()` is replaced by `req.acceptsEncodings()`. - -`req.acceptsLanguage()` is replaced by `req.acceptsLanguages()`. - -

      Leading colon (:) in the name for app.param(name, fn)

      - -A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon. - -This should not affect your code if you follow the Express 4 documentation of [app.param](/{{ page.lang }}/4x/api.html#app.param), as it makes no mention of the leading colon. - -

      req.param(name)

      - -This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object. - -

      res.json(obj, status)

      - -Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`. - -

      res.jsonp(obj, status)

      - -Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`. - -

      res.send(body, status)

      - -Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. - -

      res.send(status)

      - -Express 5 no longer supports the signature res.send(status), where _`status`_ is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. -If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature. - -

      res.sendfile()

      - -The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5. - -

      Changed

      - -

      app.router

      - -The `app.router` object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. - -

      req.host

      - -In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5 the port number is maintained. - -

      req.query

      - -In Express 4.7 and Express 5 onwards, the query parser option can accept `false` to disable query string parsing when you want to use your own function for query string parsing logic. - -

      Improvements

      - -

      res.render()

      - -This method now enforces asynchronous behavior for all view engines, avoiding bugs caused by view engines that had a synchronous implementation and that violated the recommended interface. diff --git a/uk/guide/routing.md b/uk/guide/routing.md deleted file mode 100755 index 849a6b1cd1..0000000000 --- a/uk/guide/routing.md +++ /dev/null @@ -1,294 +0,0 @@ ---- -layout: page -title: Маршрутизація Express -menu: guide -lang: uk ---- - -# Маршрутизація - -_Routing_ refers to the definition of application end points (URIs) and how they respond to client requests. -For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/basic-routing.html). - -The following code is an example of a very basic route. - -
      
      -var express = require('express');
      -var app = express();
      -
      -// respond with "hello world" when a GET request is made to the homepage
      -app.get('/', function(req, res) {
      -  res.send('hello world');
      -});
      -
      - -

      Route methods

      - -A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class. - -The following code is an example of routes that are defined for the GET and the POST methods to the root of the app. - -
      
      -// GET method route
      -app.get('/', function (req, res) {
      -  res.send('GET request to the homepage');
      -});
      -
      -// POST method route
      -app.post('/', function (req, res) {
      -  res.send('POST request to the homepage');
      -});
      -
      - -Express supports the following routing methods that correspond to HTTP methods: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search`, and `connect`. - -
      -To route methods that translate to invalid JavaScript variable names, use the bracket notation. For example, -`app['m-search']('/', function ...` -
      - -There is a special routing method, `app.all()`, which is not derived from any HTTP method. This method is used for loading middleware functions at a path for all request methods. - -In the following example, the handler will be executed for requests to "/secret" whether you are using GET, POST, PUT, DELETE, or any other HTTP request method that is supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). - -
      
      -app.all('/secret', function (req, res, next) {
      -  console.log('Accessing the secret section ...');
      -  next(); // pass control to the next handler
      -});
      -
      - -

      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. - -
      - Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) is a handy tool for testing basic Express routes, although it does not support pattern matching. -
      - -
      -Query strings are not part of the route path. -
      - -Here are some examples of route paths based on strings. - -This route path will match requests to the root route, `/`. - -
      
      -app.get('/', function (req, res) {
      -  res.send('root');
      -});
      -
      - -This route path will match requests to `/about`. - -
      
      -app.get('/about', function (req, res) {
      -  res.send('about');
      -});
      -
      - -This route path will match requests to `/random.text`. - -
      
      -app.get('/random.text', function (req, res) {
      -  res.send('random.text');
      -});
      -
      - -Here are some examples of route paths based on string patterns. - -This route path will match `acd` and `abcd`. - -
      
      -app.get('/ab?cd', function(req, res) {
      -  res.send('ab?cd');
      -});
      -
      - -This route path will match `abcd`, `abbcd`, `abbbcd`, and so on. - -
      
      -app.get('/ab+cd', function(req, res) {
      -  res.send('ab+cd');
      -});
      -
      - -This route path will match `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, and so on. - -
      
      -app.get('/ab*cd', function(req, res) {
      -  res.send('ab*cd');
      -});
      -
      - -This route path will match `/abe` and `/abcde`. - -
      
      -app.get('/ab(cd)?e', function(req, res) {
      - res.send('ab(cd)?e');
      -});
      -
      - -
      -The characters ?, +, *, and () are subsets of their regular expression counterparts. The hyphen (-) and the dot (.) are interpreted literally by string-based paths. -
      - -Examples of route paths based on regular expressions: - -This route path will match anything with an "a" in the route name. - -
      
      -app.get(/a/, function(req, res) {
      -  res.send('/a/');
      -});
      -
      - -This route path will match `butterfly` and `dragonfly`, but not `butterflyman`, `dragonfly man`, and so on. - -
      
      -app.get(/.*fly$/, function(req, res) {
      -  res.send('/.*fly$/');
      -});
      -
      - -

      Route handlers

      - -You can provide multiple callback functions that behave like [middleware](/{{ page.lang }}/guide/using-middleware.html) 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. - -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: - -
      
      -app.get('/example/a', function (req, res) {
      -  res.send('Hello from A!');
      -});
      -
      - -More than one callback function can handle a route (make sure you specify the `next` object). For example: - -
      
      -app.get('/example/b', function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from B!');
      -});
      -
      - -An array of callback functions can handle a route. For example: - -
      
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      -}
      -
      -var cb2 = function (req, res) {
      -  res.send('Hello from C!');
      -}
      -
      -app.get('/example/c', [cb0, cb1, cb2]);
      -
      - -A combination of independent functions and arrays of functions can handle a route. For example: - -
      
      -var cb0 = function (req, res, next) {
      -  console.log('CB0');
      -  next();
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1');
      -  next();
      -}
      -
      -app.get('/example/d', [cb0, cb1], function (req, res, next) {
      -  console.log('the response will be sent by the next function ...');
      -  next();
      -}, function (req, res) {
      -  res.send('Hello from D!');
      -});
      -
      - -

      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. - -| Method | Description -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Prompt a file to be downloaded. -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | End the response process. -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Send a JSON response. -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Send a JSON response with JSONP support. -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirect a request. -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Render a view template. -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Send a response of various types. -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Send a file as an octet stream. -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. - -

      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](/{{ page.lang }}/4x/api.html#router). - -Here is an example of chained route handlers that are defined by using `app.route()`. - -
      
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      - -

      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". - -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 the following content: - -
      
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware that is specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      -
      -module.exports = router;
      -
      - -Then, load the router module in the app: - -
      
      -var birds = require('./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. diff --git a/uk/guide/using-middleware.md b/uk/guide/using-middleware.md deleted file mode 100644 index 67d6e4d56c..0000000000 --- a/uk/guide/using-middleware.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -layout: page -title: Використання проміжних обробників Express -menu: guide -lang: uk ---- - -# Використання проміжних обробників - -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. - -_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/4x/api.html#req) (`req`), the [response object](/{{ page.lang }}/4x/api.html#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 can perform the following tasks: - -* Execute any code. -* Make changes to the request and the response objects. -* End the request-response cycle. -* Call the next middleware function in the stack. - -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. - -An Express application can use the following types of middleware: - - - [Application-level middleware](#middleware.application) - - [Router-level middleware](#middleware.router) - - [Error-handling middleware](#middleware.error-handling) - - [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. - -

      Application-level middleware

      - -Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/4x/api.html#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. - -This example shows a middleware function with no mount path. The function is executed every time the app receives a request. - -
      
      -var app = express();
      -
      -app.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      - -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. - -
      
      -app.use('/user/:id', function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      - -This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path. - -
      
      -app.get('/user/:id', function (req, res, next) {
      -  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. - -
      
      -app.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      - -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. - -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. - -
      
      -app.get('/user/:id', function (req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -}, function (req, res, next) {
      -  res.send('User Info');
      -});
      -
      -// handler for the /user/:id path, which prints the user ID
      -app.get('/user/:id', function (req, res, next) {
      -  res.end(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. -**NOTE**: `next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. - -This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. - -
      
      -app.get('/user/:id', function (req, res, next) {
      -  // if the user ID is 0, skip to the next route
      -  if (req.params.id == 0) next('route');
      -  // otherwise pass the control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for the /user/:id path, which renders a special page
      -app.get('/user/:id', function (req, res, next) {
      -  res.render('special');
      -});
      -
      - -

      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()`. - -
      
      -var 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: - -
      
      -var app = express();
      -var router = express.Router();
      -
      -// a middleware function with no mount path. This code is executed for every request to the router
      -router.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
      -router.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -// a middleware sub-stack that handles GET requests to the /user/:id path
      -router.get('/user/:id', function (req, res, next) {
      -  // if the user ID is 0, skip to the next router
      -  if (req.params.id == 0) next('route');
      -  // otherwise pass control to the next middleware function in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for the /user/:id path, which renders a special page
      -router.get('/user/:id', function (req, res, next) {
      -  console.log(req.params.id);
      -  res.render('special');
      -});
      -
      -// mount the router on the app
      -app.use('/', router);
      -
      - -

      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)`): - -
      
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      - -For details about error-handling middleware, see: [Error handling](/{{ page.lang }}/guide/error-handling.html). - -

      Built-in middleware

      - -Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). With the exception of `express.static`, all of the middleware -functions that were previously included with Express' are now in separate modules. Please view [the list of middleware functions](https://github.com/senchalabs/connect#middleware). - -The only built-in middleware function in Express is `express.static`. This function is based on [serve-static](https://github.com/expressjs/serve-static), and is responsible for serving static assets such as HTML files, images, and so on. - -The function signature is: -
      
      -express.static(root, [options])
      -
      - -The `root` argument specifies the root directory from which to serve static assets. - -For information on the `options` argument and more details on this middleware function, see [express.static](/en/4x/api.html#express.static). - -Here is an example of using the `express.static` middleware function with an elaborate options object: - -
      
      -var options = {
      -  dotfiles: 'ignore',
      -  etag: false,
      -  extensions: ['htm', 'html'],
      -  index: false,
      -  maxAge: '1d',
      -  redirect: false,
      -  setHeaders: function (res, path, stat) {
      -    res.set('x-timestamp', Date.now());
      -  }
      -}
      -
      -app.use(express.static('public', options));
      -
      - -You can have more than one static directory per app: - -
      
      -app.use(express.static('public'));
      -app.use(express.static('uploads'));
      -app.use(express.static('files'));
      -
      - -For more details about the `serve-static` function and its options, see: [serve-static](https://github.com/expressjs/serve-static) documentation. - -

      Third-party middleware

      - -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`. - -
      
      -$ npm install cookie-parser
      -
      - -
      
      -var express = require('express');
      -var app = express();
      -var cookieParser = require('cookie-parser');
      -
      -// load the cookie-parsing middleware
      -app.use(cookieParser());
      -
      - -For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](../resources/middleware.html). diff --git a/uk/guide/using-template-engines.md b/uk/guide/using-template-engines.md deleted file mode 100755 index 89fc6b4a8d..0000000000 --- a/uk/guide/using-template-engines.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -layout: page -title: Використання шаблонізаторів в Express -menu: guide -lang: uk ---- - -# Використання шаблонізаторів в Express - -A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces -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. - -Some popular template engines that work with Express are [Pug](https://pugjs.org/api/getting-started.html), -[Mustache](https://www.npmjs.com/package/mustache), and [EJS](https://www.npmjs.com/package/ejs). -The [Express application generator](/{{ page.lang }}/starter/generator.html) uses Pug as its default, but it also supports several others. - -See [Template Engines (Express wiki)](https://github.com/expressjs/express/wiki#template-engines) -for a list of template engines you can use with Express. -See also [Comparing JavaScript Templating Engines: Jade, Mustache, Dust and More](https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/). - -To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set): - -* `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: - -
      
      -$ npm install pug --save
      -
      - -
      -Express-compliant template engines such as Pug export a function named `__express(filePath, options, callback)`, -which is called by the `res.render()` function to render the template code. - -Some template engines do not follow this convention. The [Consolidate.js](https://www.npmjs.org/package/consolidate) -library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express. -
      - -After the view engine is set, you don't have to specify the engine or load the template engine module in your app; -Express loads the module internally, as shown below (for the above example). - -
      
      -app.set('view engine', 'pug');
      -
      - -Create a Pug template file named `index.pug` in the `views` directory, with the following content: - -
      
      -html
      -  head
      -    title= title
      -  body
      -    h1= message
      -
      - -Then create a route to render the `index.pug` file. If the `view engine` property is not set, -you must specify the extension of the `view` file. Otherwise, you can omit it. - -
      
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      - -When you make a request to the home page, the `index.pug` file will be rendered as HTML. - -To learn more about how template engines work in Express, see: -["Developing template engines for Express"](/{{ page.lang }}/advanced/developing-template-engines.html). diff --git a/uk/guide/writing-middleware.md b/uk/guide/writing-middleware.md deleted file mode 100755 index 2383074c52..0000000000 --- a/uk/guide/writing-middleware.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -layout: page -title: Створення проміжних обробників для використання у Express застосунках -menu: guide -lang: uk ---- - -# Створення проміжних обробників для використання у Express застосунках - -

      Overview

      - -_Middleware_ functions are functions that have access to the [request object](/4x/api.html#req) (`req`), the [response object](/4x/api.html#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 can perform the following tasks: - -* Execute any code. -* Make changes to the request and the response objects. -* End the request-response cycle. -* Call the next middleware in the stack. - -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. - -The following figure shows the elements of a middleware function call: - - - - -
      - - -
      HTTP method for which the middleware function applies.
      - -
      Path (route) for which the middleware function applies.
      - -
      The middleware function.
      - -
      Callback argument to the middleware function, called "next" by convention.
      - -
      HTTP response argument to the middleware function, called "res" by convention.
      - -
      HTTP request argument to the middleware function, called "req" by convention.
      -
      - -

      Example

      - -Here is an example of a simple "Hello World" Express application. -The remainder of this article will define and add two middleware functions to the application: -one called `myLogger` that prints a simple log message and another called `requestTime` that -displays the timestamp of the HTTP request. - -
      
      -var express = require('express');
      -var app = express();
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -app.listen(3000);
      -
      - -

      Middleware function myLogger

      -Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. The middleware function is assigned to a variable named `myLogger`. - -
      
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      -
      - -
      -Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. -The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next". -To avoid confusion, always use this convention. -
      - -To load the middleware function, call `app.use()`, specifying the middleware function. -For example, the following code loads the `myLogger` middleware function before the route to the root path (/). - -
      
      -var express = require('express');
      -var app = express();
      -
      -var myLogger = function (req, res, next) {
      -  console.log('LOGGED');
      -  next();
      -};
      -
      -app.use(myLogger);
      -
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      -app.listen(3000);
      -
      - -Every time the app receives a request, it prints the message "LOGGED" to the terminal. - -The order of middleware loading is important: middleware functions that are loaded first are also executed first. - -If `myLogger` is loaded after the route to the root path, the request never reaches it and the app doesn't print "LOGGED", because the route handler of the root path terminates the request-response cycle. - -The middleware function `myLogger` simply prints a message, then passes on the request to the next middleware function in the stack by calling the `next()` function. - -

      Middleware function requestTime

      - -Next, we'll create a middleware function called "requestTime" and add it as a property called `requestTime` -to the request object. - -
      
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      -
      - -The app now uses the `requestTime` middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to `req` (the request object). - -
      
      -var express = require('express');
      -var app = express();
      -
      -var requestTime = function (req, res, next) {
      -  req.requestTime = Date.now();
      -  next();
      -};
      -
      -app.use(requestTime);
      -
      -app.get('/', function (req, res) {
      -  var responseText = 'Hello World!
      '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); - -app.listen(3000); -
      - -When you make a request to the root of the app, the app now displays the timestamp of your request in the browser. - -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. - -For more information about Express middleware, see: [Using Express middleware](/guide/using-middleware.html). diff --git a/uk/index.md b/uk/index.md deleted file mode 100644 index 2f35c1f2b4..0000000000 --- a/uk/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -layout: home -title: Express - це фреймворк для веб-застосунків, побудованих на Node.js -menu: home -lang: uk ---- -
      - {% include header/header-{{ page.lang }}.html %} -
      -
      -
      - - Швидкий, гнучкий, мінімалістичний фреймворк для веб-застосунків, побудованих на Node.js -
      -
      $ npm install express --save
      -
      -
      - -
      -
      - -
      - -
      -
      -

      Веб-застосунки

      Express - це мінімалістичний та гнучкий фреймворк для веб-застосунків, побудованих на Node.js, що надає широкий набір функціональності. -
      - -
      -

      API

      Маючи в свому розпорядженні безліч допоміжних HTTP-методів та проміжних обробників, створювати надійні API можна легко і швидко. -
      - -
      -

      Продуктивність

      Express забезпечує тонкий прошарок базової функціональності для веб-застосунків, що не спотворює звичну та зручну функціональність Node.js. -
      - -
      -

      Фреймворки

      Багато популярних фреймворків грунтуються на Express. -
      -
      - -
      - - diff --git a/uk/resources/community.md b/uk/resources/community.md deleted file mode 100755 index b6b1db1e1f..0000000000 --- a/uk/resources/community.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -layout: page -title: Спільнота Express -menu: resources -lang: uk ---- - -# Спільнота - -## Mailing List - -Join over 2000 Express users or browse over 5000 -discussions in the [Google Group](https://groups.google.com/group/express-js). - -## Gitter - -The [expressjs/express chatroom](https://gitter.im/expressjs/express) is great place -for developers interested in the everyday discussions related to Express. - -## IRC Channel - -Hundreds of developers idle in #express on freenode every day. -If you have questions about the framework, jump in for quick -feedback. - -## Examples - -View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples) -in the repository covering everything from API design and authentication -to template engine integration. - -## Issues - -If you've come across what you think is a bug, or just want to make -a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues). - -## Third Party - -Our vibrant community has created a large variety of extensions, -[middleware modules](/{{ page.lang }}/resources/middleware.html) and higher level frameworks. Check them out in the -[wiki](https://github.com/expressjs/express/wiki). diff --git a/uk/resources/frameworks.md b/uk/resources/frameworks.md deleted file mode 100644 index b0bf786259..0000000000 --- a/uk/resources/frameworks.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -layout: page -title: Фреймворки, що використовують Express -menu: frameworks -lang: uk ---- - -# Фреймворки, що використовують Express - -Several popular Node.js frameworks are built on Express: - -- **[LoopBack](http://loopback.io)**: Highly-extensible, open-source Node.js framework for quickly creating dynamic end-to-end REST APIs. -- **[Sails](http://sailsjs.org/)**: MVC framework for Node.js for building practical, production-ready apps. -- **[Kraken](http://krakenjs.com/)**: Secure and scalable layer that extends Express by providing structure and convention. -- **[MEAN](http://mean.io/)**: Opinionated fullstack JavaScript framework that simplifies and accelerates web application development. diff --git a/uk/resources/glossary.md b/uk/resources/glossary.md deleted file mode 100755 index cf92c4ba00..0000000000 --- a/uk/resources/glossary.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -layout: page -title: Голосарій Express -menu: resources -lang: uk ---- - -# Голосарій - -### застосунок - -In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/{{ page.lang }}/api.html#express). - -### API - -Application programming interface. Spell out the abbreviation when it is first used. - -### Express - -A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable. - -### libuv - -A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js. - -### middleware - -A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: - - * `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware. - * `app.use(mw)` is called _adding the middleware to the global processing stack_. - * `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_. - -### Node.js - -A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". - -### open-source, open source - -When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Note: Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. - -### request - -An HTTP request. A client submits an HTTP request message to a server, which returns a response. 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 - -An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body. - -### route - -Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route. - -### router - -See [router](/{{ page.lang }}/api.html#router) in the API reference. diff --git a/uk/resources/learning.md b/uk/resources/learning.md deleted file mode 100644 index 469d443b50..0000000000 --- a/uk/resources/learning.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: page -title: Додаткове навчання -menu: resources -lang: uk ---- - -# Додаткове навчання - -
      Disclaimer: Unendorsed community content.
      - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Baboon Blog: Express category](http://www.baboon.ir/tutorials/expressjs/) (Persian language) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/uk/resources/middleware.md b/uk/resources/middleware.md deleted file mode 100755 index 28a0213200..0000000000 --- a/uk/resources/middleware.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -layout: page -title: Проміжні обробники Express -menu: resources -lang: uk ---- - -# Проміжні обробники третій сторін - -Here are some Express middleware modules: - - - [body-parser](https://github.com/expressjs/body-parser): previously `express.bodyParser`, `json`, and `urlencoded`. - See also: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression): previously `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): Connect/Express middleware modules for optimal image serving. Switches images to `.webp` or `.jxr`, if possible. - - [connect-timeout](https://github.com/expressjs/timeout): previously `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): previously `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): previously `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): previously `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): previously `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): unobtrusive development tool that adds a tab with information about template variables (locals), current session, useful request data, and more to your application. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): Express middleware module for filtering-out parts of JSON responses based on the `fields` query-string; by using Google API's Partial Response. - - [express-session](https://github.com/expressjs/session): previously `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): Express middleware module for using a CDN for static assets, with multiple host support (For example: cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): Express middleware module for people who are strict about trailing slashes. - - [express-stormpath](https://github.com/stormpath/stormpath-express): Express middleware module for user storage, authentication, authorization, SSO, and data security. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): middleware module for redirecting HTTP requests containing uppercase to a canonical lowercase form. - - [helmet](https://github.com/helmetjs/helmet): module to help secure your apps by setting various HTTP headers. - - [join-io](https://github.com/coderaiser/join-io "join-io"): module for joining files on the fly to reduce the requests count. - - [method-override](https://github.com/expressjs/method-override): previously `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): previously `logger` - - [passport](https://github.com/jaredhanson/passport): Express middleware module for authentication. - - [response-time](https://github.com/expressjs/response-time): previously `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): previously `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): previously `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): module for serving static content. - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): fingerprinted URLs or Caching Headers for static assets including support for one or more external domains. - - [vhost](https://github.com/expressjs/vhost): previously `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): Express middleware module that provides common helper methods to the views. - - [sriracha-admin](https://github.com/hdngr/siracha): Express middleware module that dynamically generates an admin site for Mongoose. - -Some middleware modules previously included with Connect are no longer supported by the Connect/Express team. These modules are replaced by an alternative module, or should be superseded by a better module. Use one of the following alternatives: - - - express.cookieParser - - [cookies](https://github.com/jed/cookies) and [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) - -For more middleware modules, see: - - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) diff --git a/uk/starter/basic-routing.md b/uk/starter/basic-routing.md deleted file mode 100755 index f33fd5e62d..0000000000 --- a/uk/starter/basic-routing.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -layout: page -title: Базова маршрутизація Express -menu: starter -lang: uk ---- - -# Базова маршрутизація - -_Маршрутизація_ визначає: яку саме відповідь застосунок буде видавати клієнту, -коли від клієнта йде запит з використанням певного HTTP-методу (GET, POST, і т.д.) та по конкретному URI. - -Кожен маршрут може мати одну чи більше функцій-обробників, що виконуються, коли даний маршрут затверджено як співпадаючий. - -Визначення маршрутів має наступну структуру: -
      
      -app.METHOD(PATH, HANDLER)
      -
      - -Де: - -- `app` є екземпляром `express`. -- `METHOD` є [методом HTTP-запиту](https://uk.wikipedia.org/wiki/HTTP). -- `PATH` є шляхом на сервері. -- `HANDLER` є функцією-обробником, що спрацьовує, коли даний маршрут затверджено як співпадаючий. - -
      -В цьому керівництві припускається, що у вас вже створено та запущено екземпляр веб-сервера `express` і його передано у змінну з іменем `app`. -Якщо ви ще не вмієте створювати екземпляри застосунків та запускати їх, прогляньте [Приклад Hello world](/{{ page.lang }}/starter/hello-world.html). -
      - -В наступних прикладах продемонстровано визначення простих маршрутів. - -Визначення маршруту, що відповідає на GET-запити до головної сторінки, в результаті чого друкується `Hello World!`: - -
      
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -});
      -
      - -Визначення маршруту, що відповідає на POST-запити до кореневого маршруту (`/`), тобто до головної сторінки: - -
      
      -app.post('/', function (req, res) {
      -  res.send('Маємо POST-запит');
      -});
      -
      - -Визначення маршруту, що відповідає на PUT-запити до `/user`: - -
      
      -app.put('/user', function (req, res) {
      -  res.send('Маємо PUT-запит до /user');
      -});
      -
      - -Визначення маршруту, що відповідає на DELETE-запити до `/user`: - -
      
      -app.delete('/user', function (req, res) {
      -  res.send('Маємо DELETE-запит до /user');
      -});
      -
      - -Більш детально про маршрутизацію описано на сторінці [гід маршрутизації](/{{ page.lang }}/guide/routing.html). diff --git a/uk/starter/faq.md b/uk/starter/faq.md deleted file mode 100755 index a84849c7a2..0000000000 --- a/uk/starter/faq.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -layout: page -title: ЧАПи Express -menu: starter -lang: uk ---- - -# Часті Питання (ЧАПи) - -## Яку структуру я повинен використовувати для свого застосунку? - -Немає єдиної відповіді на дане питання. Все залежить від -розміру вашого застосунку та від команди, яка приймає участь у його розробці. Щоб бути на стільки гнучким, -на скільки це можливо, Express не спирається на фіксовану структуру. - -Маршрути та інша логіка застосунку може розміщуватись у файлах довільної кількості, -та поміщатись в каталоги будь-якої структури. Розгляньте наступні патерни проектування: - -* [Списки маршрутів](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [Карта маршрутів](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [MVC-стиль контролерів](https://github.com/expressjs/express/tree/master/examples/mvc) - -Також, існують сторонні розширення для Express, які спрощують деякі з перелічених патернів проектування: - -* [Ресурсна маршрутизація](https://github.com/expressjs/express-resource) - -## Як визначати моделі? - -В Express немає засобів для роботи з базою даних. Їх надають деякі сторонні модулі -Node.js, що дозволяють вам взаємодіяти практично з будь-якою базою даних. - -Ознайомтесь з [LoopBack](http://loopback.io) - цей фреймворк створено на базі Express, -він зорієнтований на роботу з моделями. - -## Яким чином можна ідентифікувати користувачів? - -Ідентифікація - це ще одна чутлива область, яку Express не ризикнув охопити. Ви можете використовувати будь-яку -схему ідентифікації. Проста схема "логін / пароль", представлена [в цьому прикладі](https://github.com/expressjs/express/tree/master/examples/auth). - - -## Які шаблонізатори підтримує Express? - -Express підтримує будь-які шаблонізатори, що узгоджуються з сигнатурою `(path, locals, callback)`. -Додаткову інформацію, стосовно нормалізації інтерфейсів шаблонізаторів та кешування, можна знайти в проекті -[consolidate.js](https://github.com/visionmedia/consolidate.js). Цей список може й не містити певних шаблонізаторів, -проте вони можуть все ж підтримувати сигнатуру Express. - -## Як можна обробляти 404-ті відповіді? - -В Express, 404-ті відповіді не генеруються в результаті помилок, а тому -проміжні обробники помилок не перехоплюють їх. Така поведінка існує оскільки 404-ту відповідь ми отримуємо -через відсутність відповідної функції в переліку проміжних обробників при маршрутизації. Все що треба зробити -в такому випадку, - це додати проміжну функцію в самий низ черги обробників, яка якраз і буде призначатись для -формування 404-тої відповіді: - -
      
      -app.use(function(req, res, next) {
      -  res.status(404).send('Вибачте, такої сторінки не існує!');
      -});
      -
      - -## Як можна встановити обробника помилок? - -Проміжні обробники помилок визначаються точно так само, як і інші проміжні обробники, -тільки передається до них чотири параметра, а не три; точніше, вони мають таку сигнатуру `(err, req, res, next)`: - -
      
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Щось поламалось!');
      -});
      -
      - -Більш детально, можна проглянути розділ [обробка помилок](/{{ page.lang }}/guide/error-handling.html). - -## Як можна відмальовувати простий код HTML? - -Не треба! Не потрібно "відмальовувати" HTML за допомогою функції `res.render()`. -Якщо ви маєте окремий файл, скористайтесь функцією `res.sendFile()`. -Якщо ви маєте великий набір файлів в певній директорії, використовуйте проміжну функцію `express.static()`. diff --git a/uk/starter/generator.md b/uk/starter/generator.md deleted file mode 100755 index 028bf8e4e0..0000000000 --- a/uk/starter/generator.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -layout: page -title: Генератор структури застосунків Express -menu: starter -lang: uk ---- - -# Генератор структури застосунків Express - -Можна використовувати інструмент `express-generator`, для швидкого створення каркасу застосунку. - -Встановлюється `express-generator` наступною командою: - -
      
      -$ npm install express-generator -g
      -
      - -З параметром `-h` можна проглянути доступні опції: - -
      
      -$ express -h
      -
      -  Usage: express [options] [dir]
      -
      -  Options:
      -
      -    -h, --help          output usage information
      -        --version       output the version number
      -    -e, --ejs           add ejs engine support
      -        --hbs           add handlebars engine support
      -        --pug           add pug engine support
      -    -H, --hogan         add hogan.js engine support
      -        --no-view       generate without view engine
      -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
      -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
      -        --git           add .gitignore
      -    -f, --force         force on non-empty directory
      -
      - -В наступному прикладі створюється каркас застосунку Express з іменем _myapp_ в поточній директорії: - -
      
      -$ express --view=pug myapp
      -
      -   create : myapp
      -   create : myapp/package.json
      -   create : myapp/app.js
      -   create : myapp/public
      -   create : myapp/public/javascripts
      -   create : myapp/public/images
      -   create : myapp/routes
      -   create : myapp/routes/index.js
      -   create : myapp/routes/users.js
      -   create : myapp/public/stylesheets
      -   create : myapp/public/stylesheets/style.css
      -   create : myapp/views
      -   create : myapp/views/index.pug
      -   create : myapp/views/layout.pug
      -   create : myapp/views/error.pug
      -   create : myapp/bin
      -   create : myapp/bin/www
      -
      - -Після чого треба встановити залежності: - -
      
      -$ cd myapp
      -$ npm install
      -
      - -На MacOS чи Linux, запустіть застосунок такою командою: - -
      
      -$ DEBUG=myapp:* npm start
      -
      - -На Windows, запускайте так: - -
      
      -> set DEBUG=myapp:* & npm start
      -
      - -Тепер вводьте в адресному рядку браузера `http://localhost:3000/`. - -Згенерований застосунок має наступну структуру директорій: - -
      
      -.
      -├── app.js
      -├── bin
      -│   └── www
      -├── package.json
      -├── public
      -│   ├── images
      -│   ├── javascripts
      -│   └── stylesheets
      -│       └── style.css
      -├── routes
      -│   ├── index.js
      -│   └── users.js
      -└── views
      -    ├── error.pug
      -    ├── index.pug
      -    └── layout.pug
      -
      -7 directories, 9 files
      -
      - -
      -Створена структура за допомогою генератора є лише однією із багатьох можливих варіантів структури застосунків Express. -Не обмежуйте себе лише такою структурою, змінюйте її під свої потреби. -
      diff --git a/uk/starter/hello-world.md b/uk/starter/hello-world.md deleted file mode 100755 index 424b5dcb9b..0000000000 --- a/uk/starter/hello-world.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: page -title: Приклад з "Hello World" в Express -menu: starter -lang: uk ---- - -# Приклад виводу "Hello world" - -
      -Далі показано дуже спрощений варіант створення застосунку Express. Тут використовується єдиний файл — тобто _не_ те, що ви отримуєте в результаті роботи [генератора Express](/{{ page.lang }}/starter/generator.html), який створює каркас для повноцінного, хоча й мінімалістичного застосунку, з декількома файлами JavaScript, шаблонами Jade, -та субдиректоріями для деяких потреб. -
      - -Для початку, створіть директорію з ім’ям `myapp`, перейдіть в неї та запустіть `npm init`. Потім встановіть `express` як залежність, -так як це показано в [керівництві встановлення](/{{ page.lang }}/starter/installing.html). - -В директорії `myapp`, створіть файл з ім’ям `app.js` та додайте наступний код: - -
      
      -var express = require('express');
      -var app = express();
      -
      -app.get('/', (req, res) => {
      -  res.send('Hello World!')
      -})
      -
      -app.listen(3000, () => {
      -  console.log('Приклад застосунку, який прослуховує 3000-ий порт!')
      -})
      -
      - -Цей скрипт запускає сервер та прослуховує з’єднання на 3000-му порті. В результаті виводиться "Hello World!", -коли запити адресуються до кореневого URL (`/`) або кореневого _маршруту_. Для усіх інших адрес формується відповідь **404 Not Found**. - -
      -Змінні `req` (request) та `res` (response) містять ті ж об’єкти, які надає Node.js, тобто ви можете викликати -`req.pipe()`, `req.on('data', callback)`, та виконувати будь-які інші дії без участі Express. -
      - -Запустіть застосунок наступною командою: - -
      
      -$ node app.js
      -
      - -Після чого, відкрийте браузер за адресою `http://localhost:3000/` щоб побачити результат. diff --git a/uk/starter/installing.md b/uk/starter/installing.md deleted file mode 100755 index 5fc18bcec0..0000000000 --- a/uk/starter/installing.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -layout: page -title: Встановлення Express -menu: starter -lang: uk ---- - -# Встановлення - -Припускаючи, що у вас вже встановлено [Node.js](https://nodejs.org/), створіть робочу директорію, де буде ваш застосунок: - -
      
      -$ mkdir myapp
      -$ cd myapp
      -
      - -Використовуйте команду `npm init` для створення файлу `package.json`. -Більш докладно про роботу `package.json` написано в [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). - -
      
      -$ npm init
      -
      - -Під час виконання цієї команди, у вас спитається про деякі моменти (ім’я та версія вашого застосунку і т.д.). -Ви можете просто натискати Enter, щоб приймати запропоновані початкові варіанти для більшості пунктів, за виключенням цього: - -
      
      -entry point: (index.js)
      -
      - -Введіть `app.js`, або будь-яке інше ім’я для головного файла. Якщо ви хочете залишити запропоноване ім’я `index.js`, -натискайте Enter. - -Тепер встановіть Express в новоствореній директорії та збережіть його в списку залежностей: - -
      
      -$ npm install express --save
      -
      - -Щоб встановити Express без додавання його в список залежностей, не передавайте параметр `--save`: - -
      
      -$ npm install express
      -
      - -
      -Модулі Node.js, встановлені з параметром `--save`, додаються до списку `залежностей` у файл `package.json`, що знаходиться в корені робочого каталогу. -Цей список використовується при запуску команди `npm install` щоб автоматично встановлювати вказані там модулі. -
      diff --git a/uk/starter/static-files.md b/uk/starter/static-files.md deleted file mode 100755 index 7fcf31c37b..0000000000 --- a/uk/starter/static-files.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -layout: page -title: Обробка статичних файлів в Express -menu: starter -lang: uk ---- - -# Обробка статичних файлів в Express - -Для обробки статичних файлів, таких як зображення, CSS файли, та JavaScript файли, використовуйте вбудовану у Express функцію `express.static`. - -Передайте ім'я директорії яка містить статичні файли у `express.static` щоб розпочати отримувати їх напряму. Наприклад, використовуйте цей код для того, щоб обробляти статичні файли у директорії з іменем `public`: - -
      
      -app.use(express.static('public'));
      -
      - -Тепер ви можете підключити файли з директорії `public`: - -
      
      -http://localhost:3000/images/kitten.jpg
      -http://localhost:3000/css/style.css
      -http://localhost:3000/js/app.js
      -http://localhost:3000/images/bg.png
      -http://localhost:3000/hello.html
      -
      - -
      -Express looks up the files relative to the static directory, so the name of the static directory is not part of the URL. -
      - -Щоб використовувати декілька директорій для статичних файлів, викличіть функцію `express.static` декілька разів: - -
      
      -app.use(express.static('public'));
      -app.use(express.static('files'));
      -
      - -Express шукає файли в тому порядку, в якому ви викликали функцію `express.static` та передали їй шлях до папки як аргумент. - -Щоб створити віртуальний префікс для шляху (якщо шлях насправді відсутній у файловій системі) для файлів які обробляються функцією `express.static`, [та встановити власний маршрут](/{{ page.lang }}/4x/api.html#app.use) зробіть як показано нище: - -
      
      -app.use('/static', express.static('public'));
      -
      - -Тепер ви можете підключити файли, які знаходяться у директорії `public` з використанням префіксу `/static`. - -
      
      -http://localhost:3000/static/images/kitten.jpg
      -http://localhost:3000/static/css/style.css
      -http://localhost:3000/static/js/app.js
      -http://localhost:3000/static/images/bg.png
      -http://localhost:3000/static/hello.html
      -
      - -Проте, шлях який ви передаєте у функцію `express.static` є відносним до директорії з якої ви запускаєте ваш `node` процес. Якщо ви запускаєете додаток з іншої директорії, більш безпечним є вказувати абсолютний шлях: - -
      
      -app.use('/static', express.static(__dirname + '/public'));
      -
      diff --git a/uz/3x/api.md b/uz/3x/api.md deleted file mode 100644 index e35a2a8c06..0000000000 --- a/uz/3x/api.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: 3x-api -title: Express 3.x - API Reference -menu: api -lang: uz ---- -
      - -
      - **Express 3.x support is ending soon** - - This series will continue to receive only security updates and bug fixes until July 2015. It is highly recommended to upgrade to Express 4.x. -
      - -

      3.x API

      - - - {% include api/en/3x/express.md %} - - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} - - - {% include api/en/3x/res.md %} - - - {% include api/en/3x/middleware.md %} - -
      diff --git a/uz/4x/api.md b/uz/4x/api.md deleted file mode 100644 index 0e96fda17a..0000000000 --- a/uz/4x/api.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API Reference -menu: api -lang: uz ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/uz/advanced/developing-template-engines.md b/uz/advanced/developing-template-engines.md deleted file mode 100644 index b0aa7459fa..0000000000 --- a/uz/advanced/developing-template-engines.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: page -title: Developing template engines for Express -menu: advanced -lang: uz ---- - -# Developing template engines for Express - -Use the `app.engine(ext, callback)` method to create your own template engine. `ext` refers to the file extension, `callback` is the template engine function which accepts the location of the file, the options object, and the callback function, as its parameters. - -The following is an example of implementing a very simple template engine for rendering ".ntl" files. - -
      
      -var fs = require('fs'); // this engine requires the fs module
      -app.engine('ntl', function (filePath, options, callback) { // define the template engine
      -  fs.readFile(filePath, function (err, content) {
      -    if (err) throw new Error(err);
      -    // this is an extremely simple template engine
      -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
      -    .replace('#message#', '

      '+ options.message +'

      '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
      - -Your app will now be able to render ".ntl" files. Create a file named "index.ntl" in the views directory with the following content. - -
      
      -#title#
      -#message#
      -
      -Then, create the following route in your app. - -
      
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -On making a request to the home page, "index.ntl" will be rendered as HTML. diff --git a/uz/advanced/performance.md b/uz/advanced/performance.md deleted file mode 100644 index 0095627c4c..0000000000 --- a/uz/advanced/performance.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: page -title: -lang: uz ---- - -# Performance diff --git a/uz/advanced/pm.md b/uz/advanced/pm.md deleted file mode 100644 index 2f94f9afd1..0000000000 --- a/uz/advanced/pm.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -layout: page -title: Process managers for Express apps -menu: advanced -lang: uz ---- - -# Process managers for Express apps - -When running Express apps for production, it is helpful to use a _process manager_ to: - -- Restart the app automatically if it crashes. -- Gain insights into runtime performance and resource consumption. -- Modify settings dynamically to improve performance. -- Control clustering. - -A process manager is somewhat like an application server: it's a "container" for applications that facilitates deployment, -provides high availability, and enables you to manage the application at runtime. - -The most popular process managers for Express and other Node applications are: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -Using any of these three tools can be very helpful, however StrongLoop Process Manager is the only solution that provides a comprehensive runtime and deployment solution that address entire Node application life cycle with tooling for every step before and after production in an unified interface. - -Here's a brief look at each of these tools. -For a detailed comparison, see [http://strong-pm.io/compare/](http://strong-pm.io/compare/). - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) is a production process manager for Node.js applications with built-in load balancing, monitoring, multi-host deployment, and a graphical console. -It enables you to: - -- Build, package, and deploy your Node application to a local or remote system. -- View CPU profiles and heap snapshots to optimize performance and diagnose memory leaks. -- Keep processes and clusters alive forever. -- View performance metrics on your application. -- Easily manage multi-host deployments with Nginx integration. -- Unify multiple StrongLoop PMs to a distributed microservices runtime managed from Arc. - -You can work with StrongLoop PM using a powerful CLI tool, `slc`, or a graphical tool, Arc. It's open source, with professional support provided by StrongLoop. - -For more information, see [http://strong-pm.io/](http://strong-pm.io/). - -Full documentation: - -- [Operating Node apps (StrongLoop documentation)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### Installation -
      
      -$ [sudo] npm install -g strongloop
      -
      - -### Basic use -
      
      -$ cd my-app
      -$ slc start
      -
      - -View status of Process Manager and all deployed apps: - -
      
      -$ slc ctl
      -Service ID: 1
      -Service Name: my-app
      -Environment variables:
      -  No environment variables defined
      -Instances:
      -    Version  Agent version  Cluster size
      -     4.1.13      1.5.14           4
      -Processes:
      -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
      -    1.1.57692  57692   0
      -    1.1.57693  57693   1     0.0.0.0:3001
      -    1.1.57694  57694   2     0.0.0.0:3001
      -    1.1.57695  57695   3     0.0.0.0:3001
      -    1.1.57696  57696   4     0.0.0.0:3001
      -
      - -List all apps (services) under management: - -
      
      -$ slc ctl ls
      -Id          Name         Scale
      - 1          my-app       1
      -
      - -Stop an app: - -
      
      -$ slc ctl stop my-app
      -
      - -Restart an app: - -
      
      -$ slc ctl restart my-app
      -
      - -You can also "soft restart," which gives worker processes a grace period to close existing connections, then restarts the current application: - -
      
      -$ slc ctl soft-restart my-app
      -
      - -To remove an app from management: - -
      
      -$ slc ctl remove my-app
      -
      - -## PM2 - -PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and will facilitate common system admin tasks. It also enables you to manage application logging, monitoring, and clustering. - -For more information, see [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2). - -### Installation - -
      
      -$ [sudo] npm install pm2 -g
      -
      - -### Basic use - -Starting an app with `pm2` requires the path of the app to be specified. However, stopping, restarting, and deleting requires just the name or the id of the app. - -
      
      -$ pm2 start npm --name my-app -- start
      -[PM2] restartProcessId process id 0
      -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
      -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
      -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
      -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
      -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
      - Use `pm2 show ` to get more details about an app
      -
      - -Starting an app with `pm2` will immediately send it to the background. You can control the background app from the command line using various `pm2` commands. - -Once an app is started with `pm2` it is registered in `pm2`'s list of processes with an ID, which makes it possible to manage apps with the same name from different directories on the system, using their IDs. - -Note that if more than one app with the same name is running, `pm2` commands affect all of them. So use IDs instead of names to manage individual apps. - -List all running processes: - -
      
      -$ pm2 list
      -
      - -Stop an app: - -
      
      -$ pm2 stop 0
      -
      - -Restart an app: - -
      
      -$ pm2 restart 0
      -
      - -To view detailed information about an app: - -
      
      -$ pm2 show 0
      -
      - -To remove an app from `pm2`'s registry: - -
      
      -$ pm2 delete 0
      -
      - - -## Forever - -Forever is a simple CLI tool for ensuring that a given script runs continuously (forever). Its simple interface makes it ideal for running smaller deployments of Node apps and scripts. - -For more information, see [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever). - -### Installation - -
      
      -$ [sudo] npm install forever -g
      -
      - -### Basic use - -To start a script, use the `forever start` command and specify the path of the script: - -
      
      -$ forever start script.js
      -
      - -This will run the script in daemon mode (in the background). - -To run the script attached to the terminal, omit `start`: - -
      
      -$ forever script.js
      -
      - -It is a good idea to log output from forever and the script using the logging options `-l`, `-o`, `-e`, as shown this example: - -
      
      -$ forever start -l forever.log -o out.log -e err.log script.js
      -
      - -To view the list of scripts started by forever: - -
      
      -$ forever list
      -
      - -To stop a script started by forever use the `forever stop` command and specify the process index (as listed by the `forever list` command). - -
      
      -$ forever stop 1
      -
      - -Alternatively, specify the path of the file: - -
      
      -$ forever stop script.js
      -
      - -To stop all the scripts started by `forever`: - -
      
      -$ forever stopall
      -
      - -Forever has many more options, and it also provides a programmatic API. diff --git a/uz/advanced/security-updates.md b/uz/advanced/security-updates.md deleted file mode 100644 index 0704cbec1c..0000000000 --- a/uz/advanced/security-updates.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -layout: page -title: Express security updates -menu: advanced -lang: uz ---- - -# Security updates - -
      -Node.js vulnerabilities directly affect Express. Therefore [keep a watch on Node vulnerabilities](http://blog.nodejs.org/vulnerability/) and make sure you are using the latest stable version of Node. -
      - -The list below enumerates the Express vulnerabilities that were fixed in the specified version update. - -## 4.x - - * 4.11.1 - * Fixed root path disclosure vulnerability in express.static, res.sendfile, and res.sendFile - * 4.10.7 - * Fixed open redirect vulnerability in express.static (advisory (https://npmjs.com/advisories/35), CVE-2015-1164 (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) - * 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 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually leak to `EMFILE` errors and server unresponsiveness. - * 4.8.0 - * Sparse arrays with extremely high indexes in query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - -## 3.x - - * 3.19.1 - * Fixed root path disclosure vulnerability in express.static, res.sendfile, and res.sendFile - * 3.19.0 - * Fixed open redirect vulnerability in express.static (advisory (https://npmjs.com/advisories/35), CVE-2015-1164 (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)) - * 3.16.10 - * Fixed directory traversal vulnerabilities in `express.static`. - * 3.16.6 - * Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually leak to `EMFILE` errors and server unresponsiveness. - * 3.16.0 - * Sparse arrays with extremely high indexes in query string could cause the process to run out of memory and crash the server. - * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. - * 3.3.0 - * The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks. diff --git a/uz/api.md b/uz/api.md deleted file mode 100644 index a01a73ff11..0000000000 --- a/uz/api.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -layout: 4x-api -title: Express 4.x - API Qo'llanma -lang: uz ---- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} - - - {% include api/en/4x/app.md %} - - - {% include api/en/4x/req.md %} - - - {% include api/en/4x/res.md %} - - - {% include api/en/4x/router.md %} - -
      diff --git a/uz/guide/behind-proxies.md b/uz/guide/behind-proxies.md deleted file mode 100644 index c33691eaeb..0000000000 --- a/uz/guide/behind-proxies.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -layout: page -title: Express behind proxies -menu: guide -lang: uz ---- - -# Express behind proxies - -Using Express behind a reverse proxy (such as Varnish or Nginx) -is trivial; however, it does require configuration. By enabling the -"trust proxy" setting via `app.enable('trust proxy')`, Express -will have knowledge that it's sitting behind a proxy and that the -`X-Forwarded-*` header fields may be trusted. (Otherwise, -they are easily spoofed.) - -Enabling this setting has several subtle effects. The first is -that `X-Forwarded-Proto` may be set by the reverse proxy to -tell the app whether it is https or simply http. This value is reflected -by [req.protocol](/api.html#req.protocol). - -The second change is that the [req.ip](/api.html#req.ip) -and [req.ips](/api.html#req.ips) values will be populated with -`X-Forwarded-For`'s list of addresses. diff --git a/uz/guide/database-integration.md b/uz/guide/database-integration.md deleted file mode 100644 index aa184297ec..0000000000 --- a/uz/guide/database-integration.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -layout: page -title: Express database integration -menu: guide -lang: uz ---- - -# Database integration - -Adding database connectivity capability to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node modules for database systems in your Express app: - -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) - -
      -These database drivers are among many that are available. For other options, -search on the [npm](https://www.npmjs.com/) site. -
      - - - -## Cassandra - -**Module**: [cassandra-driver](https://github.com/datastax/nodejs-driver) -**Installation** - -
      
      -$ npm install cassandra-driver
      -
      - -**Example** - -
      
      -var cassandra = require('cassandra-driver');
      -var client = new cassandra.Client({ contactPoints: ['localhost']});
      -
      -client.execute('select key from system.local', function(err, result) {
      -  if (err) throw err;
      -  console.log(result.rows[0]);
      -});
      -
      - - - -## CouchDB - -**Module**: [nano](https://github.com/dscape/nano) -**Installation** - -
      
      -$ npm install nano
      -
      - -**Example** - -
      
      -var nano = require('nano')('http://localhost:5984');
      -nano.db.create('books');
      -var books = nano.db.use('books');
      -
      -//Insert a book document in the books database
      -books.insert({name: 'The Art of war'}, null, function(err, body) {
      -  if (!err){
      -    console.log(body);
      -  }
      -});
      -
      -//Get a list of all books
      -books.list(function(err, body){
      -  console.log(body.rows);
      -});
      -
      - - - -## LevelDB - -**Module**: [levelup](https://github.com/rvagg/node-levelup) -**Installation** - -
      
      -$ npm install level
      -
      - -**Example** - -
      
      -var levelup = require('levelup');
      -var db = levelup('./mydb');
      -
      -db.put('name', 'LevelUP', function (err) {
      -
      -  if (err) return console.log('Ooops!', err);
      -  db.get('name', function (err, value) {
      -    if (err) return console.log('Ooops!', err);
      -    console.log('name=' + value);
      -  });
      -
      -});
      -
      - - - -## MySQL - -**Module**: [mysql](https://github.com/felixge/node-mysql/) -**Installation** - -
      
      -$ npm install mysql
      -
      - -**Example** - -
      
      -var mysql      = require('mysql');
      -var connection = mysql.createConnection({
      -  host     : 'localhost',
      -  user     : 'dbuser',
      -  password : 's3kreee7'
      -});
      -
      -connection.connect();
      -
      -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      -  if (err) throw err;
      -  console.log('The solution is: ', rows[0].solution);
      -});
      -
      -connection.end();
      -
      - - - -## MongoDB - -**Module**: [mongoskin](https://github.com/kissjs/node-mongoskin) -**Installation** - -
      
      -$ npm install mongoskin
      -
      - -**Example** - -
      
      -var db = require('mongoskin').db('localhost:27017/animals');
      -
      -db.collection('mamals').find().toArray(function(err, result) {
      -  if (err) throw err;
      -  console.log(result);
      -});
      -
      - -If you want a object model driver for MongoDB, checkout [Mongoose](https://github.com/LearnBoost/mongoose). - - - -## Neo4j - -**Module**: [apoc](https://github.com/hacksparrow/apoc) -**Installation** - -
      
      -$ npm install apoc
      -
      - -**Example** - -
      
      -var apoc = require('apoc');
      -
      -apoc.query('match (n) return n').exec().then(
      -  function (response) {
      -    console.log(response);
      -  },
      -  function (fail) {
      -    console.log(fail);
      -  }
      -);
      -
      - - - -## PostgreSQL - -**Module**: [pg](https://github.com/brianc/node-postgres) -**Installation** - -
      
      -$ npm install pg
      -
      - -**Example** - -
      
      -var pg = require('pg');
      -var conString = "postgres://username:password@localhost/database";
      -
      -pg.connect(conString, function(err, client, done) {
      -
      -  if (err) {
      -    return console.error('error fetching client from pool', err);
      -  }
      -  client.query('SELECT $1::int AS number', ['1'], function(err, result) {
      -    done();
      -    if (err) {
      -      return console.error('error running query', err);
      -    }
      -    console.log(result.rows[0].number);
      -  });
      -
      -});
      -
      - - - -## Redis - -**Module**: [redis](https://github.com/mranney/node_redis) -**Installation** - -
      
      -$ npm install redis
      -
      - -**Example** - -
      
      -var client = require('redis').createClient();
      -
      -client.on('error', function (err) {
      -  console.log('Error ' + err);
      -});
      -
      -client.set('string key', 'string val', redis.print);
      -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
      -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
      -
      -client.hkeys('hash key', function (err, replies) {
      -
      -  console.log(replies.length + ' replies:');
      -  replies.forEach(function (reply, i) {
      -    console.log('    ' + i + ': ' + reply);
      -  });
      -
      -  client.quit();
      -
      -});
      -
      - - - -## SQLite - -**Module**: [sqlite3](https://github.com/mapbox/node-sqlite3) -**Installation** - -
      
      -$ npm install sqlite3
      -
      - -**Example** - -
      
      -var sqlite3 = require('sqlite3').verbose();
      -var db = new sqlite3.Database(':memory:');
      -
      -db.serialize(function() {
      -
      -  db.run('CREATE TABLE lorem (info TEXT)');
      -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
      -
      -  for (var i = 0; i < 10; i++) {
      -    stmt.run('Ipsum ' + i);
      -  }
      -
      -  stmt.finalize();
      -
      -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
      -    console.log(row.id + ': ' + row.info);
      -  });
      -});
      -
      -db.close();
      -
      diff --git a/uz/guide/debugging.md b/uz/guide/debugging.md deleted file mode 100644 index bc058dd086..0000000000 --- a/uz/guide/debugging.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -layout: page -title: Debugging Express -menu: guide -lang: uz ---- - -# Debugging Express - -Express uses the [debug](https://github.com/visionmedia/debug) module -internally to log information about route matches, middleware in use, application mode, -and the flow of the request-response cycle. - -
      -`debug` is like an augmented version of `console.log`. But unlike `console.log`, you don't have to -comment out `debug` logs in production code. It is turned off by default and can be conditionally turned on with the use an environment variable named `DEBUG`. -
      - -To see all the internal logs used in Express, simply set the `DEBUG` environment variable to -`express:*` when launching your app. - -
      
      -$ DEBUG=express:* node index.js
      -
      - -On Windows, use the corresponding command. - -
      
      -> set DEBUG=express:* & node index.js
      -
      - -Running this on the default app generated by the [express generator](/starter/generator.html) would print the following. - -
      
      -$ 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 /  +0ms
      -  express:router:layer new / +0ms
      -  express:router use /  +0ms
      -  express:router:layer new / +0ms
      -  express:router use /  +0ms
      -  express:router:layer new / +0ms
      -
      - -Now, when a request is made to the app, you will see the logs specified in the Express code. - -
      
      -  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
      -
      - -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. - -## `express`-generated app - -The app generated by the `express` command also uses the `debug` module and its debug namespace is scoped to the name of the application. - -If you generated the app with - -
      
      -$ express sample-app
      -
      - -You can enable the debug statements with the following command - -
      
      -$ DEBUG=sample-app:* node ./bin/www
      -
      - -You can specify more than one debug namespace by assignning a comma separated list of names, as shown below. - -
      
      -$ DEBUG=http,mail,express:* node index.js
      -
      - -For more documentation on `debug`, see the [debug guide](https://github.com/visionmedia/debug). diff --git a/uz/guide/error-handling.md b/uz/guide/error-handling.md deleted file mode 100644 index fdf1106c0b..0000000000 --- a/uz/guide/error-handling.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -layout: page -title: Express error handling -menu: guide -lang: uz ---- - -# Error handling - -Define error-handling middleware like other middleware, -except with four arguments instead of three, specifically with the signature -`(err, req, res, next)`): - -
      
      -app.use(function(err, req, res, next){
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      - -You define error-handling middleware last, after other `app.use()` and routes calls; -For example: - -
      
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next){
      -  // logic
      -});
      -
      - -Responses from within the middleware are completely arbitrary. You may -wish to respond with an HTML error page, a simple message, a JSON string, -or anything else you prefer. - -For organizational (and higher-level framework) purposes, you may define -several error-handling middleware, much like you would with -regular middleware. For example suppose you wanted to define an error-handler -for requests made via XHR, and those without, you might do: - -
      
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      -
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      - -Where the more generic `logErrors` may write request and -error information to stderr, loggly, or similar services: - -
      
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      - -Where `clientErrorHandler` is defined as the following (note -that the error is explicitly passed along to the next): - -
      
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something blew up!' });
      -  } else {
      -    next(err);
      -  }
      -}
      -
      - -The following `errorHandler` "catch-all" implementation may be defined as: - -
      
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      diff --git a/uz/guide/migrating-4.md b/uz/guide/migrating-4.md deleted file mode 100644 index 82dec66add..0000000000 --- a/uz/guide/migrating-4.md +++ /dev/null @@ -1,601 +0,0 @@ ---- -layout: page -title: Migrating to Express 4 -menu: guide -lang: uz ---- - -# Moving to Express 4 - -

      Overview

      - -Express 4 is a breaking change from Express 3. That means an existing Express 3 app will not work if you update the Express version in its dependencies. - -This article covers: - - - -

      Changes in Express 4

      - -The main changes in Express 4 are: - - - -See also: - -* [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) - -

      -Changes to Express core and middleware system -

      - -Express 4 no longer depends on Connect, and removes all the built-in -middleware from its core, except `express.static`. This means -Express is now an independent routing and middleware web framework, and -Express versioning and releases are not affected by middleware updates. - -With the built-in middleware gone, you must explicitly add all the -middleware required to run your app. Simply follow these steps: - -1. Install the module: `npm install --save ` -2. In your app, require the module: `require('module-name')` -3. Use the module according to its documentation: `app.use( ... )` - -The following table lists Express 3 middleware and their counterparts in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Express 3Express 4
      express.bodyParserbody-parser + -multer
      express.compresscompression
      express.cookieSessioncookie-session
      express.cookieParsercookie-parser
      express.loggermorgan
      express.sessionexpress-session
      express.faviconserve-favicon
      express.responseTimeresponse-time
      express.errorHandlererrorhandler
      express.methodOverridemethod-override
      express.timeoutconnect-timeout
      express.vhostvhost
      express.csrfcsurf
      express.directoryserve-index
      express.staticserve-static
      - -Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. - -In most cases, you can simply replace the old version 3 middleware with -its Express 4 counterpart. For details, see the module documentation in -GitHub. - -

      app.use accepts parameters

      - -In version 4 you can now load middleware on a path with a variable -parameter and read the parameter value from the route handler. -For example: - -
      
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -})
      -
      -

      -The routing system -

      - -Apps now implicitly load routing middleware, so you no longer have to -worry about the order in which middleware is loaded with respect to -the `router` middleware. - -The way you define routes is unchanged, but the routing system has two -new features to help organize your routes: - -{: .doclist } -* A new method, `app.route()`, to create chainable route handlers for a route path. -* A new class, `express.Router`, to create modular mountable route handlers. - -

      app.route() method

      - -The new `app.route()` method enables you to create chainable route handlers -for a route path. Since the path is specified in a single location, it -helps to create modular routes and reduce redundancy and typos. For more -information on routes, see [Router() documentation](/4x/api.html#router). - -Here is an example of chained route handlers defined using `app.route()`. - -
      
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  })
      -
      - -

      express.Router class

      - -The other feature to help organize routes is a new class, -`express.Router`, that you can use 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 middleware in -it, defines some routes, and mounts it on a path on the main app. - -Create a router file named `birds.js` in the app directory, -with the following content: - -
      
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -})
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -})
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -})
      -
      -module.exports = router;
      -
      - -Then, load the router module in the app: - -
      
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      - -The app will now be able to handle requests to `/birds` and -`/birds/about`, along with calling the `timeLog` -middleware specific to the route. - -

      -Other changes -

      - -The following table lists other small but important changes in Express 4. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ObjectDescription
      NodeExpress 4 requires Node 0.10.x or later and has dropped support for -Node 0.8.x.
      -`http.createServer()` - -The http module is no longer needed. The app is started using -`app.listen()`. -
      -`app.configure()` - -`app.configure()` has been removed. Use -`process.env.NODE_ENV` or -`app.get('env')` 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, is now an object. -
      -`res.locals` - -Was a function, is 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

      - -Here is an example of migrating an Express 3 application to Express 4. -The files of interest are `app.js` and `package.json`. - -

      -Version 3 app -

      - -

      app.js

      - -Consider an Express v.3 application with the following `app.js` file: - -
      
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -// development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      -}
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      - -

      package.json

      - -The accompanying version 3 `package.json` file might look - something like this: - -
      
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "express": "3.12.0",
      -    "pug": "*"
      -  }
      -}
      -
      - -

      -Process -

      - -Begin the migration process by installing the required middleware for the -Express 4 app and updating Express and Pug to their respective latest -version with the following command: - -
      
      -$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      - -Make the following changes to `app.js`: - -1. The `http` module is longer required, so remove - `var http = require('http');` - -2. The built-in Express middleware `express.favicon`, - `express.logger`, `express.methodOverride`, - `express.session`, `express.bodyParser` and - `express.errorHandler` are no longer available on the - `express` object. You must install their alternatives - manually and load them in the app. - -3. You no longer need to load `app.router`. - It is not a valid Express 4 app object, so remove - `app.use(app.router);` - -4. Make sure the middleware are loaded in the right order - load `errorHandler` after loading the app routes. - -5. Start the app with `app.listen()` instead of - `http.createServer`. - -

      Version 4 app

      - -

      package.json

      - -Running the above `npm` command will update `package.json` as follows: - -
      
      -{
      -  "name": "application-name",
      -  "version": "0.0.1",
      -  "private": true,
      -  "scripts": {
      -    "start": "node app.js"
      -  },
      -  "dependencies": {
      -    "body-parser": "^1.5.2",
      -    "errorhandler": "^1.1.1",
      -    "express": "^4.8.0",
      -    "express-session": "^1.7.2",
      -    "pug": "^2.0.0-beta6",
      -    "method-override": "^2.1.2",
      -    "morgan": "^1.2.2",
      -    "multer": "^0.1.3",
      -    "serve-favicon": "^2.0.1"
      -  }
      -}
      -
      - -

      app.js

      - -Then, remove invalid code, load the required middleware, and make other -changes as necessary. Then `app.js` will look like this: - -
      
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      -
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      -
      -var app = express();
      -
      -// all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      -
      -// error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      -}
      -
      -app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      - -

      Run the app

      - -With that, the migration process is complete, and the app is now an -Express 4 app. To confirm, start the app with the following command: - -
      
      -$ node .
      -
      - -Load [http://localhost:3000](http://localhost:3000) - and see the home page being rendered by Express 4. - -

      Upgrading to the Express 4 app generator

      - -The command-line tool to generate an Express app is still - `express`, but to upgrade to the new version, you must uninstall - the Express 3 app generator and then install the new - `express-generator`. - -

      Installing

      - -If you already have the Express 3 app generator installed on your system, -you must uninstall it as follows: - -
      
      -$ npm uninstall -g express
      -
      -Depending on how your file and directory privileges are configured, -you may need to run this command with `sudo`. - -Now install the new generator: - -
      
      -$ npm install -g express-generator
      -
      - -Depending on how your file and directory privileges are configured, -you may need to run this command with `sudo`. - -Now the `express` command on your system is updated to the -Express 4 generator. - -

      Changes to the app generator

      - -Command options and use largely remain the same, with the following exceptions: - -{: .doclist } -* The `--sessions` option has been removed. -* The `--jshtml` option has been removed. -* The `--hogan` option has been added to support [Hogan.js](http://twitter.github.io/hogan.js/). - -

      Example

      - -Execute the following command to create an Express 4 app: - -
      
      -$ express app4
      -
      - -If you look at the contents of the `app.js` file in the -`app4` directory, you will notice that all the middleware -(except `express.static`) required for the app are loaded as -independent modules and the `router` middleware -is no longer explicitly loaded in the app. - -You will also notice that the `app.js` file is now a Node module, -compared to the standalone app generated by the old generator. - -After installing the dependencies, start the app using the following command: - -
      
      -$ npm start
      -
      - -If you peek at the npm start script in `package.json` file, -you will notice that the actual command that starts the app is -`node ./bin/www`, which used to be `node app.js` -in Express 3. - -Since the `app.js` file generated by the Express 4 generator -is now a Node module, it can no longer be started independently as an app -(unless you modify the code). It has to be to be loaded in a Node file -and started via the Node file. The Node file is `./bin/www` -in this case. - -Neither the `bin` directory nor the extensionless `www` -file is mandatory for creating an Express app or starting the app. They are -just suggestions by the generator, so feel free to modify them to suit your -needs. - -To get rid of the `www` directory and keep things the "Express 3 way", -delete the line that says `module.exports = app;` at the end of -`app.js`, and paste the following code in its place. - -
      
      -app.set('port', process.env.PORT || 3000);
      -
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      - -Make sure to load the `debug` module at the top of `app.js` with the following code. - -
      
      -var debug = require('debug')('app4');
      -
      - -Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`. - -With that, you just moved the functionality of `./bin/www` back to -`app.js`. Not that it is recommended, but the exercise helps -to understand how `./bin/www` works and why `app.js` -won't start on its own anymore. diff --git a/uz/guide/routing.md b/uz/guide/routing.md deleted file mode 100644 index 4308a49757..0000000000 --- a/uz/guide/routing.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -layout: page -title: Express routerlar -menu: guide -lang: uz ---- - -# Routerlar - -Routing refers to the definition of end points (URIs) to an application and how it responds to client requests. - -A route is a combination of a URI, a HTTP request method (GET, POST, and so on), and one or more handlers for the endpoint. It takes the following structure `app.METHOD(path, [callback...], callback)`, where `app` is an instance of `express`, `METHOD` is an [HTTP request method](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol), `path` is a path on the server, and `callback` is the function executed when the route is matched. - -The following is an example of a very basic route. - -
      
      -var express = require('express')
      -var app = express()
      -
      -// respond with "hello world" when a GET request is made to the homepage
      -app.get('/', function(req, res) {
      -  res.send('hello world')
      -})
      -
      - -

      Route methods

      - -A route method is derived from one of the HTTP methods, and is attached to an instance of `express`. - -The following is an example of routes defined for the GET and the POST methods to the root of the app. - -
      
      -// GET method route
      -app.get('/', function (req, res) {
      -  res.send('GET request to the homepage')
      -})
      -
      -// POST method route
      -app.post('/', function (req, res) {
      -  res.send('POST request to the homepage')
      -})
      -
      -
      - -Express supports the following routing methods corresponding to HTTP methods: `get`, `post`, `put`, `head`, `delete`, `options`, `trace`, `copy`, `lock`, `mkcol`, `move`, `purge`, `propfind`, `proppatch`, `unlock`, `report`, `mkactivity`, `checkout`, `merge`, `m-search`, `notify`, `subscribe`, `unsubscribe`, `patch`, `search`, and `connect`. - -
      -To route methods which translate to invalid JavaScript variable names, use the bracket notation. For example, -`app['m-search']('/', function ...` -
      - -There is a special routing method, `app.all()`, which is not derived from any HTTP method. It is used for loading middleware at a path for all request methods. - -In the following example, the handler will be executed for requests to "/secret" whether using GET, POST, PUT, DELETE, or any other HTTP request method. - -
      
      -app.all('/secret', function (req, res, next) {
      -  console.log('Accessing the secret section ...')
      -  next() // pass control to the next handler
      -})
      -
      - -

      Route paths

      - -Route paths, in combination with a request method, define the endpoints at which requests can be made to. They can be strings, string patterns, or regular expressions. - -
      -Query strings are not a part of the route path. -
      - -Examples of route paths based on strings: - -
      
      -// with match request to the root
      -app.get('/', function (req, res) {
      -  res.send('root')
      -})
      -
      -// will match requests to /about
      -app.get('/about', function (req, res) {
      -  res.send('about')
      -})
      -
      -// will match request to /random.text
      -app.get('/random.text', function (req, res) {
      -  res.send('random.text')
      -})
      -
      - -Examples of route paths based on string patterns: - -
      
      -// will match acd and abcd
      -app.get('/ab?cd', function(req, res) {
      -  res.send('ab?cd')
      -})
      -
      -// will match abcd, abbcd, abbbcd, and so on
      -app.get('/ab+cd', function(req, res) {
      -  res.send('ab+cd')
      -})
      -
      -// will match abcd, abxcd, abRABDOMcd, ab123cd, and so on
      -app.get('/ab*cd', function(req, res) {
      -  res.send('ab*cd')
      -})
      -
      -// will match /abe and /abcde
      -app.get('/ab(cd)?e', function(req, res) {
      - res.send('ab(cd)?e')
      -})
      -
      - -
      -The characters ?, +, *, and () are subsets of their Regular Expression counterparts. The hyphen (-) and the dot (.) are interpreted literally by string-based paths. -
      - -Examples of route paths based on regular expressions: - -
      
      -// will match anything with an a in the route name:
      -app.get(/a/, function(req, res) {
      -  res.send('/a/')
      -})
      -
      -// will match butterfly, dagonfly; but not butterflyman, dragonfly man, and so on
      -app.get(/.*fly$/, function(req, res) {
      -  res.send('/.*fly$/')
      -})
      -
      - -

      Route handlers

      - -You can provide multiple callback functions that behave just like [middleware](/guide/using-middleware.html) to handle a request. The only exception is that these callbacks may invoke `next('route')` to bypass the remaining route callback(s). 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. - -Route handlers can come in the form of a function, an array of functions, or various combinations of both, as shown the following examples. - -A route can be handled using a single callback function: - -
      
      -app.get('/example/a', function (req, res) {
      -  res.send('Hello from A!')
      -})
      -
      - -A route can be handled using a more than one callback function (make sure to specify the `next` object): - -
      
      -app.get('/example/b', function (req, res, next) {
      -  console.log('response will be sent by the next function ...')
      -  next()
      -}, function (req, res) {
      -  res.send('Hello from B!')
      -})
      -
      - -A route can be handled using an array of callback functions: - -
      
      -var cb0 = function (req, res, next) {
      -  console.log('CB0')
      -  next()
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1')
      -  next()
      -}
      -
      -var cb2 = function (req, res) {
      -  res.send('Hello from C!')
      -}
      -
      -app.get('/example/c', [cb0, cb1, cb2])
      -
      - -A route can be handled using a combination of array of functions and independent functions: - -
      
      -var cb0 = function (req, res, next) {
      -  console.log('CB0')
      -  next()
      -}
      -
      -var cb1 = function (req, res, next) {
      -  console.log('CB1')
      -  next()
      -}
      -
      -app.get('/example/d', [cb0, cb1], function (req, res, next) {
      -  console.log('response will be sent by the next function ...')
      -  next()
      -}, function (req, res) {
      -  res.send('Hello from D!')
      -})
      -
      - -

      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 them is called from a route handler, the client request will be left hanging. - -| Method | Description -|----------------------|-------------------------------------- -| [res.download()](/4x/api.html#res.download) | Prompt a file to be downloaded. -| [res.end()](/4x/api.html#res.end) | End the response process. -| [res.json()](/4x/api.html#res.json) | Send a JSON response. -| [res.jsonp()](/4x/api.html#res.jsonp) | Send a JSON response with JSONP support. -| [res.redirect()](/4x/api.html#res.redirect) | Redirect a request. -| [res.render()](/4x/api.html#res.render) | Render a view template. -| [res.send()](/4x/api.html#res.send) | Send a response of various types. -| [res.sendFile](/4x/api.html#res.sendFile) | Send a file as an octet stream. -| [res.sendStatus()](/4x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. - -

      app.route()

      - -Chainable route handlers for a route path can be created using `app.route()`. -Since the path is specified at a single location, it -helps to create modular routes and reduce redundancy and typos. For more -information on routes, see [Router() documentation](/4x/api.html#router). - -Here is an example of chained route handlers defined using `app.route()`. - -
      
      -app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      -  })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      -  })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  })
      -
      - -

      express.Router

      - -The `express.Router` class can be used 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 middleware in -it, defines some routes, and mounts it on a path on the main app. - -Create a router file named `birds.js` in the app directory, -with the following content: - -
      
      -var express = require('express');
      -var router = express.Router();
      -
      -// middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -})
      -// define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -})
      -// define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -})
      -
      -module.exports = router;
      -
      - -Then, load the router module in the app: - -
      
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      - -The app will now be able to handle requests to `/birds` and -`/birds/about`, along with calling the `timeLog` -middleware specific to the route. diff --git a/uz/guide/using-middleware.md b/uz/guide/using-middleware.md deleted file mode 100644 index 659a9a6a15..0000000000 --- a/uz/guide/using-middleware.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -layout: page -title: Using Express middleware -menu: guide -lang: uz ---- - -# Using middleware - -An Express application is essentially a series of middleware calls. - -Middleware is a function with access to the request object (`req`), the response object (`res`), and the next middleware in line in the request-response cycle of an Express application, commonly denoted by a variable named `next`. Middleware can: - - - Execute any code. - - Make changes to the request and the response objects. - - End the request-response cycle. - - Call the next middleware in the stack. - -If the current middleware does not end the request-response cycle, it must call `next()` to pass control to the next middleware, otherwise the request will be left hanging. - -With an optional mount path, middleware can be loaded at the application level or at the router level. -Also, a series of middleware functions can be loaded together, creating a sub-stack of the middleware system at a mount point. - -An Express application can use the following kinds of middleware: - - - [Application-level middleware](#middleware.application) - - [Router-level middleware](#middleware.router) - - [Built-in middleware](#middleware.built-in) - - [Third-party middleware](#middleware.third-party) - -

      Application level middleware

      - -Application level middleware are bound to an instance of `express`, using `app.use()` and `app.VERB()`. - -
      
      -var app = express();
      -
      -// a middleware with no mount path; gets executed for every request to the app
      -app.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -// a middleware mounted on /user/:id; will be executed for any type of HTTP request to /user/:id
      -app.use('/user/:id', function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -// a route and its handler function (middleware system) which handles GET requests to /user/:id
      -app.get('/user/:id', function (req, res, next) {
      -  res.send('USER');
      -});
      -
      - -Here is an example of loading a series of middleware at a mount point with a mount path. - -
      
      -// a middleware sub-stack which prints request info for any type of HTTP request to /user/:id
      -app.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      - -Route handlers, being a middleware system, makes it possible to define multiple routes for a path. In the example below, two routes are defined for GET requests to `/user/:id`. The second router will not cause any problems, however it will never get called, because the first route ends the request-response cycle. - -
      
      -// a middleware sub-stack which handles GET requests to /user/:id
      -app.get('/user/:id', function (req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -}, function (req, res, next) {
      -  res.send('User Info');
      -});
      -
      -// handler for /user/:id which prints the user id
      -app.get('/user/:id', function (req, res, next) {
      -  res.end(req.params.id);
      -});
      -
      - -If you need to skip the rest of the middleware from a router middleware stack, call `next('route')` to pass on the control to the next route. Note: `next('route')` will work only in middleware loaded using `app.VERB()` or `router.VERB()`. - -
      
      -// a middleware sub-stack which handles GET requests to /user/:id
      -app.get('/user/:id', function (req, res, next) {
      -  // if user id is 0, skip to the next route
      -  if (req.params.id == 0) next('route');
      -  // else pass the control to the next middleware in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for /user/:id which renders a special page
      -app.get('/user/:id', function (req, res, next) {
      -  res.render('special');
      -});
      -
      - -

      Router level middleware

      - -Router level middleware work just like application level middleware except they are bound to an instance of `express.Router()`. - -
      
      -var router = express.Router();
      -
      -Router level middleware are loaded using `router.use()` and `router.VERB()`. - -The middleware system created at the application level in the example above, can be replicated at the router level using the following code. - -
      
      -var app = express();
      -var router = express.Router();
      -
      -// a middleware with no mount path, gets executed for every request to the router
      -router.use(function (req, res, next) {
      -  console.log('Time:', Date.now());
      -  next();
      -});
      -
      -// a middleware sub-stack shows request info for any type of HTTP request to /user/:id
      -router.use('/user/:id', function(req, res, next) {
      -  console.log('Request URL:', req.originalUrl);
      -  next();
      -}, function (req, res, next) {
      -  console.log('Request Type:', req.method);
      -  next();
      -});
      -
      -// a middleware sub-stack which handles GET requests to /user/:id
      -router.get('/user/:id', function (req, res, next) {
      -  // if user id is 0, skip to the next router
      -  if (req.params.id == 0) next('route');
      -  // else pass the control to the next middleware in this stack
      -  else next(); //
      -}, function (req, res, next) {
      -  // render a regular page
      -  res.render('regular');
      -});
      -
      -// handler for /user/:id which renders a special page
      -router.get('/user/:id', function (req, res, next) {
      -  console.log(req.params.id);
      -  res.render('special');
      -});
      -
      -// mount the router on the app
      -app.use('/', router);
      -
      - -

      Built-in middleware

      - -As of 4.x, Express no longer depends on Connect. Except for `express.static`, all of Express' previously included middleware are now in separate repos. Please view [the list of middleware](https://github.com/senchalabs/connect#middleware). - -

      express.static(root, [options])

      - -`express.static` is based on [serve-static](https://github.com/expressjs/serve-static), and is responsible for serving the static assets of an Express application. - -The `root` argument refers to the root directory from which the static assets are to be served. - -The optional `options` object can have the following properties. - -* `dotfiles` option for serving dotfiles. Possible values are "allow", "deny", and "ignore"; defaults to "ignore". -* `etag` enable or disable etag generation, defaults to `true`. -* `extensions` sets file extension fallbacks, defaults to `false`. -* `index` sends directory index file, defaults to "index.html". Set `false` to disable directory indexing. -* `lastModified` enabled by default, sets the `Last-Modified` header to the last modified date of the file on the OS. Set `false` to disable it. -* `maxAge` sets the max-age property of the Cache-Control header in milliseconds or a string in [ms format](https://www.npmjs.org/package/ms), defaults to 0. -* `redirect` redirects to trailing "/" when the pathname is a dir, defaults to `true`. -* `setHeaders` function for setting HTTP headers to serve with the file. - -Here is an example of using the `express.static` middleware with an elaborate options object. - -
      
      -var options = {
      -  dotfiles: 'ignore',
      -  etag: false,
      -  extensions: ['htm', 'html'],
      -  index: false,
      -  maxAge: '1d',
      -  redirect: false,
      -  setHeaders: function (res, path, stat) {
      -    res.set('x-timestamp', Date.now())
      -  }
      -};
      -
      -app.use(express.static('public', options));
      -
      - -You can have more than one static directory per app. - -
      
      -app.use(express.static('public'));
      -app.use(express.static('uploads'));
      -app.use(express.static('files'));
      -
      - -For more details about `serve-static` and its options, visit the [serve-static](https://github.com/expressjs/serve-static) documentation. - -

      Third-party middleware

      - -Express is a routing and middleware web framework with minimal functionality of its own. Functionality to Express apps are added via third-party middleware. - -Install the node module for the required functionality and loaded it in your app at the application level or at the router level. - -In the following example, `cookie-parser`, a cookie parsing middleware is installed and loaded in the app. - -
      
      -$ npm install cookie-parser
      -
      - -
      
      -var express = require('express');
      -var app = express();
      -var cookieParser = require('cookie-parser');
      -
      -// load the cookie parsing middleware
      -app.use(cookieParser());
      -
      - -See [Third-party middleware](../resources/middleware.html) for a partial list of third-party middleware commonly used with Express. diff --git a/uz/guide/using-template-engines.md b/uz/guide/using-template-engines.md deleted file mode 100644 index 02b6457075..0000000000 --- a/uz/guide/using-template-engines.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -layout: page -title: Using template engines with Express -menu: guide -lang: uz ---- - -# Using template engines with Express - -Before Express can render template files, the following application settings have to be set. - -* `views`, the directory where the template files are located. Eg: `app.set('views', './views')` -* `view engine`, the template engine to use. Eg: `app.set('view engine', 'pug')` - -Then install the corresponding template engine npm package. - -
      
      -$ npm install pug --save
      -
      - -
      -Express-compliant template engines such as Pug, export a function named `__express(filePath, options, callback)`, which is called by `res.render()` to render the template code. - -Some template engines do not follow this convention, the [Consolidate.js](https://www.npmjs.org/package/consolidate) library was created to map all of node's popular template engines to follow this convention, thus allowing them to work seamlessly within Express. -
      - -Once the view engine is set, you don't have to explicitly specify the engine or load the template engine module in your app, Express loads it internally as shown below, for the example above. - -
      
      -app.set('view engine', 'pug');
      -
      - -Create a Pug template files named "index.pug" in the views directory, with the following content. - -
      
      -html
      -  head
      -    title= title
      -  body
      -    h1= message
      -
      - -Then create a route to render the "index.pug" file. If the `view engine` property is not set, you will have to specify the extension of the view file, else you can omit it. - -
      
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      - -On making a request to the home page, "index.pug" will be rendered as HTML. - -To better understand how template engines work in Express, read ["Developing template engines for Express"](/{{ page.lang }}/advanced/developing-template-engines.html). diff --git a/uz/index.md b/uz/index.md deleted file mode 100644 index 333fbccbc4..0000000000 --- a/uz/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: home -title: Express - Node.js web-dasturlar uchun freymvork -menu: home -lang: uz ---- -
      - {% include header/header-{{ page.lang }}.html %} -
      -
      -
      - - Node.js uchun tezkor, moslashuvchan, minimalistik web-freymvork. -
      -
      $ npm install express --save
      -
      -
      - -
      -
      - -
      -
      - -
      -

      Web dasturlar

      Express, Node.jsda web-dasturlarni yaratishda keng ko'lamda yordam beruvchi, minimalistik va moslashuvchan freymvorkdir. -
      - -
      -

      APIs

      Ko'plab HTTP metodlar, oraliq qayta ishlovchi(middleware)lar yordamida, ishonchli tezkor va oson API server yaratish mumkin bo'ladi. -
      - -
      -

      Ishlab chiqaruvchanlik

      Express Nodedagi siz bilgan va sevgan imkoniyatlarni cheklamagan holda web-dasturlardagi eng asosiy imkoniyatlar bilan ta'minlab beradi. -
      - -
      -

      Freymvorklar

      Express asosida yaratilgan ko'plab mashxur freymvorklar . -
      - -
      -
      - -
      - {% include announcement/announcement-{{ page.lang }}.md %} -
      diff --git a/uz/resources/community.md b/uz/resources/community.md deleted file mode 100644 index 40244eccd5..0000000000 --- a/uz/resources/community.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -layout: page -title: Express community -menu: resources -lang: uz ---- - -# Community - -## Mailing List - -Join over 2000 Express users or browse over 5000 -discussions in the [Google Group](https://groups.google.com/group/express-js). - -## Gitter - -The [expressjs/express chatroom](https://gitter.im/expressjs/express) is great place -for developers interested in the everyday discussions related to Express. - -## IRC Channel - -Hundreds of developers idle in #express on freenode every day. -If you have questions about the framework, jump in for quick -feedback. - -## Examples - -View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples) -in the repo covering everything from API design and auth -to template engine integration. - -## Issues - -If you've come across what you think is a bug, or just want to make -a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues). - -## Third Party - -Our vibrant community has created a large variety of extensions, -[middleware](/resources/middleware.html) and higher level frameworks. Check them out in the -[wiki](https://github.com/expressjs/express/wiki). diff --git a/uz/resources/glossary.md b/uz/resources/glossary.md deleted file mode 100644 index 94ca4fefb7..0000000000 --- a/uz/resources/glossary.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -layout: page -title: Express glossary -menu: resources -lang: uz ---- - -# Glossary - -
      This is currently a working draft
      - -### application - -In general, one or more programs designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. May also refer to an [app object](/api.html#express). - -### API - -Application programming interface. Spell out on first use. - -### Express - -A fast, un-opinionated, minimalist web framework for Node.js applications. In general, prefer simply "Express" to "Express.js," though the latter is acceptable. - -### libuv - -Multi-platform support library with focus on asynchronous I/O, primarily developed for use by Node.js. - -### middleware - -A function invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: - - * `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware. - * `app.use(mw)` is called _adding the middleware to the global processing stack_. - * `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_. - -### Node.js - -Software platform used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](http://nodejs.org/). **Usage note**: Initially, "Node.js," thereafter "Node". - -### open-source, open source - -When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). Note: Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective - -### request - -An HTTP request. A client submits an HTTP request message to a server, which returns an response. 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 - -An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and may also contain requested content in its message body. - -### route - -Part of a URL that identifies a resource. For example, in `http://foo.com/products`, "/products/id" is the route. - -### router - -See [http://expressjs.com/api#router](http://expressjs.com/api#router) diff --git a/uz/resources/learning.md b/uz/resources/learning.md deleted file mode 100644 index 8a50660573..0000000000 --- a/uz/resources/learning.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -layout: page -title: Additional learning -menu: resources -lang: uz ---- - -# Additional learning - -
      Disclaimer: Unendorsed community content.
      - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Pack Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Pack Publishing, June 2013. - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/uz/resources/middleware.md b/uz/resources/middleware.md deleted file mode 100644 index 147906241b..0000000000 --- a/uz/resources/middleware.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -layout: page -title: Express middleware -menu: resources -lang: uz ---- - -# Third-party middleware - -Here are some Express middleware modules: - - - [body-parser](https://github.com/expressjs/body-parser): previously `express.bodyParser`, `json`, and `urlencoded`. - See also: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression) - previously `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus): Connect/Express middleware for optimal image serving. Switches to webp/jpegxr if possible. - - [connect-timeout](https://github.com/expressjs/timeout): previously `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser): previously `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session): previously `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf): previousy `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler): previously `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug): unobtrusive development tool that adds a tab with information about req, session, locals, and more to your application. - - [express-partial-response](https://github.com/nemtsov/express-partial-response): Express middleware for filtering-out parts of JSON responses based on the `fields` query-string; using Google API's Partial Response. - - [express-session](https://github.com/expressjs/session): previously `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn): easily use a CDN for your static assets, with multiple host support (ex. cdn1.host.com, cdn2.host.com). - - [express-slash](https://github.com/ericf/express-slash): Express middleware for people who are strict about trailing slashes. - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize): redirect HTTP requests containing uppercase to a canonical lowercase form. - - [method-override](https://github.com/expressjs/method-override): previously `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan): previously `logger` - - [response-time](https://github.com/expressjs/response-time): previously `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon): previously `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index): previousy `express.directory` - - [serve-static](https://github.com/expressjs/serve-static): for serving static content - - [static-expiry](https://github.com/paulwalker/connect-static-expiry): fingerprinted URLs/Caching Headers for static assets including external domain(s) support. - - [vhost](https://github.com/expressjs/vhost): previously `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers): An express middleware that provides common helper methods to the views. - -Some middleware previously included with Connect are no longer supported by the Connect/Express team, -are replaced by an alternative module, or should be superseded by a better module. Use one of these alternatives instead: - - - express.cookieParser - - [cookies](https://github.com/jed/cookies) and [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) - -For more middleware, see also: - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) diff --git a/uz/starter/basic-routing.md b/uz/starter/basic-routing.md deleted file mode 100644 index 2d440d8b71..0000000000 --- a/uz/starter/basic-routing.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: page -title: Express asosiy marshrutizatsiya -menu: starter -lang: uz ---- - -# Asosiy marshrutizatsiya -Ushbu material Expressda asosiy marshrutizatsiyalar bilan ishlash haqidadir. Marshrutizatsiya dasturda HTTP so'rovlarga (GET, POST va b.sh) murojat qilinganda, ma'lum bir manzilga(endpoint) qanday javob berishini aniqlaydi. - -Har bir marshrut(route) bir yoki ko'plar qayta ishlovchi funksiyalarga ega. - -Marshrutni aniqlash quyidagi ko'rinishga ega `app.METHOD(PATH, HANDLER)`, bu yerda `app` `express`ning ekzamplyari, `METHOD` esa [HTTP request method](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol), `PATH` esa saytdagi manzili va `HANDLER` esa marshrut chaqirilganda bajariladinga funksiya. -
      -Ushbu qo'llanmani foydalanishdan oldin `express` obyektidan ekzamplyar olib, uni `app` deb atang va serverni ishga tushuring. Agar siz bu bilan tanish bo'lmasangiz, unda [Hello world misol](/starter/hello-world.html) qo'llanmanisini o'qib chiqing. -
      - -Quyidagi kodlar marshrutizatsiyaga bir necha misollar keltirilgan. - -
      
      -// Bosh sahifada "Hello World!" javobini qaytaradi.
      -app.get('/', function (req, res) {
      -  res.send('Hello World!');
      -})
      -
      -// Bosh sahifada POST so'rovni qabul qilish.
      -app.post('/', function (req, res) {
      -  res.send('Got a POST request');
      -})
      -
      -// /user manzilida PUT so'rovni qabul qilish.
      -app.put('/user', function (req, res) {
      -  res.send('Got a PUT request at /user');
      -})
      -
      -// /user mazilida DELETE so'rovni qabul qilish.
      -app.delete('/user', function (req, res) {
      -  res.send('Got a DELETE request at /user');
      -})
      -
      - -Marshrutizatsiya haqida to'liq ma'lumot olish uchun, ma'lumotnoma orqali [Marshrutizatsiya](/guide/routing.html) bo'limini o'qib chiqing. diff --git a/uz/starter/faq.md b/uz/starter/faq.md deleted file mode 100644 index 5d45f58dce..0000000000 --- a/uz/starter/faq.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -layout: page -title: Express FAQ -menu: starter -lang: uz ---- - -# FAQ - -## Dasturim uchun qanday struktura tanlashim kerak? - -Bu savolga bitta javob yo'q. Bu dasturingiz hajmi va dasturchilar jamosiga bog'liq bo'ladi. Tobora moslashuvchan bo'lish uchun, Express struktura yaratishga hech qanday cheklovlar qo'ymaydi. - -Dasturning marshrutizatsiya va boshqa logika qismi ko'plab fayllarda joylashgan bo'lishi mumkin, struktura esa siz hohlagan holda yaratish imkoniyati mavjud. Ilhomlanish uchun quyidagi strukturalarni ko'rishingiz mumkin: - -* [Marshrutlarni e'lon qilish](https://github.com/expressjs/express/blob/master/examples/route-separation/index.js#L19) -* [Marshrutlarni haritasi](https://github.com/expressjs/express/blob/master/examples/route-map/index.js#L47) -* [MVC ko'rinishida kontrollerlar](https://github.com/expressjs/express/tree/master/examples/mvc) - -Bundan tashqari, Express uchun qo'shimcha yordam beruvchi shablonlar mavjud: - -* [Resourceful marshrutizatsiya](https://github.com/expressjs/express-resource) -* [Namespaced marshrutizatsiya](https://github.com/expressjs/express-namespace) - -## Modellarni qanday aniqlashim mumkin? - -Express qaysi ma'lumotlar ombori bilan ishlashni keltirilmagan. Siz hohlagan Node modullarni ishlatishingiz mumkin bo'ladi, bu esa sizga hohlagan ma'lumotlar omborini ishlatish imkonini beradi. - -[LoopBack](http://loopback.io) ko'ring, Express asosida modellar bilan ishlash uchun yaratilgan freymvork. - -## Qanday qilish foydalanuvchini autenfikatsiya qilishim mumkin? - -Bu ham Express o'ziga olmaydigan qismi hisoblanadi. Siz hohlagan autenfikatsiya tizimini ishlatishingiz mumkin bo'ladi. -Oddiy username / password sxemasini ishlatish uchun [ushbu misolni](https://github.com/expressjs/express/tree/master/examples/auth) ko'ring. - -## Express qaysi shablonizator ishlatadi? - -Express `(path, locals, callback)` signaturasini maqullaydigan barcha shablonizatorni ishlatishi mumkin. -Iterfey shablonizator va keshirovaniyani normalashtirish uchun, [consolidate.js](https://github.com/visionmedia/consolidate.js) ni ko'ring. - -## Qanday qilib bir necha direktoriyalarni statik fayllarga aylantirishim mumkin? - -Siz oraliq qayta ishlovchilarni bir necha marta ishatishingiz mumkin. Quyidagilar keltirilgan oraliq qayta ishlovchida, `GET /javascripts/jquery.js` ni olishga so'rov jo'natilganda, avvalo `./public/javascripts/jquery.js`ni tekshiradi; -Agarda ushbu fayl direktoriyada topilmasa, undan keyingi oraliq qayta ishlovchida ko'rsatilgan direktoriyani `./files/javascripts/jquery.js` tekshiradi. - -
      
      -app.use(express.static('public'));
      -app.use(express.static('files'));
      -
      - -## Statik fayllarni tarqatish qanday qilib manzil prefiksini ko'rsatsam bo'ladi? - -Asosiy Connect "mounting" yordamida "prefiks" aniqlab qaysi middleware ishga tushishini ko'rsatish mumkin bo'ladi. -Bu usul effektiv ishlaydi huddi prefiks hech qachon manzil qismi bo'lmagandek. -Masalan, bizga `GET /files/javascripts/jquery.js` kerak bo'lsa. -Siz `/files` prefiksini o'rnatib, `/javascripts/jquery.js`ni `req.url` aniqlashingiz mumkin, shu bilan tarqatish uchun middleware ko'rsatishingiz mumkin: - -
      
      -app.use('/public', express.static('public'));
      -
      - -## Siz qanday qilib 404 xatoni qayta ishlaysiz? - -Expressda, 404 xatosi, natija xatosi hisoblanmaydi. Shuning uchun ham xatolarni qayta ishlovchi middleware 404ni qayta ishlay olmaydi. Chunki 404 qo'shimcha ish yo'qligidan dalolat beradi; -Boshqa qilib aytganda, Express hamma oraliq qayta ishlovchi(middleware) / routerlarni(routes)larni ishga tushuradi, -va ularda hech biri ish haqida natija beramangani aniqlanadi. -Buning uchun siz eng oxirida(hammasidan keyin) 404ni qayta ishlash oraliq qayta ishlovchi ko'rsatishingiz kerak bo'ladi: - -
      
      -app.use(function(req, res, next){
      -  res.send(404, 'Sorry cant find that!');
      -});
      -
      - -## Xato qayta ishlovchisini qanday aniqlaysiz? - -Siz xatolarni qayta ishlovchi middlewareni ko'rsatishingiz mumkin, shu bilan qolgan qayta ishlovchisi(middleware)ga -uchta argumentlar o'rniga to'rtta argument jo'natishingiz kerak; u quyidagicha `(err, req, res, next)`: - -
      
      -app.use(function(err, req, res, next){
      -  console.error(err.stack);
      -  res.send(500, 'Something broke!');
      -});
      -
      - -Batafsil ma'lumot uchun [Xatolarni qayta ishlash](/guide/error-handling.html) o'qing. - -## Qanday qilib plain HTMLni render qilishim mumkin? - -Siz buni qilishingiz kerak emas! HTMLni `res.render()` orqali "render" qilish kerak emas. -Agar sizda shunday fayl bo'lsa, `res.sendFile()` ishlating. -Agar siz ko'pgina bunday fayllarni ishlatsangiz `express.static()` qayta ishlovchisi(middleware)ni ishlatishingiz mumkin. diff --git a/uz/starter/generator.md b/uz/starter/generator.md deleted file mode 100644 index 06d63d7acb..0000000000 --- a/uz/starter/generator.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -layout: page -title: Express dasturlar generatori -menu: starter -lang: uz ---- - -# Express dasturlar generatori - -Dastur generatsiya qilish uchun `express` buyrug'idan foydalanishgiz mumkin, u dasturning asosiy qismini yaratib beradi. - -Uni o'rnatish uchun quyidagi buyruqlardan foydalaning. - -
      
      -$ npm install express-generator -g
      -
      - -Qo'shimcha amallarda foydalanish uchun `-h` qo'shimchasini yozing: - -
      
      -$ express -h
      -
      -  Usage: express [options] [dir]
      -
      -  Options:
      -
      -    -h, --help          output usage information
      -        --version       output the version number
      -    -e, --ejs           add ejs engine support
      -        --hbs           add handlebars engine support
      -        --pug           add pug engine support
      -    -H, --hogan         add hogan.js engine support
      -        --no-view       generate without view engine
      -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
      -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
      -        --git           add .gitignore
      -    -f, --force         force on non-empty directory
      -
      - -Masalan, quyidagi buyruq _myapp_ nomi dasturni yaratadi. - -
      
      -$ express --view=pug myapp
      -
      -   create : myapp
      -   create : myapp/package.json
      -   create : myapp/app.js
      -   create : myapp/public
      -   create : myapp/public/javascripts
      -   create : myapp/public/images
      -   create : myapp/routes
      -   create : myapp/routes/index.js
      -   create : myapp/routes/users.js
      -   create : myapp/public/stylesheets
      -   create : myapp/public/stylesheets/style.css
      -   create : myapp/views
      -   create : myapp/views/index.pug
      -   create : myapp/views/layout.pug
      -   create : myapp/views/error.pug
      -   create : myapp/bin
      -   create : myapp/bin/www
      -
      - -Keyin dasturning kerakli modullarni o'rnatish kerak bo'ladi: - -
      
      -$ cd myapp
      -$ npm install
      -
      - -Dasturni ishga tushurish (MacOS va Linux): - -
      
      -$ DEBUG=myapp ./bin/www
      -
      - -Windowsda esa, quyidagicha: - -
      
      -> set DEBUG=myapp & node .\bin\www
      -
      - -Undan keyin brauzerda `http://localhost:3000/` manziligaa kirib dastur ishalayotganini tekshiring. - -Generatsiya qilingan dasturning strukturasi quyidagicha bo'ladi. - -
      
      -.
      -├── app.js
      -├── bin
      -│   └── www
      -├── package.json
      -├── public
      -│   ├── images
      -│   ├── javascripts
      -│   └── stylesheets
      -│       └── style.css
      -├── routes
      -│   ├── index.js
      -│   └── users.js
      -└── views
      -    ├── error.pug
      -    ├── index.pug
      -    └── layout.pug
      -
      -7 directories, 9 files
      -
      - -
      -Generator yordamida generatsiya qilingan struktra, Express dasturda yaratish mumkin bo'lgan strukturalardan bir usuli hisoblanadi. Siz bu strukturadan foydalanmasligingiz mumkin, o'zingizga kerakli ko'rinishda yaratishingiz mumkin. -
      diff --git a/uz/starter/hello-world.md b/uz/starter/hello-world.md deleted file mode 100644 index ac1f1d4403..0000000000 --- a/uz/starter/hello-world.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -layout: page -title: Express "Hello World" -menu: starter -lang: uz ---- - -# Hello world - -Bu yerda Express dasturga eng sodda misol keltirilgan. - -
      
      -const express = require('express')
      -const app = express()
      -const port = 3000
      -
      -app.get('/', (req, res) => {
      -  res.send('Hello World!')
      -})
      -
      -app.listen(port, () => {
      -  console.log(`Example app listening at http://localhost:${port}`)
      -})
      -
      - -
      -`req` (request) va `res` (response) Node taqdim etayotgan obyektlar hisoblanadi, shuning uchun -`req.pipe()`, `req.on('data', callback)` Express talab qilmaydigan boshqa obyektlar. -
      - -Dastur serverni ishga tushuradi va 3000 portdagi aloqani eshitib turadi. Javob sifatida bosh sahifaga "Hello World!" so'zi jo'natiladi. Qolgan barcha sahifalarga esa **404 Not Found** javobi jo'natiladi. - -Kodni yozib, `app.js` faylida saqlab qoying. Uni ishga tushurish uchun quyidagi buyruqni ishga tushiring: - -
      
      -$ node app.js
      -
      - -Natijani ko'rish uchun, brauzerdan [http://localhost:3000/](http://localhost:3000/) manziliga kiring. diff --git a/uz/starter/installing.md b/uz/starter/installing.md deleted file mode 100644 index 8badd1e677..0000000000 --- a/uz/starter/installing.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -layout: page -title: Expressni o'rnatish -menu: starter -lang: uz ---- - -# O'rnatish - -Avval, agar ish direktoryasini yaratmagan bo'lsangiz, uni yarating va ish direktoriyasiga aylantiring. - -
      
      -$ mkdir myapp
      -$ cd myapp
      -
      - -Agar sizning direktoriyangizda `package.json` fayli mavjud bo'lmasa, uni `npm init` buyrug'i orqali yarating. - -
      
      -$ npm init
      -
      - -Expressni dastur direktoriyangizga o'rnating va uning kerakli modullarini saqlab qo'ying: - -
      
      -$ npm install express --save
      -
      - -Expressni vaqtinchalik o'rnatish uchun va uning kerakli modullarni saqlab qo'ymaslik uchun `--save` qo'shimchasini olib tashlang:: - -
      
      -$ npm install express
      -
      - -
      -Agar `--save` orqali modullarni o'rnatsangiz u `package.json` faylidagi `dependencies` ro'yxatidagi qo'shiladi. -Dastur direktoriyasida `npm install` buyurug'ini bajarsangiz, dasturning barcha kerakli modullarni avtomatik tarzda o'rnatib beradi. -
      diff --git a/uz/starter/static-files.md b/uz/starter/static-files.md deleted file mode 100644 index 490e331c75..0000000000 --- a/uz/starter/static-files.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -layout: page -title: Expressda server statik fayllar -menu: starter -lang: uz ---- - -# Expressda server statik fayllar -Serverda statik fayllar bu rasmlar, CSS, JavaScript va fayllarni misol qilish mumkin, ular Expressda o'rnatilgan Expressda o'rnatilgan `express.static` middleware orqali ko'rsatiladi. - -Statik fayllarni qayerda joylashini ko'rsatish uchun `express.static` oraliq qayta ishlovchisiga direktoriya nomini jo'nating. -Masalan, siz o'z rasmlaringizni, CSS, JavaScriptlarni `public` direktoriyasida saqlamoqchi bo'lsangiz unda quyidagicha bo'ladi - -
      
      -app.use(express.static('public'));
      -
      - -Undan keyin `public` direktoriyasini ko'rsatmagan holda statik fayllarni yuklashingiz mumkin bo'ladi: - -
      
      -http://localhost:3000/images/kitten.jpg
      -http://localhost:3000/css/style.css
      -http://localhost:3000/js/app.js
      -http://localhost:3000/images/bg.png
      -http://localhost:3000/hello.html
      -
      - -
      -Fayllar faqat statik direktoriyadan qidiriladi, faylning nomi qanday bo'lishidan qaramay u statik fayl hisoblanadi, statik direktoriya esa URLga hech qanday ta'sir ko'rsatmaydi. -
      - -Agar siz ko'pgina direktoriyani statik qilmoqchi bo'lsangiz unda, `express.static` oraliq qayta ishlovchisini yana foydalanishingiz mumkin: - -
      
      -app.use(express.static('public'));
      -app.use(express.static('files'));
      -
      - -Fayllar ketma-ketlik bo'yicha statik direktoriyadan joy olishda va `express.static` orqali o'rnatiladi. - -Agar siz "virtual" (huddi manzil lekin fayl sistemada mavjud emas) fayllardan oldin prefix qo'shimchalik yaratmoqchi bo'lsangiz, `express.static` ikkita argument jo'nating, qo'shimcha ma'lumotni esa [bu yerdan](/4x/api.html#app.use) olishingiz mumkin bo'ladi. Ishlatishga misol esa: - -
      
      -app.use('/static', express.static('public'));
      -
      - -Endi esa `public` direktoriyansidagi statik fayllarni "/static" prefiksi orqali olinadi. - -
      
      -http://localhost:3000/static/images/kitten.jpg
      -http://localhost:3000/static/css/style.css
      -http://localhost:3000/static/js/app.js
      -http://localhost:3000/static/images/bg.png
      -http://localhost:3000/static/hello.html
      -
      -Agarda siz `express.static` orqali ko'rsatgan direktoriyangiz boshqa joyda ishga tushmasa, Siz uning absolyut manzilini ko'rsatishingiz kerak bo'ladi, masalan u mana bunday bo'ladi: - -
      
      -app.use('/static', express.static(__dirname + '/public'));
      -
      diff --git a/vulnerabilities.xml b/vulnerabilities.xml new file mode 100644 index 0000000000..d76816832b --- /dev/null +++ b/vulnerabilities.xml @@ -0,0 +1,10 @@ +--- +layout: feed +sitemap: false +title: Express Vulnerabilities +html_url: /en/blog/posts.html +--- +{% assign posts = site.posts | sort: "date" | reverse %} +{% for post in posts %} +{% if post.tags contains "vulnerabilities" %}{% include feed-entry.xml entry=post %}{% endif %} +{% endfor %} diff --git a/zh-cn/3x/api.md b/zh-cn/3x/api.md old mode 100755 new mode 100644 index 5e50b5fca9..022856d69a --- a/zh-cn/3x/api.md +++ b/zh-cn/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - API 参考 +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: zh-cn +redirect_from: " " --- +
      **Express 3.x 不再受到维护** - 自上次更新(2015 年 8 月 1 日)以来 3.x 中已知和未知的安全问题和性能问题都尚未处理。因此强烈建议您使用最新版本的 Express。 -
      - -

      3.x API

      +Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
      - - {% include api/en/3x/res.md %} +

      3.x API

      - - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %}
      diff --git a/zh-cn/4x/api.md b/zh-cn/4x/api.md old mode 100755 new mode 100644 index 4313c44f39..0c9d85d85b --- a/zh-cn/4x/api.md +++ b/zh-cn/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - API 参考 +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: zh-cn +redirect_from: " " --- +

      4.x API

      - - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
      diff --git a/zh-cn/5x/api.md b/zh-cn/5x/api.md new file mode 100644 index 0000000000..d5e3099230 --- /dev/null +++ b/zh-cn/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - API 参考 +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
      + +

      5.x API

      + +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
      diff --git a/zh-cn/advanced/best-practice-performance.md b/zh-cn/advanced/best-practice-performance.md old mode 100755 new mode 100644 index e17d9e57e3..9d9068e31b --- a/zh-cn/advanced/best-practice-performance.md +++ b/zh-cn/advanced/best-practice-performance.md @@ -1,110 +1,102 @@ --- layout: page title: 在生产环境中使用 Express 的性能最佳实践 +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: zh-cn +redirect_from: " " --- # 生产环境最佳实践:性能和可靠性 -## 概述 - 本文讨论了部署到生产环境的 Express 应用程序的性能和可靠性最佳实践。 -本主题明显属于“DevOps”范畴,涵盖了传统的开发和运行流程。因此,本信息也相应地分为两个部分: - -* [代码中的注意事项](#code)(开发部分)。 -* [环境/设置中的注意事项](#env)(运行部分)。 +This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: - +- [代码中的注意事项](#code)(开发部分)。 + - 通过 Gzip 压缩,有助于显著降低响应主体的大小,从而提高 Web 应用程序的速度。可使用[压缩](https://www.npmjs.com/package/compression)中间件进行 Express 应用程序中的 gzip 压缩。例如: + - 不使用同步函数 + - 正确进行日志记录 + - [Handle exceptions properly](#handle-exceptions-properly) +- Things to do in your environment / setup (the ops part): + - 将 NODE_ENV 设置为“production” + - Node 应用程序在遇到未捕获的异常时会崩溃。您需要确保应用程序经过彻底测试,能够处理所有异常,这一点最为重要(请参阅[正确处理异常](#exceptions)以了解详细信息)。但是,作为一种防故障措施,请实施一种机制,确保应用程序崩溃后可以自动重新启动。 + - 在集群应用程序中,个别工作进程的崩溃并不会影响其余的进程。除了性能优势,故障隔离是运行应用程序进程集群的另一原因。每当工作进程崩溃时,请确保始终使用 cluster.fork() 来记录事件并生成新进程。 + - 高速缓存请求结果 + - 使用负载均衡器 + - 逆向代理位于 Web 应用程序之前,除了将请求转发给应用程序外,还对请求执行支持性操作。它还可以处理错误页、压缩、高速缓存、文件服务和负载均衡等功能。 -## 代码中的注意事项 +## Things to do in your code {#in-code} 以下是为改进应用程序性能而在代码中要注意的事项: -* 使用 gzip 压缩 -* 不使用同步函数 -* 使用中间件提供静态文件 -* 正确进行日志记录 -* 正确处理异常 +- 通过 Gzip 压缩,有助于显著降低响应主体的大小,从而提高 Web 应用程序的速度。可使用[压缩](https://www.npmjs.com/package/compression)中间件进行 Express 应用程序中的 gzip 压缩。例如: +- 不使用同步函数 +- 正确进行日志记录 +- [Handle exceptions properly](#handle-exceptions-properly) ### 使用 gzip 压缩 -通过 Gzip 压缩,有助于显著降低响应主体的大小,从而提高 Web 应用程序的速度。可使用[压缩](https://www.npmjs.com/package/compression)中间件进行 Express 应用程序中的 gzip 压缩。例如: +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: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` -对于生产环境中的大流量网站,实施压缩的最佳位置是在反向代理层级(请参阅[使用反向代理](#proxy))。在此情况下,不需要使用压缩中间件。有关在 Nginx 中启用 gzip 压缩的详细信息,请参阅 Nginx 文档中的 [ngx_http_gzip_module 模块](http://nginx.org/en/docs/http/ngx_http_gzip_module.html)。 +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. 对于生产环境中的大流量网站,实施压缩的最佳位置是在反向代理层级(请参阅[使用反向代理](#proxy))。在此情况下,不需要使用压缩中间件。有关在 Nginx 中启用 gzip 压缩的详细信息,请参阅 Nginx 文档中的 [ngx_http_gzip_module 模块](http://nginx.org/en/docs/http/ngx_http_gzip_module.html)。 ### 不使用同步函数 -同步函数和方法会阻止执行进程的运行,直至其返回。对同步函数的每次调用可能在数微秒或数毫秒后返回,但是在大流量网站中,这些调用的累积返回时间也相当可观,会影响到应用程序的性能。因此应避免在生产环境中使用同步函数。 +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. -虽然 Node 和许多模块提供函数的同步和异步版本,但是在生产环境中请始终使用异步版本。只有在初始启动时才适合使用同步函数。 +虽然 Node 和许多模块提供函数的同步和异步版本,但是在生产环境中请始终使用异步版本。只有在初始启动时才适合使用同步函数。 The only time when a synchronous function can be justified is upon initial startup. -如果您使用 Node.js 4.0+ 或 io.js 2.1.0+,那么可以使用 `--trace-sync-io` 命令行标记,每当应用程序使用同步 API 时就显示一条警告消息和堆栈跟踪。当然,您不会希望在生产环境中实际使用此功能,这只是为了确保代码已准备好用于生产环境。请参阅 [node 命令行选项文档](https://nodejs.org/api/cli.html#cli_trace_sync_io)以了解更多信息。 +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#cli_trace_sync_io) for more information. -### 正确进行日志记录 +### 正确处理异常 -一般而言,从应用程序进行日志记录有两个原因:出于调试目的和出于记录应用程序活动目的(基本上就是除调试以外的其他所有事项)。通过使用 `console.log()` 或 `console.err()` 在终端上显示日志消息是开发过程中的常见做法。但是,如果目标是终端或文件,[这些函数就是同步的](https://nodejs.org/api/console.html#console_console_1),因此,除非要将输出通过管道传到另一个程序,否则上述函数就不适合用于生产环境。 +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 -如果您出于调试目的进行日志记录,请使用 [debug](https://www.npmjs.com/package/debug) 这样的特殊调试模块,而不要使用 `console.log()`。此模块支持您使用 DEBUG 环境变量来控制将哪些调试消息(如果有)发送到 `console.err()`。为了确保应用程序完全采用异步方式,仍需要将 `console.err()` 通过管道传到另一个程序。但您并不会真的希望在生产环境中进行调试,对吧? +如果您出于调试目的进行日志记录,请使用 [debug](https://www.npmjs.com/package/debug) 这样的特殊调试模块,而不要使用 `console.log()`。此模块支持您使用 DEBUG 环境变量来控制将哪些调试消息(如果有)发送到 `console.err()`。为了确保应用程序完全采用异步方式,仍需要将 `console.err()` 通过管道传到另一个程序。但您并不会真的希望在生产环境中进行调试,对吧? 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? #### 出于应用程序活动目的 -如果要对应用程序活动进行日志记录(例如,跟踪流量或 API 调用),请使用 [Winston](https://www.npmjs.com/package/winston) 或 [Bunyan](https://www.npmjs.com/package/bunyan) 之类的日志记录库,而不要使用 `console.log()`。要了解这两个库的详细对比,请参阅 StrongLoop 博客帖子 [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/)。 - - +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. ### 正确处理异常 -Node 应用程序在遇到未捕获的异常时会崩溃。不处理异常并采取相应的措施会导致 Express 应用程序崩溃并脱机。如果您按照以下[确保应用程序自动重新启动](#restart)中的建议执行,那么应用程序可以从崩溃中恢复。幸运的是,Express 应用程序的启动时间一般很短。然而,应当首先立足于避免崩溃,为此,需要正确处理异常。 +Node 应用程序在遇到未捕获的异常时会崩溃。不处理异常并采取相应的措施会导致 Express 应用程序崩溃并脱机。如果您按照以下[确保应用程序自动重新启动](#restart)中的建议执行,那么应用程序可以从崩溃中恢复。幸运的是,Express 应用程序的启动时间一般很短。然而,应当首先立足于避免崩溃,为此,需要正确处理异常。 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. 要确保处理所有异常,请使用以下方法: -* [使用 try-catch](#try-catch) -* [使用 promise](#promises) +- [使用 try-catch](#try-catch) +- [使用 promise](#promises) -在深入了解这些主题之前,应该对 Node/Express 错误处理有基本的了解:使用 error-first 回调并在中间件中传播错误。Node 将“error-first 回调”约定用于从异步函数返回错误,回调函数的第一个参数是错误对象,后续参数中包含结果数据。为了表明没有错误,可将 null 值作为第一个参数传递。回调函数必须相应地遵循“error-first”回调约定,以便有意义地处理错误。在 Express 中,最佳做法是使用 next() 函数,通过中间件链来传播错误。 +在深入了解这些主题之前,应该对 Node/Express 错误处理有基本的了解:使用 error-first 回调并在中间件中传播错误。Node 将“error-first 回调”约定用于从异步函数返回错误,回调函数的第一个参数是错误对象,后续参数中包含结果数据。为了表明没有错误,可将 null 值作为第一个参数传递。回调函数必须相应地遵循“error-first”回调约定,以便有意义地处理错误。在 Express 中,最佳做法是使用 next() 函数,通过中间件链来传播错误。 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. 有关错误处理基本知识的更多信息,请参阅: -* [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/)(StrongLoop 博客) - -#### 请勿执行以下操作 - -*请勿*侦听 `uncaughtException` 事件,当异常像气泡一样在事件循环中一路回溯时,就会发出该事件。为 `uncaughtException` 添加事件侦听器将改变进程遇到异常时的缺省行为;进程将继续运行而不理会异常。这貌似是防止应用程序崩溃的好方法,但是在遇到未捕获的异常之后仍继续运行应用程序是一种危险的做法,不建议这么做,因为进程状态可能会变得不可靠和不可预测。 - -此外,`uncaughtException` 被公认为[比较粗糙](https://nodejs.org/api/process.html#process_event_uncaughtexception),[建议](https://github.com/nodejs/node-v0.x-archive/issues/2582)从内核中将其移除。所以侦听 `uncaughtException` 并不是个好主意。这就是为何我们推荐诸如多个进程和虚拟机管理器之类的方案:崩溃后重新启动通常是从错误中恢复的最可靠方法。 - -我们也不建议使用[域](https://nodejs.org/api/domain.html)。它一般并不能解决问题,是一种不推荐使用的模块。 - - +- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### 使用 try-catch -Try-catch 是一种 JavaScript 语言构造,可用于捕获同步代码中的异常。例如,使用 try-catch 来处理 JSON 解析错误(如下所示)。 - -使用诸如 [JSHint](http://jshint.com/) 或 [JSLint](http://www.jslint.com/) 之类的工具有助于查找类似[未定义变量的引用错误](http://www.jshint.com/docs/options/#undef)这样的隐含异常。 +Try-catch 是一种 JavaScript 语言构造,可用于捕获同步代码中的异常。例如,使用 try-catch 来处理 JSON 解析错误(如下所示)。 Use try-catch, for example, to handle JSON parsing errors as shown below. -以下示例使用 try-catch 来处理潜在的进程崩溃异常。 -此中间件函数接受名为“params”的查询字段参数(JSON 对象)。 +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(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -113,167 +105,124 @@ app.get('/search', (req, res) => { }) ``` -然而,try-catch 仅适用于同步代码。而由于 Node 平台主要采用异步方式(尤其在生产环境中),因此 try-catch 不会捕获大量异常。 - - +However, try-catch works only for synchronous code. 然而,try-catch 仅适用于同步代码。而由于 Node 平台主要采用异步方式(尤其在生产环境中),因此 try-catch 不会捕获大量异常。 #### 使用 promise -Promise 可以处理使用 `then()` 的异步代码块中的任何异常(显式和隐式)。只需将 `.catch(next)` 添加到 Promise 链的末尾。例如: +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -现在,所有异步和同步错误都会传播到错误中间件。 - -然而,有两则警告: - -1. 所有异步代码必须返回 Promise(除了发射器)。如果特定库未返回 Promise,请使用类似 [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html) 的助手函数来转换基本对象。 -2. 事件发射器(比如流)仍然会导致未捕获的异常。所以请确保正确处理错误事件;例如: +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -有关使用 Promise 来处理错误的更多信息,请参阅: +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 -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +_请勿_侦听 `uncaughtException` 事件,当异常像气泡一样在事件循环中一路回溯时,就会发出该事件。为 `uncaughtException` 添加事件侦听器将改变进程遇到异常时的缺省行为;进程将继续运行而不理会异常。这貌似是防止应用程序崩溃的好方法,但是在遇到未捕获的异常之后仍继续运行应用程序是一种危险的做法,不建议这么做,因为进程状态可能会变得不可靠和不可预测。 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. - +此外,`uncaughtException` 被公认为[比较粗糙](https://nodejs.org/api/process.html#process_event_uncaughtexception),[建议](https://github.com/nodejs/node-v0.x-archive/issues/2582)从内核中将其移除。所以侦听 `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. + +我们也不建议使用[域](https://nodejs.org/api/domain.html)。它一般并不能解决问题,是一种不推荐使用的模块。 It generally doesn't solve the problem and is a deprecated module. ## 环境/设置中的注意事项 以下是为改进应用程序性能而在系统环境中要注意的事项: -* 将 NODE_ENV 设置为“production” -* 确保应用程序能够自动重新启动 -* 在集群中运行应用程序 -* 高速缓存请求结果 -* 使用负载均衡器 -* 使用逆向代理 +- 将 NODE_ENV 设置为“production” +- Node 应用程序在遇到未捕获的异常时会崩溃。您需要确保应用程序经过彻底测试,能够处理所有异常,这一点最为重要(请参阅[正确处理异常](#exceptions)以了解详细信息)。但是,作为一种防故障措施,请实施一种机制,确保应用程序崩溃后可以自动重新启动。 +- 在集群应用程序中,个别工作进程的崩溃并不会影响其余的进程。除了性能优势,故障隔离是运行应用程序进程集群的另一原因。每当工作进程崩溃时,请确保始终使用 cluster.fork() 来记录事件并生成新进程。 +- 高速缓存请求结果 +- 使用负载均衡器 +- 逆向代理位于 Web 应用程序之前,除了将请求转发给应用程序外,还对请求执行支持性操作。它还可以处理错误页、压缩、高速缓存、文件服务和负载均衡等功能。 ### 将 NODE_ENV 设置为“production” -NODE_ENV 环境变量指定运行应用程序的环境(通常是开发或者生产环境)。为了改进性能,最简单的方法是将 NODE_ENV 设置为“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`. 将 NODE_ENV 设置为“production”会使 Express: -* 高速缓存视图模板。 -* 高速缓存从 CSS 扩展生成的 CSS 文件。 -* 生成简短的错误消息。 - -[测试表明](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/)仅仅这样做就可以使应用程序性能提高 3 倍多! - -如果您需要编写特定于环境的代码,可以使用 `process.env.NODE_ENV` 来检查 NODE_ENV 的值。请注意,检查任何环境变量的值都会导致性能下降,所以应该三思而行。 +- 高速缓存视图模板。 +- 高速缓存从 CSS 扩展生成的 CSS 文件。 +- 生成简短的错误消息。 -在开发中,通常会在交互式 shell 中设置环境变量,例如,使用 `export` 或者 `.bash_profile` 文件。但是一般而言,您不应在生产服务器上执行此操作;而是应当使用操作系统的初始化系统(systemd 或 Upstart)。下一节提供如何使用初始化系统的常规详细信息,但是设置 NODE_ENV 对于性能非常重要(且易于操作),所以会在此重点介绍。 +[Tests indicate](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! -对于 Upstart,请使用作业文件中的 `env` 关键字。例如: +如果您需要编写特定于环境的代码,可以使用 `process.env.NODE_ENV` 来检查 NODE_ENV 的值。请注意,检查任何环境变量的值都会导致性能下降,所以应该三思而行。 Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. -
      -
      -# /etc/init/env.conf
      - env NODE_ENV=production
      -
      -
      +在开发中,通常会在交互式 shell 中设置环境变量,例如,使用 `export` 或者 `.bash_profile` 文件。但是一般而言,您不应在生产服务器上执行此操作;而是应当使用操作系统的初始化系统(systemd 或 Upstart)。下一节提供如何使用初始化系统的常规详细信息,但是设置 NODE_ENV 对于性能非常重要(且易于操作),所以会在此重点介绍。 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. -有关更多信息,请参阅 [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables)。 +对于 systemd,请使用单元文件中的 `Environment` 伪指令。例如: For example: -对于 systemd,请使用单元文件中的 `Environment` 伪指令。例如: - -
      -
      +```sh
       # /etc/systemd/system/myservice.service
       Environment=NODE_ENV=production
      -
      -
      - -有关更多信息,请参阅 [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html)。 +``` -如果在使用 StrongLoop Process Manager,还可以[在将 StrongLoop PM 作为服务安装时设置环境变量](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables)。 +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### 确保应用程序能够自动重新启动 -在生产环境中,您肯定不希望应用程序脱机。这意味着需要确保在应用程序崩溃的情况下以及服务器自身崩溃的情况下应用程序都能够重新启动。虽然您不希望这两种情况发生,但是必须未雨绸缪,以防不测: +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: -* 使用进程管理器在应用程序(和 Node)崩溃时将其重新启动。 -* 在操作系统崩溃时,使用操作系统提供的初始化系统重新启动进程管理器。还可以在没有进程管理器的情况下使用初始化系统。 +- 使用进程管理器在应用程序(和 Node)崩溃时将其重新启动。 +- 在操作系统崩溃时,使用操作系统提供的初始化系统重新启动进程管理器。还可以在没有进程管理器的情况下使用初始化系统。 It's also possible to use the init system without a process manager. -Node 应用程序在遇到未捕获的异常时会崩溃。您需要确保应用程序经过彻底测试,能够处理所有异常,这一点最为重要(请参阅[正确处理异常](#exceptions)以了解详细信息)。但是,作为一种防故障措施,请实施一种机制,确保应用程序崩溃后可以自动重新启动。 +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. #### 使用进程管理器 -在开发中,只需在命令行从 `node server.js` 或类似项启动应用程序。但是在生产环境中执行此操作会导致灾难。如果应用程序崩溃,它会脱机,直到其重新启动为止。为了确保应用程序在崩溃后可以重新启动,请使用进程管理器。进程管理器是一种应用程序“容器”,用于促进部署,提供高可用性,并支持用户在运行时管理应用程序。 +在开发中,只需在命令行从 `node server.js` 或类似项启动应用程序。但是在生产环境中执行此操作会导致灾难。如果应用程序崩溃,它会脱机,直到其重新启动为止。为了确保应用程序在崩溃后可以重新启动,请使用进程管理器。进程管理器是一种应用程序“容器”,用于促进部署,提供高可用性,并支持用户在运行时管理应用程序。 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. 除了在应用程序崩溃时将其重新启动外,进程管理器还可以执行以下操作: -* 获得对运行时性能和资源消耗的洞察。 -* 动态修改设置以改善性能。 -* 控制集群(StrongLoop PM 和 pm2)。 - -Node 的最流行进程管理器包括: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -要了解对这三种进程管理器的逐个功能的比较,请参阅 [http://strong-pm.io/compare/](http://strong-pm.io/compare/)。有关这所有三种进程管理器的更详细介绍,请参阅 [Express 应用程序的进程管理器](/{{ page.lang }}/advanced/pm.html)。 +- 获得对运行时性能和资源消耗的洞察。 +- 动态修改设置以改善性能。 +- Control clustering (pm2). -即使应用程序会不时崩溃,使用其中任何进程管理器都足以使其成功启动。 - -但 StrongLoop PM 有许多专门针对生产部署的功能。您可以使用该管理器以及相关的 StrongLoop 工具执行以下功能: - -* 在本地构建和打包应用程序,然后将其安全地部署到生产系统。 -* 在应用程序由于任何原因而崩溃时自动将其重新启动。 -* 远程管理集群。 -* 查看 CPU 概要文件和堆快照,以优化性能和诊断内存泄漏。 -* 查看应用程序的性能指标。 -* 轻松地扩展到具有 Nginx 负载均衡器集成控制的多个主机。 - -如以下所述,在使用初始化系统将 StrongLoop PM 作为操作系统服务安装后,StrongLoop PM 会在系统重新启动时自动重新启动。这样,就可以确保应用程序进程和集群持久保持运行。 +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. #### 使用初始化系统 -下一层的可靠性是确保在服务器重新启动时应用程序可以重新启动。系统仍然可能由于各种原因而宕机。为了确保在服务器崩溃后应用程序可以重新启动,请使用内置于操作系统的初始化系统。目前主要使用两种初始化系统:[systemd](https://wiki.debian.org/systemd) 和 [Upstart](http://upstart.ubuntu.com/)。 +下一层的可靠性是确保在服务器重新启动时应用程序可以重新启动。系统仍然可能由于各种原因而宕机。为了确保在服务器崩溃后应用程序可以重新启动,请使用内置于操作系统的初始化系统。目前主要使用两种初始化系统:[systemd](https://wiki.debian.org/systemd) 和 [Upstart](http://upstart.ubuntu.com/)。 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). 有两种方法将初始化系统用于 Express 应用程序: -* 在进程管理器中运行应用程序,使用初始化系统将进程管理器安装为服务。进程管理器将在应用程序崩溃时将其重新启动,初始化系统则在操作系统重新启动时重新启动进程管理器。这是建议使用的方法。 -* 通过初始化系统直接运行应用程序(和 Node)。这样做要简单些,但是无法发挥使用进程管理器的额外优点。 +- 在进程管理器中运行应用程序,使用初始化系统将进程管理器安装为服务。进程管理器将在应用程序崩溃时将其重新启动,初始化系统则在操作系统重新启动时重新启动进程管理器。这是建议使用的方法。 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 是一个 Linux 系统和服务管理器。大多数主要 Linux 分发版采用 systemd 作为其缺省初始化系统。 +Systemd 是一个 Linux 系统和服务管理器。大多数主要 Linux 分发版采用 systemd 作为其缺省初始化系统。 Most major Linux distributions have adopted systemd as their default init system. -systemd 服务配置文件称为*单元文件*,扩展名为 .service。以下是一个用于直接管理 Node 应用程序的单元文件示例(请将粗体文本替换为系统和应用程序的值): +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=Awesome Express App
      +Description=
       
       [Service]
       Type=simple
      -ExecStart=/usr/local/bin/node /projects/myapp/index.js
      -WorkingDirectory=/projects/myapp
      +ExecStart=/usr/local/bin/node 
      +WorkingDirectory=
       
       User=nobody
       Group=nogroup
      @@ -294,156 +243,68 @@ Restart=always
       
       [Install]
       WantedBy=multi-user.target
      -
      -
      -有关 systemd 的更多信息,请参阅 [systemd 参考(联机帮助页)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html)。 -##### 作为 systemd 服务的 StrongLoop PM - -可以轻松地将 StrongLoop Process Manager 作为 systemd 服务安装。这样做之后,当服务器重新启动时,它会自动重新启动 StrongLoop PM,后者又会重新启动所管理的所有应用程序。 - -要将 StrongLoop PM 作为 systemd 服务安装: - -
      -
      -$ sudo sl-pm-install --systemd
      -
      -
      - -使用以下命令启动此服务: - -
      -
      -$ sudo /usr/bin/systemctl start strong-pm
      -
      -
      - -有关更多信息,请参阅[Setting up a production host](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10)(StrongLoop 文档)。 - -##### Upstart - -Upstart 是在许多 Linux 分发版上提供的一种系统工具,用于在系统启动期间启动某些任务和服务,在系统关闭期间停止这些任务和服务,以及对这些任务和服务进行监督。可以将 Express 应用程序或进程管理器配置为服务,这样 Upstart 会在其崩溃时自动将其重新启动。 - -Upstart 服务以作业配置文件(也称为“作业”)形式定义,扩展名为 `.conf`。以下示例说明如何为名为“myapp”的应用程序创建名为“myapp”的作业,其主文件位于 `/projects/myapp/index.js`。 - -在 `/etc/init/` 中创建名为 `myapp.conf` 的文件,其中包含以下内容(请将粗体文本替换为系统和应用程序的值): - -
      -
      -# When to start the process
      -start on runlevel [2345]
      -
      -# When to stop the process
      -stop on runlevel [016]
      -
      -# Increase file descriptor limit to be able to handle more requests
      -limit nofile 50000 50000
      -
      -# Use production mode
      -env NODE_ENV=production
      -
      -# Run as www-data
      -setuid www-data
      -setgid www-data
      -
      -# Run from inside the app dir
      -chdir /projects/myapp
      -
      -# The process to start
      -exec /usr/local/bin/node /projects/myapp/index.js
      -
      -# Restart the process if it is down
      -respawn
      -
      -# Limit restart attempt to 10 times within 10 seconds
      -respawn limit 10 10
      -
      -
      - -注:此脚本需要 Ubuntu 12.04-14.10 上受支持的 Upstart 1.4 或更新版本。 - -由于此作业配置为在系统启动时运行,因此应用程序将随操作系统一起启动,并在应用程序崩溃或者系统宕机后自动重新启动。 - -除了自动重新启动此应用程序,Upstart 还支持您使用以下命令: - -* `start myapp` - 启动应用程序 -* `restart myapp` - 重新启动应用程序 -* `stop myapp` - 停止应用程序。 - -有关 Upstart 的更多信息,请参阅 [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook)。 - -##### 作为 Upstart 服务的 StrongLoop PM - -可以轻松地将 StrongLoop Process Manager 作为 Upstart 服务安装。这样做之后,当服务器重新启动时,它会自动重新启动 StrongLoop PM,后者又会重新启动所管理的所有应用程序。 - -要将 StrongLoop PM 作为 Upstart 1.4 服务安装: +``` -
      -
      -$ sudo sl-pm-install
      -
      -
      +有关 systemd 的更多信息,请参阅 [systemd 参考(联机帮助页)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html)。 -使用以下命令运行此服务: +### 在集群中运行应用程序 -
      -
      -$ sudo /sbin/initctl start strong-pm
      -
      -
      +在多核系统中,可以通过启动进程的集群,将 Node 应用程序的性能提升多倍。一个集群运行此应用程序的多个实例,理想情况下一个 CPU 核心上运行一个实例,从而在实例之间分担负载和任务。 A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. -注:在不支持 Upstart 1.4 的系统上,这些命令略有不同。请参阅 [Setting up a production host](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10)(StrongLoop 文档),以了解更新信息。 +![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](http://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. -在多核系统中,可以通过启动进程的集群,将 Node 应用程序的性能提升多倍。一个集群运行此应用程序的多个实例,理想情况下一个 CPU 核心上运行一个实例,从而在实例之间分担负载和任务。 +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(). - +#### 使用 Node 的集群模块 -重要信息:由于应用程序实例作为单独的进程运行,因此它们不会共享同一内存空间。也就是说,对象位于应用程序每个实例的本地。因此,无法在应用程序代码中保存状态。然而,可以使用 [Redis](http://redis.io/) 之类的内存中数据存储器来存储与会话相关的数据和状态。此警告适用于几乎所有形式的水平扩展(无论是多个进程的集群还是多个物理服务器的集群)。 +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. -在集群应用程序中,个别工作进程的崩溃并不会影响其余的进程。除了性能优势,故障隔离是运行应用程序进程集群的另一原因。每当工作进程崩溃时,请确保始终使用 cluster.fork() 来记录事件并生成新进程。 +#### Using PM2 -#### 使用 Node 的集群模块 +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). -可以使用 Node 的[集群模块](https://nodejs.org/docs/latest/api/cluster.html)来建立集群。这使主进程可以生成工作进程并在工作进程之间分配传入连接。然而,使用可以自动执行此操作的众多工具中的一种(例如 [node-pm](https://www.npmjs.com/package/node-pm) 或 [cluster-service](https://www.npmjs.com/package/cluster-service)),要比直接使用此模块好得多。 +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. -#### 使用 StrongLoop PM +To enable cluster mode, start your application like so: -如果将应用程序部署到 StrongLoop Process Manager (PM),那么可以利用集群*而不必*修改应用程序代码。 +```bash +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ pm2 start npm --name my-app -i max -- start +``` -如果使用 StrongLoop Process Manager (PM) 运行应用程序,它会在集群中自动运行此应用程序,所生成的工作进程数等于系统中的 CPU 核心数。您可以使用 slc 命令行工具手动更改集群中工作进程的数量,而不必停止应用程序。 +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. -例如,假设要将应用程序部署到 prod.foo.com,并且 StrongLoop PM 正在端口 8701(缺省值)上侦听,那么可使用 slc 将集群大小设置为 8: +Once running, the application can be scaled like so: -
      -
      -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
      -
      -
      +```bash +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ pm2 scale my-app 2 +``` -有关使用 StrongLoop PM 建立集群的更多信息,请参阅 StrongLoop 文档中的[集群](https://docs.strongloop.com/display/SLC/Clustering)。 +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. ### 高速缓存请求结果 提高生产环境性能的另一种策略是对请求的结果进行高速缓存,以便应用程序不需要为满足同一请求而重复执行操作。 -使用 [Varnish](https://www.varnish-cache.org/) 或 [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/)(另请参阅 [Nginx Caching](https://serversforhackers.com/nginx-caching/))之类的高速缓存服务器,可以显著提高应用程序的速度和性能。 +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### 使用负载均衡器 -无论应用程序如何优化,单个实例都只能处理有限的负载和流量。扩展应用程序的一种方法是运行此应用程序的多个实例,并通过负载均衡器分配流量。设置负载均衡器可以提高应用程序的性能和速度,并使可扩展性远超单个实例可以达到的水平。 - -负载均衡器通常是逆向代理,用于编排进出多个应用程序实例和服务器的流量。可以使用 [Nginx](http://nginx.org/en/docs/http/load_balancing.html) 或 [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts) 轻松地为应用程序设置负载均衡器。 - -对于负载均衡功能,可能必须确保与特定会话标识关联的请求连接到产生请求的进程。这称为*会话亲缘关系*或者*粘性会话*,可通过以上的建议来做到这一点:将 Redis 之类的数据存储器用于会话数据(取决于您的应用程序)。要了解相关讨论,请参阅 [Using multiple nodes](http://socket.io/docs/using-multiple-nodes/)。 +无论应用程序如何优化,单个实例都只能处理有限的负载和流量。扩展应用程序的一种方法是运行此应用程序的多个实例,并通过负载均衡器分配流量。设置负载均衡器可以提高应用程序的性能和速度,并使可扩展性远超单个实例可以达到的水平。 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. -#### 将 StrongLoop PM 与 Nginx 负载均衡器一起使用 +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). -[StrongLoop Process Manager](http://strong-pm.io/) 与 Nginx Controller 集成,从而能够方便地配置多主机生产环境配置。有关更多信息,请参阅 [Scaling to multiple servers](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers)(StrongLoop 文档)。 - +对于负载均衡功能,可能必须确保与特定会话标识关联的请求连接到产生请求的进程。这称为_会话亲缘关系_或者_粘性会话_,可通过以上的建议来做到这一点:将 Redis 之类的数据存储器用于会话数据(取决于您的应用程序)。要了解相关讨论,请参阅 [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/)。 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/). ### 使用逆向代理 -逆向代理位于 Web 应用程序之前,除了将请求转发给应用程序外,还对请求执行支持性操作。它还可以处理错误页、压缩、高速缓存、文件服务和负载均衡等功能。 +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. -通过将无需了解应用程序状态的任务移交给逆向代理,可以使 Express 腾出资源来执行专门的应用程序任务。因此,建议在生产环境中,在 [Nginx](https://www.nginx.com/) 或 [HAProxy](http://www.haproxy.org/) 之类的逆向代理背后运行 Express。 +通过将无需了解应用程序状态的任务移交给逆向代理,可以使 Express 腾出资源来执行专门的应用程序任务。因此,建议在生产环境中,在 [Nginx](https://www.nginx.com/) 或 [HAProxy](http://www.haproxy.org/) 之类的逆向代理背后运行 Express。 For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/zh-cn/advanced/best-practice-security.md b/zh-cn/advanced/best-practice-security.md old mode 100755 new mode 100644 index 7f1d85643e..65b67b5fd7 --- a/zh-cn/advanced/best-practice-security.md +++ b/zh-cn/advanced/best-practice-security.md @@ -1,81 +1,172 @@ --- layout: page title: 生产环境中 Express 的安全最佳实践 +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: zh-cn +redirect_from: " " --- # 生产环境最佳实践:安全 ## 概述 -术语*“生产”*表示软件生命周期中应用程序或 API 可供最终用户或使用者正常使用的阶段。而在*“开发”*阶段中,您仍然积极编写和测试代码,应用程序并未对外部开发访问。对应的系统环境分别被称为*生产*和*开发*环境。 +术语\*“生产”_表示软件生命周期中应用程序或 API 可供最终用户或使用者正常使用的阶段。而在_“开发”_阶段中,您仍然积极编写和测试代码,应用程序并未对外部开发访问。对应的系统环境分别被称为_生产_和_开发\*环境。 In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively. -开发和生产环境的设置通常不同,需求也天差地别。在开发环境中没问题的做法在生产环境中可能就无法接受。例如,在开发环境中,可能需要对错误进行详细日志记录以便进行调试,而同一行为在生产环境中可能会成为安全问题。在开发环境中,无需担心可扩展性、可靠性和性能,而这些方面在生产环境中就是关键问题。 +Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production. + +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} 本文讨论了部署到生产环境的 Express 应用程序的一些安全最佳实践。 +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - [hsts](https://github.com/helmetjs/hsts) 用于设置 `Strict-Transport-Security` 头,实施安全的服务器连接 (HTTP over SSL/TLS)。 + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) 用于移除 `X-Powered-By` 头。 + - [Reduce fingerprinting](#reduce-fingerprinting) + - `domain` - 表示 cookie 的域;用于和请求 URL 的服务器的域进行比较。如果匹配,那么接下来检查路径属性。 + - 相反,[cookie-session](https://www.npmjs.com/package/cookie-session) 中间件实现 cookie 支持的存储:它将整个会话序列化到 cookie 中,而不只是会话键。仅当会话数据相对较小,且易于编码为原语值(而不是对象)时,才使用此中间件。尽管假设浏览器支持每个 cookie 至少 4096 字节以确保不会超过限制,但是每个域的大小不会超过 4093 字节。另外请注意,客户机可以访问 cookie 数据,所以,如果有任何理由将其保持安全或隐藏状态,那么 express-session 可能是更好的选择。 + - 使用缺省会话 cookie 名称会使应用程序对攻击敞开大门。`X-Powered-By` 之类的值会造成问题:潜在攻击者可以利用这样的值对服务器采集“指纹”,并相应地确定攻击目标。 + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) + - 最后说明一点,和任何其他 Web 应用程序一样,Express 应用程序也容易受到各种基于 Web 的攻击。请熟悉已知的 [Web 漏洞](https://www.owasp.org/www-project-top-ten/)并采取相应的预防措施。 + - [Additional considerations](#additional-considerations) + ## 请勿使用不推荐或者存在漏洞的 Express 版本 -Express 2.x 和 3.x 不再得到维护。不会纠正这些版本中的安全问题和性能问题。请勿使用这些版本!如果您尚未迁移到 V4,请按照[迁移指南](/{{ page.lang }}/guide/migrating-4.html)进行迁移。 +Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html) or consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). -还请确保您未使用[安全性更新页面](/{{ page.lang }}/advanced/security-updates.html)中列出的任何存在漏洞的 Express 版本。如果在使用,请更新到某个稳定发行版,首选为最新版本。 +Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/{{ page.lang }}/advanced/security-updates.html). If you are, update to one of the stable releases, preferably the latest. ## 使用 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)。 +If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -您可能很熟悉安全套接字层 (SSL) 加密。[TLS 就是下一代的 SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx) 。换言之,如果您以前使用 SSL,请考虑升级到 TLS。一般而言,我们建议使用 Nginx 来处理 TLS。要获取在 Nginx(和其他服务器)上配置 TLS 的优秀参考信息,请参阅 [Recommended Server Configurations](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations) (Mozilla Wiki)。 +You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). 此外,可以使用一种方便的 [Let's Encrypt](https://letsencrypt.org/about/) 工具来获取免费的 TLS 证书,这是由[因特网安全研究组 (ISRG)](https://letsencrypt.org/isrg/) 提供的免费、自动化的开放式认证中心 (CA)。 +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## 使用 Helmet [Helmet](https://www.npmjs.com/package/helmet) 通过适当地设置 HTTP 头,帮助您保护应用程序避免一些众所周知的 Web 漏洞。 -Helmet 实际上只使用以下九个较小中间件函数的集合,这些功能用于设置与安全相关的 HTTP 头: +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* [csp](https://github.com/helmetjs/csp) 用于设置 `Content-Security-Policy` 头,帮助抵御跨站点脚本编制攻击和其他跨站点注入攻击。 -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) 用于移除 `X-Powered-By` 头。 -* [hsts](https://github.com/helmetjs/hsts) 用于设置 `Strict-Transport-Security` 头,实施安全的服务器连接 (HTTP over SSL/TLS)。 -* [ieNoOpen](https://github.com/helmetjs/ienoopen) 用于为 IE8+ 设置 `X-Download-Options`。 -* [noCache](https://github.com/helmetjs/nocache) 用于设置 `Cache-Control` 和 Pragma 头,以禁用客户端高速缓存。 -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) 用于设置 `X-Content-Type-Options`,以防止攻击者以 MIME 方式嗅探浏览器发出的响应中声明的 content-type。 -* [frameguard](https://github.com/helmetjs/frameguard) 用于设置 `X-Frame-Options` 头,提供 [clickjacking](https://www.owasp.org/index.php/Clickjacking) 保护。 -* [xssFilter](https://github.com/helmetjs/x-xss-protection) 用于设置 `X-XSS-Protection`,在最新的 Web 浏览器中启用跨站点脚本编制 (XSS) 过滤器。 +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. 像安装其他模块一样安装 Helmet: -
      -
      -$ npm install --save helmet
      -
      -
      +```bash +$ npm install helmet +``` 然后将其用于您的代码: -
      -
      -...
      -var helmet = require('helmet');
      -app.use(helmet());
      -...
      -
      -
      +```js +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... +``` + +## Reduce fingerprinting + +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. + +By default, Express sends the `X-Powered-By` response header that you can +disable using the `app.disable()` method: + +```js +app.disable('x-powered-by') +``` + +{% capture powered-advisory %} -### 至少禁用 X-Powered-By 头 +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. -如果不希望使用 Helmet,那么至少应禁用 `X-Powered-By` 头。攻击者可能会使用该头(缺省情况下已启用)来检测运行 Express 的应用程序,然后发动针对特定目标的攻击。 +{% endcapture %} -所以,最佳实践是使用 `app.disable()` 方法禁用此头: +{% include admonitions/note.html content=powered-advisory %} -
      -
      -app.disable('x-powered-by');
      -
      -
      +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): -如果使用 `helmet.js`,它会为您执行此功能。 +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## 安全地使用 cookie @@ -83,78 +174,109 @@ app.disable('x-powered-by'); 有两个主要的中间件 cookie 会话模块: -* [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` 中间件。 +- [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) 中间件将会话数据存储在服务器上;它仅将会话标识(而非会话数据)保存在 cookie 中。缺省情况下,它使用内存中存储,并不旨在用于生产环境。在生产环境中,需要设置可扩展的会话存储;请参阅[兼容的会话存储](https://github.com/expressjs/session#compatible-session-stores)列表。 +The main difference between these two modules is how they save cookie session data. 这两个模块之间的主要差异是它们保存 cookie 会话数据的方式。[express-session](https://www.npmjs.com/package/express-session) 中间件将会话数据存储在服务器上;它仅将会话标识(而非会话数据)保存在 cookie 中。缺省情况下,它使用内存中存储,并不旨在用于生产环境。在生产环境中,需要设置可扩展的会话存储;请参阅[兼容的会话存储](https://github.com/expressjs/session#compatible-session-stores)列表。 By default, it uses in-memory storage and is not designed for a production environment. 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 字节以确保不会超过限制,但是每个域的大小不会超过 4093 字节。另外请注意,客户机可以访问 cookie 数据,所以,如果有任何理由将其保持安全或隐藏状态,那么 express-session 可能是更好的选择。 +In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then `express-session` may be a better choice. ### 请勿使用缺省会话 cookie 名称 -使用缺省会话 cookie 名称会使应用程序对攻击敞开大门。`X-Powered-By` 之类的值会造成问题:潜在攻击者可以利用这样的值对服务器采集“指纹”,并相应地确定攻击目标。 +Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. 为避免此问题,请使用通用 cookie 名称;例如,使用 [express-session](https://www.npmjs.com/package/express-session) 中间件: -
      -
      -var session = require('express-session');
      +```js
      +const session = require('express-session')
       app.set('trust proxy', 1) // trust first proxy
      -app.use( session({
      -   secret : 's3Cur3',
      -   name : 'sessionId',
      -  })
      -);
      -
      -
      +app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) +``` ### 设置 cookie 安全性选项 设置以下 cookie 选项来增强安全性: -* `secure` - 确保浏览器只通过 HTTPS 发送 cookie。 -* `httpOnly` - 确保 cookie 只通过 HTTP(S)(而不是客户机 JavaScript)发送,这有助于防御跨站点脚本编制攻击。 -* `domain` - 表示 cookie 的域;用于和请求 URL 的服务器的域进行比较。如果匹配,那么接下来检查路径属性。 -* `path` - 表示 cookie 的路径;用于和请求路径进行比较。如果路径和域都匹配,那么在请求中发送 cookie。 -* `expires` - 用于为持久性 cookie 设置到期日期。 +- `secure` - 确保浏览器只通过 HTTPS 发送 cookie。 +- `httpOnly` - 确保 cookie 只通过 HTTP(S)(而不是客户机 JavaScript)发送,这有助于防御跨站点脚本编制攻击。 +- `domain` - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next. +- `path` - 表示 cookie 的路径;用于和请求路径进行比较。如果路径和域都匹配,那么在请求中发送 cookie。 If this and domain match, then send the cookie in the request. +- `expires` - 用于为持久性 cookie 设置到期日期。 以下是使用 [cookie-session](https://www.npmjs.com/package/cookie-session) 中间件的示例: -
      -
      -var session = require('cookie-session');
      -var express = require('express');
      -var app = express();
      +```js
      +const session = require('cookie-session')
      +const express = require('express')
      +const app = express()
       
      -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
      +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
       app.use(session({
         name: 'session',
         keys: ['key1', 'key2'],
      -  cookie: { secure: true,
      -            httpOnly: true,
      -            domain: 'example.com',
      -            path: 'foo/bar',
      -            expires: expiryDate
      -          }
      -  })
      -);
      -
      -
      + cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) +``` -## 其他注意事项 +## Prevent brute-force attacks against authorization + +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +1. The number of consecutive failed attempts by the same user name and IP address. +2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) + +## Ensure your dependencies are secure + +Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. -以下是来自非常出色的 [Node.js 安全核对表](https://blog.risingstack.com/node-js-security-checklist/)的一些进一步建议。请参阅此博客帖子以了解关于这些建议的所有详细信息: +Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. -* 实施速率限制,防止针对认证的暴力攻击。实现这一点的一种方式是使用 [StrongLoop API ](https://strongloop.com/node-js/api-gateway/)来强制实施速率限制策略。或者,可以使用诸如 [express-limiter](https://www.npmjs.com/package/express-limiter) 的中间件,但是这样做需要对代码作些修改。 -* 使用 [csurf](https://www.npmjs.com/package/csurf) 中间件来防御跨站点请求伪造 (CSRF)。 -* 始终过滤和净化用户输入,防御跨站点脚本编制 (XSS) 和命令注入攻击。 -* 使用参数化查询或预编译的语句来防御 SQL 注入攻击。 -* 使用开源的 [sqlmap](http://sqlmap.org/) 工具来检测应用程序中的 SQL 注入漏洞。 -* 使用 [nmap](https://nmap.org/) 和 [sslyze](https://github.com/nabla-c0d3/sslyze) 工具来测试 SSL 密码、密钥和重新协商的配置以及证书的有效性。 -* 使用 [safe-regex](https://www.npmjs.com/package/safe-regex) 来确保正则表达式不易受到[正则表达式拒绝服务](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)攻击。 +```bash +$ 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: + +```bash +$ npm install -g snyk +$ cd your-app +``` + +Use this command to test your application for vulnerabilities: + +```bash +$ snyk test +``` + +### 避免其他已知的漏洞 + +关注 [Node 安全项目](https://npmjs.com/advisories)公告,这可能会影响 Express 或应用程序使用的其他模块。一般而言,Node 安全项目是有关 Node 安全性的知识和工具的出色资源。 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. + +## 其他注意事项 -## 避免其他已知的漏洞 +以下是来自非常出色的 [Node.js 安全核对表](https://blog.risingstack.com/node-js-security-checklist/)的一些进一步建议。请参阅此博客帖子以了解关于这些建议的所有详细信息: Refer to that blog post for all the details on these recommendations: -关注 [Node 安全项目](https://npmjs.com/advisories)公告,这可能会影响 Express 或应用程序使用的其他模块。一般而言,Node 安全项目是有关 Node 安全性的知识和工具的出色资源。 +- 始终过滤和净化用户输入,防御跨站点脚本编制 (XSS) 和命令注入攻击。 +- 使用参数化查询或预编译的语句来防御 SQL 注入攻击。 +- 使用开源的 [sqlmap](http://sqlmap.org/) 工具来检测应用程序中的 SQL 注入漏洞。 +- 使用 [nmap](https://nmap.org/) 和 [sslyze](https://github.com/nabla-c0d3/sslyze) 工具来测试 SSL 密码、密钥和重新协商的配置以及证书的有效性。 +- 使用 [safe-regex](https://www.npmjs.com/package/safe-regex) 来确保正则表达式不易受到[正则表达式拒绝服务](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)攻击。 -最后说明一点,和任何其他 Web 应用程序一样,Express 应用程序也容易受到各种基于 Web 的攻击。请熟悉已知的 [Web 漏洞](https://www.owasp.org/index.php/Top_10_2013-Top_10)并采取相应的预防措施。 +[helmet]: <如果使用 `helmet.js`,它会为您执行此功能。> \ No newline at end of file diff --git a/zh-cn/advanced/developing-template-engines.md b/zh-cn/advanced/developing-template-engines.md old mode 100755 new mode 100644 index ed4ea5c2e5..bc8e4c886f --- a/zh-cn/advanced/developing-template-engines.md +++ b/zh-cn/advanced/developing-template-engines.md @@ -1,47 +1,46 @@ --- layout: page title: 为 Express 开发模板引擎 +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: zh-cn +redirect_from: " " --- # 为 Express 开发模板引擎 -可以使用 `app.engine(ext, callback)` 方法创建自己的模板引擎。`ext` 表示文件扩展名,而 `callback` 表示模板引擎函数,它接受以下项作为参数:文件位置、选项对象和回调函数。 +可以使用 `app.engine(ext, callback)` 方法创建自己的模板引擎。`ext` 表示文件扩展名,而 `callback` 表示模板引擎函数,它接受以下项作为参数:文件位置、选项对象和回调函数。 `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. 以下代码示例实现非常简单的模板引擎以呈现 `.ntl` 文件。 -
      -
      -var fs = require('fs'); // this engine requires the fs module
      -app.engine('ntl', function (filePath, options, callback) { // define the template engine
      -  fs.readFile(filePath, function (err, content) {
      -    if (err) return callback(new Error(err));
      +```js
      +const fs = require('fs') // this engine requires the fs module
      +app.engine('ntl', (filePath, options, callback) => { // define the template engine
      +  fs.readFile(filePath, (err, content) => {
      +    if (err) return callback(err)
           // this is an extremely simple template engine
      -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
      -    .replace('#message#', '

      '+ options.message +'

      '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
      -
      - -应用程序现在能够呈现 `.ntl` 文件。在 `views` 目录中创建名为 `index.ntl` 且包含以下内容的文件: - -
      -
      +    const rendered = content.toString()
      +      .replace('#title#', `${options.title}`)
      +      .replace('#message#', `

      ${options.message}

      `) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine +``` + +Your app will now be able to render `.ntl` files. 应用程序现在能够呈现 `.ntl` 文件。在 `views` 目录中创建名为 `index.ntl` 且包含以下内容的文件: + +```pug #title# #message# -
      -
      +``` + 然后,在应用程序中创建以下路径: -
      -
      -app.get('/', function (req, res) {
      -  res.render('index', { title: 'Hey', message: 'Hello there!'});
      -});
      -
      -
      -您向主页发出请求时,`index.ntl` 将呈现为 HTML。 + +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` + +您向主页发出请求时,`index.ntl` 将呈现为 HTML。 \ No newline at end of file diff --git a/zh-cn/advanced/healthcheck-graceful-shutdown.md b/zh-cn/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..b6eaa92bc0 --- /dev/null +++ b/zh-cn/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/zh-cn/advanced/pm.md b/zh-cn/advanced/pm.md deleted file mode 100755 index 89e9233a04..0000000000 --- a/zh-cn/advanced/pm.md +++ /dev/null @@ -1,283 +0,0 @@ ---- -layout: page -title: Express 应用程序的进程管理器 -menu: advanced -lang: zh-cn ---- - -# Express 应用程序的进程管理器 - -在生产环境中运行 Express 应用程序时,使用*进程管理器*对于完成以下任务很有帮助: - -- 在应用程序崩溃后将其重新启动。 -- 获得对运行时性能和资源消耗的洞察。 -- 动态修改设置以改善性能。 -- 控制集群。 - -进程管理器有点类似于应用程序服务器:它是应用程序的“容器”,可促进部署,提供高可用性并使您可以在运行时管理应用程序。 - -用于 Express 和其他 Node.js 应用程序的最流行的进程管理器包括: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -这三种工具都非常有用,但 StrongLoop Process Manager 是提供全面的运行时和部署解决方案的唯一工具,能够满足整个 Node.js 应用程序生命周期的需求,并在统一的界面中为生产前后的每一个步骤提供工具。 - -以下是对每种工具的简介。 -要获取详细的比较,请参阅 [http://strong-pm.io/compare/](http://strong-pm.io/compare/)。 - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) 是 Node.js 应用程序的生产进程管理器。StrongLoop PM 具有内置负载均衡、监控和多主机部署功能,还有一个图形控制台。 -可将 StrongLoop PM 用于以下任务: - -- 构建、打包 Node.js 应用程序并将其部署到本地或远程系统。 -- 查看 CPU 概要文件和堆快照,以优化性能和诊断内存泄漏。 -- 使进程和集群持久保持运行。 -- 查看应用程序的性能指标。 -- 使用 Nginx 集成轻松管理多主机部署。 -- 将多个 StrongLoop PM 统一到从 Arc 管理的分布式微服务运行时。 - -可以使用称为 `slc` 的强大命令行界面工具或者称为 Arc 的图形工具与 StrongLoop PM 协作。Arc 是开源的,由 StrongLoop 提供专业支持。 - -有关更多信息,请参阅 [http://strong-pm.io/](http://strong-pm.io/)。 - -完整文档: - -- [Operating Node apps](http://docs.strongloop.com/display/SLC)(StrongLoop 文档) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### 安装 -
      -
      -$ [sudo] npm install -g strongloop
      -
      -
      - -### 基本使用 -
      -
      -$ cd my-app
      -$ slc start
      -
      -
      - -查看进程管理器和所有部署的应用程序的状态: - -
      -
      -$ slc ctl
      -Service ID: 1
      -Service Name: my-app
      -Environment variables:
      -  No environment variables defined
      -Instances:
      -    Version  Agent version  Cluster size
      -     4.1.13      1.5.14           4
      -Processes:
      -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
      -    1.1.57692  57692   0
      -    1.1.57693  57693   1     0.0.0.0:3001
      -    1.1.57694  57694   2     0.0.0.0:3001
      -    1.1.57695  57695   3     0.0.0.0:3001
      -    1.1.57696  57696   4     0.0.0.0:3001
      -
      -
      - -列出受到管理的所有应用程序(服务): - -
      -
      -$ slc ctl ls
      -Id          Name         Scale
      - 1          my-app       1
      -
      -
      - -停止应用程序: - -
      -
      -$ slc ctl stop my-app
      -
      -
      - -重新启动应用程序: - -
      -
      -$ slc ctl restart my-app
      -
      -
      - -还可以“软重新启动”,这使工作进程有一个宽限期来关闭现有连接,然后重新启动当前应用程序: - -
      -
      -$ slc ctl soft-restart my-app
      -
      -
      - -要移除受到管理的应用程序: - -
      -
      -$ slc ctl remove my-app
      -
      -
      - -## PM2 - -PM2 是 Node.js 应用程序的生产进程管理器,具有内置的负载均衡器。PM2 可以使应用程序保持持久运行,无需宕机即可重新装入,并可以简化常见的系统管理任务。PM2 还使您可以管理应用程序记录、监控和集群。 - -有关更多信息,请参阅 [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2)。 - -### 安装 - -
      -
      -$ [sudo] npm install pm2 -g
      -
      -
      - -### 基本使用 - -在使用 `pm2` 命令启动应用程序时,必须指定应用程序的路径。但在停止、重新启动或删除应用程序时,只需指定应用程序的名称或标识。 - -
      -
      -$ pm2 start npm --name my-app -- start
      -[PM2] restartProcessId process id 0
      -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
      -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
      -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
      -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
      -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
      - Use the `pm2 show ` command to get more details about an app.
      -
      -
      - -使用 `pm2` 命令启动应用程序时,立即将应用程序发送到后台。可以使用各种 `pm2` 命令从命令行控制后台应用程序。 - -在使用 `pm2` 命令启动应用程序之后,会 PM2 的进程列表中使用标识注册该应用程序。因此,可以使用标识来管理系统上不同目录中的同名应用程序。 - -请注意,如果有多个同名的应用程序在运行,那么 `pm2` 命令会影响所有这些应用程序。所以请使用标识而不是名称来管理各个应用程序。 - -列出所有正在运行的进程: - -
      -
      -$ pm2 list
      -
      -
      - -停止应用程序: - -
      -
      -$ pm2 stop 0
      -
      -
      - -重新启动应用程序: - -
      -
      -$ pm2 restart 0
      -
      -
      - -要查看关于应用程序的详细信息: - -
      -
      -$ pm2 show 0
      -
      -
      - -要从 PM2 的注册表移除应用程序: - -
      -
      -$ pm2 delete 0
      -
      -
      - - -## Forever - -Forever 是一种简单的命令行界面工具,用于确保特定脚本持续(永久)运行。Forever 的简单界面使其成为运行 Node.js 应用程序和脚本的较小部署的理想选择。 - -有关更多信息,请参阅 [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever)。 - -### 安装 - -
      -
      -$ [sudo] npm install forever -g
      -
      -
      - -### 基本使用 - -要启动脚本,请使用 `forever start` 命令并指定脚本的路径: - -
      -
      -$ forever start script.js
      -
      -
      - -此命令(在后台)以守护程序方式运行脚本。 - -要运行脚本以便其附加到终端,请省略 `start`: - -
      -
      -$ forever script.js
      -
      -
      - -使用日志记录选项 `-l`、`-o` 和 `-e`(如此示例中所示)记录来自 Forever 工具和脚本的输出,是很好的构想: - -
      -
      -$ forever start -l forever.log -o out.log -e err.log script.js
      -
      -
      - -要查看 Forever 启动的脚本的列表: - -
      -
      -$ forever list
      -
      -
      - -要停止由 Forever 启动的脚本,请使用 `forever stop` 命令并指定进程索引(如 `forever list` 命令所列出)。 - -
      -
      -$ forever stop 1
      -
      -
      - -或者,指定文件的路径: - -
      -
      -$ forever stop script.js
      -
      -
      - -要停止 Forever 启动的所有脚本: - -
      -
      -$ forever stopall
      -
      -
      - -Forever 还有许多其他选项,还提供编程 API。 diff --git a/zh-cn/advanced/security-updates.md b/zh-cn/advanced/security-updates.md old mode 100755 new mode 100644 index 33b084ad63..73fc38e8cb --- a/zh-cn/advanced/security-updates.md +++ b/zh-cn/advanced/security-updates.md @@ -1,44 +1,89 @@ --- layout: page title: Express 安全性更新 +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: zh-cn +redirect_from: " " --- # 安全更新
      -Node.js 漏洞直接影响 Express。因此,请[监视 Node.js 漏洞](http://blog.nodejs.org/vulnerability/)并确保使用最新稳定版的 Node.js。 +Node.js vulnerabilities directly affect Express. +Node.js 漏洞直接影响 Express。因此,请[监视 Node.js 漏洞](https://nodejs.org +/en/blog/vulnerability/)并确保使用最新稳定版的 Node.js。 +
      以下列举了在指定版本更新中修复的 Express 漏洞。 +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} + ## 4.x - * 4.11.1 - * 修复了 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路径披露漏洞 - * 4.10.7 - * 在 `express.static`([公告](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中修复了开放重定向漏洞。 - * 4.8.8 - * 在 `express.static`([公告](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` 错误和服务器无响应。 - * 4.8.0 - * 查询字符串中具有极高数量索引的稀疏数组会导致进程耗尽内存并使服务器崩溃。 - * 极端嵌套查询字符串对象会导致进程阻塞并使服务器暂时无响应。 +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. + - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. +- 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +- 4.15.2 + - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - 修复了 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路径披露漏洞 +- 4.10.7 + - 在 `express.static`([公告](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中修复了开放重定向漏洞。 +- 4.8.8 + - 在 `express.static`([公告](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` 错误和服务器无响应。 Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. +- 4.8.0 + - 查询字符串中具有极高数量索引的稀疏数组会导致进程耗尽内存并使服务器崩溃。 + - 极端嵌套查询字符串对象会导致进程阻塞并使服务器暂时无响应。 ## 3.x - * 3.19.1 - * 修复了 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路径披露漏洞 - * 3.19.0 - * 在 `express.static`([公告](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中修复了开放重定向漏洞。 - * 3.16.10 - * 在 `express.static` 中修复了目录遍历漏洞。 - * 3.16.6 - * Node.js 0.10 在某些情况下可能会泄漏 `fd`,这会影响 `express.static` 和 `res.sendfile`。恶意请求会导致 `fd` 泄漏并最终导致 `EMFILE` 错误和服务器无响应。 - * 3.16.0 - * 查询字符串中具有极高数量索引的稀疏数组会导致进程耗尽内存并使服务器崩溃。 - * 极端嵌套查询字符串对象会导致进程阻塞并使服务器暂时无响应。 - * 3.3.0 - * 不受支持的方法覆盖尝试的 404 响应易于受到跨站点脚本编制攻击。 +
      + **Express 3.x 不再受到维护** + +Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. + +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). + +
      + +- 3.19.1 + - 修复了 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路径披露漏洞 +- 3.19.0 + - 在 `express.static`([公告](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中修复了开放重定向漏洞。 +- 3.16.10 + - 在 `express.static` 中修复了目录遍历漏洞。 +- 3.16.6 + - Node.js 0.10 在某些情况下可能会泄漏 `fd`,这会影响 `express.static` 和 `res.sendfile`。恶意请求会导致 `fd` 泄漏并最终导致 `EMFILE` 错误和服务器无响应。 Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. +- 3.16.0 + - 查询字符串中具有极高数量索引的稀疏数组会导致进程耗尽内存并使服务器崩溃。 + - 极端嵌套查询字符串对象会导致进程阻塞并使服务器暂时无响应。 +- 3.3.0 + - 不受支持的方法覆盖尝试的 404 响应易于受到跨站点脚本编制攻击。 \ No newline at end of file diff --git a/zh-cn/api.md b/zh-cn/api.md old mode 100755 new mode 100644 index d8b0e1eea7..7eac63a8f4 --- a/zh-cn/api.md +++ b/zh-cn/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - API 参考 -lang: zh-cn +layout: api +version: 5x +title: Express 5.x - API 参考 +description: 访问 Express.js API 参考文档,获取当前版本所有模块、方法及属性的详细说明,助您构建 Web 应用。 +menu: api +redirect_from: " " --- -
      - -

      4.x API

      - - - {% include api/en/4x/express.md %} +
      +

      5.x API

      + {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
      diff --git a/zh-cn/changelog/index.md b/zh-cn/changelog/index.md new file mode 100644 index 0000000000..2456265b18 --- /dev/null +++ b/zh-cn/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
      + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
        +
      • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
        +
      • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
        +
      • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
        +
      • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
      • + +
      • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
      • + +
      • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
      • + +
      • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
      • + +
      • + Starting with this version, Express supports Node.js 18.x. +
      • + +
      • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
      • + +
      • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
      • + +
      • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
      • + +
      • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
      • + +
      • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
      • + +
      • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
        +
      • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
        +
      • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
      • + +
      • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
      • + +
      • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
      • + +
      • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
      • + +
      • + Starting with this version, Express supports Node.js 14.x. +
      • + +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
        +
      • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
        +
      • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
      • + +
      • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
      • + +
      • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
      • + +
      • + Starting with this version, Express supports Node.js 10.x and 12.x. +
      • + +
      • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
      • + +
      • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
        +
      • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
        +
      • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
      • + +
      • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
      • + +
      • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
        +
      • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
        +
      • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
        +
      • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
      • + +
      • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
      • + +
      • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
      • + +
      • + Starting with this version, Express supports Node.js 8.x. +
      • + +
      • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
      • + +
      • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
      • + +
      • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
      • + +
      • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
      • + +
      • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
        +
      • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
      • + +
      • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
      • + +
      • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
        +
      • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
        +
      • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
      • + +
      • + Fix error when `res.set` cannot add charset to `Content-Type`. +
      • + +
      • + Fix missing `` in HTML document. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
        +
      • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
        +
      • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
        +
      • + Starting with this version, Express supports Node.js 7.x. +
      • + +
      • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
      • + +
      • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
      • + +
      • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
        +
      • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
        +
      • + Starting with this version, Express supports Node.js 6.x. +
      • + +
      • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
      • + +
      • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
      • + +
      • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
      • + +
      • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
      • + +
      • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
      • + +
      • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
      • + +
      • + IP address resolution with proxies has been greatly improved. +
      • + +
      • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
      • +
      + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
      diff --git a/zh-cn/guide/behind-proxies.md b/zh-cn/guide/behind-proxies.md old mode 100755 new mode 100644 index 59d1ad3c9d..18403e9483 --- a/zh-cn/guide/behind-proxies.md +++ b/zh-cn/guide/behind-proxies.md @@ -1,18 +1,21 @@ --- layout: page title: 代理背后的 Express +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: zh-cn +redirect_from: " " --- # 代理背后的 Express -在代理背后运行 Express 应用程序时,可使用 [app.set()](/{{ page.lang }}/4x/api.html#app.set) 将应用程序变量 `trust proxy` 设置为下表中所列的某个值。 +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
      -尽管不设置应用程序变量 `trust proxy` 该应用程序也不会运行失败,但是它会误将代理的 IP 地址注册为客户机 IP 地址(除非配置了 `trust proxy`)。 +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
      +在代理背后运行 Express 应用程序时,可使用 [app.set()](/{{ page.lang }}/4x/api.html#app.set) 将应用程序变量 `trust proxy` 设置为下表中所列的某个值。 + @@ -21,58 +24,74 @@ lang: zh-cn - + - +
      类型
      如果为 `true`,那么客户机的 IP 地址将用作 `X-Forwarded-*` 头中最左侧的条目。 如果为 `false`,那么该应用程序将被视为直接面对因特网,而客户机的 IP 地址则派生自 `req.connection.remoteAddress`。这是缺省设置。 + + +If `false`, the app is understood as directly facing the client and the client's IP address is derived from `req.socket.remoteAddress`. This is the default setting. + +
      +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
      IP 地址IP addresses -要信任的 IP 地址、子网或者一组 IP 地址与子网。以下列表显示预先配置的子网名称: -* loopback - `127.0.0.1/8` 或 `::1/128` -* linklocal - `169.254.0.0/16` 或 `fe80::/10` -* uniquelocal - `10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16` 或 `fc00::/7` +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: + +- loopback - `127.0.0.1/8`, `::1/128` +- linklocal - `169.254.0.0/16`, `fe80::/10` +- uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` 您可以按以下某种方法设置 IP 地址: -
      -app.set('trust proxy', 'loopback') // specify a single subnet
      +```js
      +app.set('trust proxy', 'loopback') // specify a single subnet
       app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
       app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
      -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
      -
      +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` + +如果指定 IP 地址或子网,那么会在地址确定过程中排除这些项,而将最接近应用程序服务器的不受信任的 IP 地址确定为客户机的 IP 地址。 This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. -如果指定 IP 地址或子网,那么会在地址确定过程中排除这些项,而将最接近应用程序服务器的不受信任的 IP 地址确定为客户机的 IP 地址。
      数字 -信任来自正面代理服务器的第 `n` 个中继段,以此作为客户机。 +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. + +
      +When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
      函数Function -定制信任实现。仅当您知道自己要做什么时,方可使用该选项。 -
      -app.set('trust proxy', function (ip) {
      -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
      -  else return false;
      -});
      -
      +Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
      -设置非 `false` `trust proxy` 值会导致三个重大变化: +Enabling `trust proxy` will have the following impact:
      • [req.hostname](/{{ page.lang }}/api.html#req.hostname) 的值派生自 `X-Forwarded-Host` 头中设置的值(可以由客户机或代理设置此值)。
      • `X-Forwarded-Proto` 可以由逆向代理设置,以告知应用程序:它是 `https` 还是 `http`,或者甚至是无效名称。该值由 [req.protocol](/{{ page.lang }}/api.html#req.protocol) 反映。 + This value is reflected by [req.protocol](/{{ page.lang }}/api.html#req.protocol).
      • [req.ip](/{{ page.lang }}/api.html#req.ip) 和 [req.ips](/{{ page.lang }}/api.html#req.ips) 值由 `X-Forwarded-For` 的地址列表填充。
      -`trust proxy` 设置由使用 [proxy-addr](https://www.npmjs.com/package/proxy-addr) 包实现。有关更多信息,请参阅其文档。 +`trust proxy` 设置由使用 [proxy-addr](https://www.npmjs.com/package/proxy-addr) 包实现。有关更多信息,请参阅其文档。 For more information, see its documentation. diff --git a/zh-cn/guide/database-integration.md b/zh-cn/guide/database-integration.md old mode 100755 new mode 100644 index 9b8e4928ef..67ec99eef5 --- a/zh-cn/guide/database-integration.md +++ b/zh-cn/guide/database-integration.md @@ -1,30 +1,34 @@ --- layout: page title: Express 数据库集成 +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: zh-cn +redirect_from: " " --- # 数据库集成 -要将数据库连接到 Express 应用程序,只需在该应用程序中为数据库装入相应的 Node.js 驱动程序。本文档简要说明如何在 Express 应用程序中为数据库系统添加和使用某些最流行的 Node.js 模块: - -* [Cassandra](#cassandra) -* [Couchbase](#couchbase) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongodb) -* [Neo4j](#neo4j) -* [Oracle](#oracle) -* [PostgreSQL](#postgresql) -* [Redis](#redis) -* [SQL Server](#sql-server) -* [SQLite](#sqlite) -* [Elasticsearch](#elasticsearch) +要将数据库连接到 Express 应用程序,只需在该应用程序中为数据库装入相应的 Node.js 驱动程序。本文档简要说明如何在 Express 应用程序中为数据库系统添加和使用某些最流行的 Node.js 模块: This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app: + +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongodb) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgresql) +- [Redis](#redis) +- [SQL Server](#sql-server) +- [SQLite](#sqlite) +- [Elasticsearch](#elasticsearch)
      + 这些数据库驱动程序是众多可用数据库驱动程序的一部分。要了解其他选项,请在 [npm](https://www.npmjs.com/) 站点上搜索。 + For other options, +search on the [npm](https://www.npmjs.com/) site.
      ## Cassandra @@ -33,17 +37,17 @@ lang: zh-cn ### 安装 -```sh +```bash $ npm install cassandra-driver ``` ### 示例 ```js -var cassandra = require('cassandra-driver') -var client = new cassandra.Client({ contactPoints: ['localhost'] }) +const cassandra = require('cassandra-driver') +const client = new cassandra.Client({ contactPoints: ['localhost'] }) -client.execute('select key from system.local', function (err, result) { +client.execute('select key from system.local', (err, result) => { if (err) throw err console.log(result.rows[0]) }) @@ -55,18 +59,18 @@ client.execute('select key from system.local', function (err, result) { ### 安装 -```sh +```bash $ npm install couchbase ``` ### 示例 ```js -var couchbase = require('couchbase') -var bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') +const couchbase = require('couchbase') +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') // add a document to a bucket -bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, result) { +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { if (err) { console.log(err) } else { @@ -75,9 +79,9 @@ bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, res }) // get all documents with shoe size 13 -var n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' -var query = N1qlQuery.fromString(n1ql) -bucket.query(query, [13], function (err, result) { +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { if (err) { console.log(err) } else { @@ -92,19 +96,19 @@ bucket.query(query, [13], function (err, result) { ### 安装 -```sh +```bash $ npm install nano ``` ### 示例 ```js -var nano = require('nano')('http://localhost:5984') +const nano = require('nano')('http://localhost:5984') nano.db.create('books') -var books = nano.db.use('books') +const books = nano.db.use('books') // Insert a book document in the books database -books.insert({ name: 'The Art of war' }, null, function (err, body) { +books.insert({ name: 'The Art of war' }, null, (err, body) => { if (err) { console.log(err) } else { @@ -113,7 +117,7 @@ books.insert({ name: 'The Art of war' }, null, function (err, body) { }) // Get a list of all books -books.list(function (err, body) { +books.list((err, body) => { if (err) { console.log(err) } else { @@ -128,23 +132,23 @@ books.list(function (err, body) { ### 安装 -```sh +```bash $ npm install level levelup leveldown ``` ### 示例 ```js -var levelup = require('levelup') -var db = levelup('./mydb') +const levelup = require('levelup') +const db = levelup('./mydb') -db.put('name', 'LevelUP', function (err) { +db.put('name', 'LevelUP', (err) => { if (err) return console.log('Ooops!', err) - db.get('name', function (err, value) { + db.get('name', (err, value) => { if (err) return console.log('Ooops!', err) - console.log('name=' + value) + console.log(`name=${value}`) }) }) ``` @@ -155,15 +159,15 @@ db.put('name', 'LevelUP', function (err) { ### 安装 -```sh +```bash $ npm install mysql ``` ### 示例 ```js -var mysql = require('mysql') -var connection = mysql.createConnection({ +const mysql = require('mysql') +const connection = mysql.createConnection({ host: 'localhost', user: 'dbuser', password: 's3kreee7', @@ -172,7 +176,7 @@ var connection = mysql.createConnection({ connection.connect() -connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) { +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => { if (err) throw err console.log('The solution is: ', rows[0].solution) @@ -187,19 +191,19 @@ connection.end() ### 安装 -```sh +```bash $ npm install mongodb ``` -### 示例(v2.*) +### 示例(v2.\*) ```js -var MongoClient = require('mongodb').MongoClient +const MongoClient = require('mongodb').MongoClient -MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { if (err) throw err - db.collection('mammals').find().toArray(function (err, result) { + db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) @@ -207,17 +211,17 @@ MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) { }) ``` -### 示例(v3.*) +### 示例(v3.\*) ```js -var MongoClient = require('mongodb').MongoClient +const MongoClient = require('mongodb').MongoClient -MongoClient.connect('mongodb://localhost:27017/animals', function (err, client) { +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { if (err) throw err - var db = client.db('animals') + const db = client.db('animals') - db.collection('mammals').find().toArray(function (err, result) { + db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) @@ -229,27 +233,31 @@ MongoClient.connect('mongodb://localhost:27017/animals', function (err, client) ## Neo4j -**模块**:[apoc](https://github.com/hacksparrow/apoc) +**Module**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver) ### 安装 -```sh -$ npm install apoc +```bash +$ npm install neo4j-driver ``` ### 示例 ```js -var apoc = require('apoc') - -apoc.query('match (n) return n').exec().then( - function (response) { - console.log(response) - }, - function (fail) { - console.log(fail) - } -) +const neo4j = require('neo4j-driver') +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) + +const session = driver.session() + +session.readTransaction((tx) => { + return tx.run('MATCH (n) RETURN count(n) AS count') + .then((res) => { + console.log(res.records[0].get('count')) + }) + .catch((error) => { + console.log(error) + }) +}) ``` ## Oracle @@ -258,9 +266,9 @@ apoc.query('match (n) return n').exec().then( ### 安装 - 注意: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). +注意: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). -```sh +```bash $ npm install oracledb ``` @@ -300,25 +308,25 @@ getEmployee(101) ## PostgreSQL -**模块**:[pg](https://github.com/brianc/node-postgres) +**Module**: [pg-promise](https://github.com/vitaly-t/pg-promise) ### 安装 -```sh +```bash $ npm install pg-promise ``` ### 示例 ```js -var pgp = require('pg-promise')(/* options */) -var db = pgp('postgres://username:password@host:port/database') +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') db.one('SELECT $1 AS value', 123) - .then(function (data) { + .then((data) => { console.log('DATA:', data.value) }) - .catch(function (error) { + .catch((error) => { console.log('ERROR:', error) }) ``` @@ -329,29 +337,29 @@ db.one('SELECT $1 AS value', 123) ### 安装 -```sh +```bash $ npm install redis ``` ### 示例 ```js -var redis = require('redis') -var client = redis.createClient() +const redis = require('redis') +const client = redis.createClient() -client.on('error', function (err) { - console.log('Error ' + err) +client.on('error', (err) => { + console.log(`Error ${err}`) }) client.set('string key', 'string val', redis.print) client.hset('hash key', 'hashtest 1', 'some value', redis.print) client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print) -client.hkeys('hash key', function (err, replies) { - console.log(replies.length + ' replies:') +client.hkeys('hash key', (err, replies) => { + console.log(`${replies.length} replies:`) - replies.forEach(function (reply, i) { - console.log(' ' + i + ': ' + reply) + replies.forEach((reply, i) => { + console.log(` ${i}: ${reply}`) }) client.quit() @@ -364,17 +372,17 @@ client.hkeys('hash key', function (err, replies) { ### 安装 -```sh +```bash $ npm install tedious ``` ### 示例 ```js -var Connection = require('tedious').Connection -var Request = require('tedious').Request +const Connection = require('tedious').Connection +const Request = require('tedious').Request -var config = { +const config = { server: 'localhost', authentication: { type: 'default', @@ -385,9 +393,9 @@ var config = { } } -var connection = new Connection(config) +const connection = new Connection(config) -connection.on('connect', function (err) { +connection.on('connect', (err) => { if (err) { console.log(err) } else { @@ -396,17 +404,17 @@ connection.on('connect', function (err) { }) function executeStatement () { - request = new Request("select 123, 'hello world'", function (err, rowCount) { + request = new Request("select 123, 'hello world'", (err, rowCount) => { if (err) { console.log(err) } else { - console.log(rowCount + ' rows') + console.log(`${rowCount} rows`) } connection.close() }) - request.on('row', function (columns) { - columns.forEach(function (column) { + request.on('row', (columns) => { + columns.forEach((column) => { if (column.value === null) { console.log('NULL') } else { @@ -425,28 +433,28 @@ function executeStatement () { ### 安装 -```sh +```bash $ npm install sqlite3 ``` ### 示例 ```js -var sqlite3 = require('sqlite3').verbose() -var db = new sqlite3.Database(':memory:') +const sqlite3 = require('sqlite3').verbose() +const db = new sqlite3.Database(':memory:') -db.serialize(function () { +db.serialize(() => { db.run('CREATE TABLE lorem (info TEXT)') - var stmt = db.prepare('INSERT INTO lorem VALUES (?)') + const stmt = db.prepare('INSERT INTO lorem VALUES (?)') - for (var i = 0; i < 10; i++) { - stmt.run('Ipsum ' + i) + for (let i = 0; i < 10; i++) { + stmt.run(`Ipsum ${i}`) } stmt.finalize() - db.each('SELECT rowid AS id, info FROM lorem', function (err, row) { - console.log(row.id + ': ' + row.info) + db.each('SELECT rowid AS id, info FROM lorem', (err, row) => { + console.log(`${row.id}: ${row.info}`) }) }) @@ -459,15 +467,15 @@ db.close() ### 安装 -```sh +```bash $ npm install elasticsearch ``` ### 示例 ```js -var elasticsearch = require('elasticsearch') -var client = elasticsearch.Client({ +const elasticsearch = require('elasticsearch') +const client = elasticsearch.Client({ host: 'localhost:9200' }) @@ -482,9 +490,9 @@ client.search({ } } } -}).then(function (response) { - var hits = response.hits.hits -}, function (error) { +}).then((response) => { + const hits = response.hits.hits +}, (error) => { console.trace(error.message) }) ``` diff --git a/zh-cn/guide/debugging.md b/zh-cn/guide/debugging.md old mode 100755 new mode 100644 index 90dd8cf228..91960fd866 --- a/zh-cn/guide/debugging.md +++ b/zh-cn/guide/debugging.md @@ -1,38 +1,28 @@ --- layout: page title: 调试 Express +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: zh-cn +redirect_from: " " --- # 调试 Express -Express 在内部使用[调试](https://www.npmjs.com/package/debug)模块来记录关于路由匹配、使用的中间件函数、应用程序模式以及请求/响应循环流程的信息。 - -
      -`debug` 就像是扩充版的 `console.log`,但是与 `console.log` 不同,您不必注释掉生产代码中的 `debug` 日志。缺省情况下,日志记录功能已关闭,可以使用 `DEBUG` 环境变量有条件地开启日志记录。 -
      - 要查看 Express 中使用的所有内部日志,在启动应用程序时,请将 `DEBUG` 环境变量设置为 `express:*`。 -
      -
      +```bash
       $ DEBUG=express:* node index.js
      -
      -
      +``` 在 Windows 上,使用对应的命令。 -
      -
      -> set DEBUG=express:* & node index.js
      -
      -
      +```bash +> $env:DEBUG = "express:*"; node index.js +``` 在 [Express 生成器](/{{ page.lang }}/starter/generator.html)所生成的缺省应用程序上运行此命令将显示以下输出: -
      -
      +```bash
       $ DEBUG=express:* node ./bin/www
         express:router:route new / +0ms
         express:router:layer new / +1ms
      @@ -68,19 +58,17 @@ $ DEBUG=express:* node ./bin/www
         express:router:layer new / +1ms
         express:router use /users router +0ms
         express:router:layer new /users +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -  express:router use / <anonymous> +0ms
      +  express:router use / &lt;anonymous&gt; +0ms
         express:router:layer new / +0ms
      -
      -
      +``` 向应用程序发出请求时,可以看到 Express 代码中指定的日志: -
      -
      +```bash
         express:router dispatching GET / +4h
         express:router query  : / +2ms
         express:router expressInit  : / +0ms
      @@ -96,10 +84,9 @@ $ DEBUG=express:* node ./bin/www
         express:view lookup "index.pug" +338ms
         express:view stat "/projects/example/views/index.pug" +0ms
         express:view render "/projects/example/views/index.pug" +1ms
      -
      -
      +``` -要仅查看来自路由器实现的日志,请将 `DEBUG` 的值设置为 `express:router`。与此类似,要仅查看来自应用程序实现的日志,请将 `DEBUG` 的值设置为 `express:application`,以此类推。 +要仅查看来自路由器实现的日志,请将 `DEBUG` 的值设置为 `express:router`。与此类似,要仅查看来自应用程序实现的日志,请将 `DEBUG` 的值设置为 `express:application`,以此类推。 Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. ## `express` 生成的应用程序 @@ -107,18 +94,36 @@ $ DEBUG=express:* node ./bin/www 例如,如果您以 `$ express sample-app` 生成应用程序,那么可以使用以下命令来启用调试语句: -
      -
      +```bash
       $ DEBUG=sample-app:* node ./bin/www
      -
      -
      +``` 可以通过分配逗号分隔的名称列表来指定多个调试名称空间: -
      -
      +```bash
       $ DEBUG=http,mail,express:* node index.js
      -
      -
      +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -有关 `debug` 的更多信息,请参阅 [debug](https://www.npmjs.com/package/debug)。 +{% include admonitions/note.html content=debug-text %} diff --git a/zh-cn/guide/error-handling.md b/zh-cn/guide/error-handling.md old mode 100755 new mode 100644 index d0ad2e7e62..1dbc1ae28a --- a/zh-cn/guide/error-handling.md +++ b/zh-cn/guide/error-handling.md @@ -1,141 +1,292 @@ --- layout: page title: Express 错误处理 +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: zh-cn +redirect_from: " " --- # 错误处理 -错误处理中间件函数的定义方式与其他中间件函数基本相同,差别在于错误处理函数有四个自变量而不是三个:`(err, req, res, next)`:例如: +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. -
      -
      -app.use(function(err, req, res, next) {
      -  console.error(err.stack);
      -  res.status(500).send('Something broke!');
      -});
      -
      -
      +## 如果将错误传递到 `next()` 且未在错误处理程序中进行处理,那么该错误将由内置的错误处理程序处理;错误将写入客户机的堆栈跟踪内。堆栈跟踪不包含在生产环境中。 -请在其他 `app.use()` 和路由调用之后,最后定义错误处理中间件,例如: +It's important to ensure that Express catches all errors that occur while +running route handlers and middleware. -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +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:
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(function(err, req, res, next) {
      -  // logic
      -});
      -
      -
      +```js +app.get('/', (req, res) => { + throw new Error('BROKEN') // Express will catch this on its own. +}) +``` -中间件函数中的响应可以采用您首选的任何格式,例如,HTML 错误页、简单消息或 JSON 字符串。 +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: -出于组织(和更高级框架)的目的,可以定义若干错误处理中间件函数,这和对常规中间件函数的处理很相似。例如,如果您希望为使用 `XHR` 发出的请求以及未使用此对象发出的请求定义错误处理程序,可以使用以下命令: +```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) + } + }) +}) +``` -
      -
      -var bodyParser = require('body-parser');
      -var methodOverride = require('method-override');
      +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:
       
      -app.use(bodyParser());
      -app.use(methodOverride());
      -app.use(logErrors);
      -app.use(clientErrorHandler);
      -app.use(errorHandler);
      -
      -
      +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` -在此示例中,通用 `logErrors` 可能将请求和错误信息写入 `stderr`,例如: +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. -
      -
      -function logErrors(err, req, res, next) {
      -  console.error(err.stack);
      -  next(err);
      -}
      -
      -
      +如果将任何项传递到 `next()` 函数(除了字符串 `'route'`),那么 Express 会将当前请求视为处于错误状态,并跳过所有剩余的非错误处理路由和中间件函数。如果您希望以某种方式处理此错误,必须如下一节中所述创建一个错误处理路由。 -也是在此示例中,`clientErrorHandler` 定义如下,错误会显式传递到下一项: +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: -
      -
      -function clientErrorHandler(err, req, res, next) {
      -  if (req.xhr) {
      -    res.status(500).send({ error: 'Something failed!' });
      -  } else {
      -    next(err);
      +```js
      +app.get('/', [
      +  function (req, res, next) {
      +    fs.writeFile('/inaccessible-path', 'data', next)
      +  },
      +  function (req, res) {
      +    res.send('OK')
         }
      -}
      -
      -
      +]) +``` -“catch-all”`errorHandler` 函数可以如下实现: +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. -
      -
      -function errorHandler(err, req, res, next) {
      -  res.status(500);
      -  res.render('error', { error: err });
      -}
      -
      -
      +You must catch errors that occur in asynchronous code invoked by route handlers or +middleware and pass them to Express for processing. For example: -如果将任何项传递到 `next()` 函数(除了字符串 `'route'`),那么 Express 会将当前请求视为处于错误状态,并跳过所有剩余的非错误处理路由和中间件函数。如果您希望以某种方式处理此错误,必须如下一节中所述创建一个错误处理路由。 +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN') + } catch (err) { + next(err) + } + }, 100) +}) +``` -如果一个路由处理程序具有多个回调函数,那么可以使用 `route` 参数跳至下一个路由处理程序。例如: +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. -
      -
      -app.get('/a_route_behind_paywall',
      -  function checkIfPaidSubscriber(req, res, next) {
      -    if(!req.user.hasPaid) {
      +Use promises to avoid the overhead of the `try...catch` block or when using functions
      +that return promises.  For example:
       
      -      // continue handling this request
      -      next('route');
      -    }
      -  }, function getPaidContent(req, res, next) {
      -    PaidContent.find(function(err, doc) {
      -      if(err) return next(err);
      -      res.json(doc);
      -    });
      -  });
      -
      -
      +```js +app.get('/', (req, res, next) => { + Promise.resolve().then(() => { + throw new Error('BROKEN') + }).catch(next) // Errors will be passed to Express. +}) +``` -在此示例中,将跳过 `getPaidContent` 处理程序,而将继续执行 `/a_route_behind_paywall` 的 `app` 中所有剩余的处理程序。 +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. -
      -对 `next()` 和 `next(err)` 的调用会表明当前处理程序是否完整以及处于何种状态。`next(err)` 将跳过链中所有剩余的处理程序(设置为按上述方式处理错误的处理程序除外)。 -
      +You could also use a chain of handlers to rely on synchronous error +catching, by reducing the asynchronous code to something trivial. For example: + +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +The above example has a couple of trivial statements from 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 +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. + +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. ## 缺省错误处理程序 -Express 随附一个内置的错误处理程序,负责处理应用程序中可能遇到的任何错误。这个缺省的错误处理中间件函数添加在中间件函数集的末尾。 +Express 随附一个内置的错误处理程序,负责处理应用程序中可能遇到的任何错误。这个缺省的错误处理中间件函数添加在中间件函数集的末尾。 This default error-handling middleware function is added at the end of the middleware function stack. -如果将错误传递到 `next()` 且未在错误处理程序中进行处理,那么该错误将由内置的错误处理程序处理;错误将写入客户机的堆栈跟踪内。堆栈跟踪不包含在生产环境中。 +If you pass an error to `next()` and you do not handle it in a custom error +handler, it will be handled by the built-in error handler; the error will be +written to the client with the stack trace. The stack trace is not included +in the production environment.
      将环境变量 `NODE_ENV` 设置为 `production`,以生产方式运行此应用程序。
      +When an error is written, the following information is added to the +response: + +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. + 如果在开始写响应之后调用 `next()` 时出错(例如,如果在以流式方式将响应传输到客户机时遇到错误),Express 缺省错误处理程序会关闭连接并使请求失败。 因此,在添加定制错误处理程序时,如果头已发送到客户机,您可能希望委托给 Express 中的缺省错误处理机制处理: -
      -
      -function errorHandler(err, req, res, next) {
      +```js
      +function errorHandler (err, req, res, next) {
         if (res.headersSent) {
      -    return next(err);
      +    return next(err)
         }
      -  res.status(500);
      -  res.render('error', { error: err });
      +  res.status(500)
      +  res.render('error', { error: err })
       }
      -
      -
      +``` + +Note that the default error handler can get triggered if you call `next()` with an error +in your code more than once, even if custom error handling middleware is in place. + +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html). + +## Writing error handlers + +错误处理中间件函数的定义方式与其他中间件函数基本相同,差别在于错误处理函数有四个自变量而不是三个:`(err, req, res, next)`:例如: For example: + +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` + +请在其他 `app.use()` 和路由调用之后,最后定义错误处理中间件,例如: + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use((err, req, res, next) => { + // logic +}) +``` + +中间件函数中的响应可以采用您首选的任何格式,例如,HTML 错误页、简单消息或 JSON 字符串。 + +For organizational (and higher-level framework) purposes, you can define +several error-handling middleware functions, much as you would with +regular middleware functions. For example, to define an error-handler +for requests made by using `XHR` and those without: + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use(logErrors) +app.use(clientErrorHandler) +app.use(errorHandler) +``` + +在此示例中,通用 `logErrors` 可能将请求和错误信息写入 `stderr`,例如: + +```js +function logErrors (err, req, res, next) { + console.error(err.stack) + next(err) +} +``` + +也是在此示例中,`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. + +```js +function clientErrorHandler (err, req, res, next) { + if (req.xhr) { + res.status(500).send({ error: 'Something failed!' }) + } else { + next(err) + } +} +``` + +“catch-all”`errorHandler` 函数可以如下实现: + +```js +function errorHandler (err, req, res, next) { + res.status(500) + res.render('error', { error: err }) +} +``` + +如果一个路由处理程序具有多个回调函数,那么可以使用 `route` 参数跳至下一个路由处理程序。例如: For example: + +```js +app.get('/a_route_behind_paywall', + (req, res, next) => { + if (!req.user.hasPaid) { + // continue handling this request + next('route') + } else { + next() + } + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` + +在此示例中,将跳过 `getPaidContent` 处理程序,而将继续执行 `/a_route_behind_paywall` 的 `app` 中所有剩余的处理程序。 + +
      + +对 `next()` 和 `next(err)` 的调用会表明当前处理程序是否完整以及处于何种状态。`next(err)` 将跳过链中所有剩余的处理程序(设置为按上述方式处理错误的处理程序除外)。 + `next(err)` will skip all remaining handlers in the chain except for those that are set up to handle errors as described above. +
      diff --git a/zh-cn/guide/migrating-4.md b/zh-cn/guide/migrating-4.md old mode 100755 new mode 100644 index 1bac1b71e1..56d9331ef0 --- a/zh-cn/guide/migrating-4.md +++ b/zh-cn/guide/migrating-4.md @@ -1,15 +1,16 @@ --- layout: page title: 迁移到 Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: zh-cn +redirect_from: " " --- # 迁移到 Express 4

      概述

      -Express 4 对 Express 3 进行了重大更改,这意味着,如果您在现有 Express 3 应用程序的依赖项中更新了 Express 版本,那么该应用程序将无法工作。 +Express 4 is a breaking change from Express 3. Express 4 对 Express 3 进行了重大更改,这意味着,如果您在现有 Express 3 应用程序的依赖项中更新了 Express 版本,那么该应用程序将无法工作。 本文讲述: @@ -24,23 +25,26 @@ Express 4 对 Express 3 进行了重大更改,这意味着,如果您在现 Express 4 中进行了若干重大更改: 另请参阅: -* [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x)。 -* [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)。 +- [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x)。 +- [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)。

      对 Express 核心和中间件系统的更改。

      -Express 4 不再依赖于 Connect,从其核心移除了所有内置的中间件(除了 `express.static` 函数)。这意味着 Express 现在是独立的路由和中间件 Web 框架,Express 的版本控制和发行不受中间件更新的影响。 +Express 4 不再依赖于 Connect,从其核心移除了所有内置的中间件(除了 `express.static` 函数)。这意味着 Express 现在是独立的路由和中间件 Web 框架,Express 的版本控制和发行不受中间件更新的影响。 This means that +Express is now an independent routing and middleware web framework, and +Express versioning and releases are not affected by middleware updates. -由于没有内置中间件,因此您必须显式添加所需的所有中间件才能运行应用程序。只需执行以下步骤: +由于没有内置中间件,因此您必须显式添加所需的所有中间件才能运行应用程序。只需执行以下步骤: Simply follow these steps: 1. 安装模块:`npm install --save ` 2. 在应用程序中需要此模块:`require('module-name')` @@ -49,7 +53,7 @@ Express 4 不再依赖于 Connect,从其核心移除了所有内置的中间 下表列出了 Express 3 中间件及其在 Express 4 中的对应组件。 - + @@ -81,25 +85,26 @@ Express 4 不再依赖于 Connect,从其核心移除了所有内置的中间 -
      Express 3Express 4
      Express 3Express 4
      express.bodyParser body-parser + multer
      serve-index
      express.static serve-static
      +
      可参考 Express 4 中间件的[完整列表](https://github.com/senchalabs/connect#middleware)。 -在大多数情况下,可以将旧的 V3 中间件替换为 Express 4 的对应组件。有关详细信息,请参阅 GitHub 中的模块文档。 +在大多数情况下,可以将旧的 V3 中间件替换为 Express 4 的对应组件。有关详细信息,请参阅 GitHub 中的模块文档。 For details, see the module documentation in +GitHub.

      app.use 可以使用参数

      在 V4 中,您可以使用变量参数来定义装入中间件函数的路径,然后从路由处理程序读取参数的值。 例如: +For example: + +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` -
      -
      -app.use('/book/:id', function(req, res, next) {
      -  console.log('ID:', req.params.id);
      -  next();
      -});
      -
      -

      路由系统

      @@ -109,70 +114,70 @@ app.use('/book/:id', function(req, res, next) { 定义路由的方式并未改变,但是路由系统新增了两个功能,用于帮助组织路由: {: .doclist } -* 一个新方法 `app.route()`,用于为路由路径创建可链接的路由处理程序。 -* 一个新类 `express.Router`,用于创建可安装的模块化路由处理程序。 + +- 一个新方法 `app.route()`,用于为路由路径创建可链接的路由处理程序。 +- 一个新类 `express.Router`,用于创建可安装的模块化路由处理程序。

      app.route() 方法

      -新的 `app.route()` 方法使您可以为路由路径创建可链接的路由处理程序。创建模块化路由很有帮助,因为在单一位置指定路径,所以可以减少冗余和输入错误。有关路由的更多信息,请参阅 [`Router()` 文档](/{{ page.lang }}/4x/api.html#router)。 +新的 `app.route()` 方法使您可以为路由路径创建可链接的路由处理程序。创建模块化路由很有帮助,因为在单一位置指定路径,所以可以减少冗余和输入错误。有关路由的更多信息,请参阅 [`Router()` 文档](/{{ page.lang }}/4x/api.html#router)。 Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more +information about routes, see [`Router()` documentation](/{{ page.lang }}/4x/api.html#router). 以下是使用 `app.route()` 函数定义的链式路由处理程序的示例。 -
      -
      +```js
       app.route('/book')
      -  .get(function(req, res) {
      -    res.send('Get a random book');
      +  .get((req, res) => {
      +    res.send('Get a random book')
      +  })
      +  .post((req, res) => {
      +    res.send('Add a book')
         })
      -  .post(function(req, res) {
      -    res.send('Add a book');
      +  .put((req, res) => {
      +    res.send('Update the book')
         })
      -  .put(function(req, res) {
      -    res.send('Update the book');
      -  });
      -
      -
      +```

      express.Router

      -有助于组织路由的另一个功能是新类 `express.Router`,可用于创建可安装的模块化路由处理程序。`Router` 实例是完整的中间件和路由系统;因此,常常将其称为“微型应用程序”。 +The other feature that helps to organize routes is a new class, +`express.Router`, that you can use to create modular mountable +route handlers. 有助于组织路由的另一个功能是新类 `express.Router`,可用于创建可安装的模块化路由处理程序。`Router` 实例是完整的中间件和路由系统;因此,常常将其称为“微型应用程序”。 以下示例将路由器创建为模块,在其中装入中间件,定义一些路由,然后安装在主应用程序的路径中。 例如,在应用程序目录中创建名为 `birds.js` 的路由器文件,其中包含以下内容: -
      -
      -var express = require('express');
      -var router = express.Router();
      +```js
      +var express = require('express')
      +var router = express.Router()
       
       // middleware specific to this router
      -router.use(function timeLog(req, res, next) {
      -  console.log('Time: ', Date.now());
      -  next();
      -});
      +router.use((req, res, next) => {
      +  console.log('Time: ', Date.now())
      +  next()
      +})
       // define the home page route
      -router.get('/', function(req, res) {
      -  res.send('Birds home page');
      -});
      +router.get('/', (req, res) => {
      +  res.send('Birds home page')
      +})
       // define the about route
      -router.get('/about', function(req, res) {
      -  res.send('About birds');
      -});
      +router.get('/about', (req, res) => {
      +  res.send('About birds')
      +})
       
      -module.exports = router;
      -
      -
      +module.exports = router +``` 接着,在应用程序中装入路由器模块: -
      -
      -var birds = require('./birds');
      -...
      -app.use('/birds', birds);
      -
      -
      +```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` 此应用程序现在可处理针对 `/birds` 和 `/birds/about` 路径的请求,调用特定于此路由的 `timeLog` 中间件。 @@ -183,7 +188,7 @@ app.use('/birds', birds); 下表列出 Express 4 中虽小但重要的其他更改: - + @@ -196,7 +201,10 @@ app.use('/birds', birds); `http.createServer()` @@ -204,7 +212,9 @@ app.use('/birds', birds); `app.configure()` @@ -284,15 +294,18 @@ app.use('/birds', birds); `res.setHeader('Set-Cookie', val)` -
      对象 描述
      + 不再需要 `http` 模块,除非您要直接使用它 (socket.io/SPDY/HTTPS)。可以使用 `app.listen()` 函数来启动此应用程序。 + The app can be started by using the +`app.listen()` function.
      +The `app.configure()` function has been removed. 已移除 `app.configure()` 函数。使用 `process.env.NODE_ENV` 或 `app.get('env')` 功能来检测环境并相应配置该应用程序。 +
      +Functionality is now limited to setting the basic cookie value. 功能现在已限制为设置基本 cookie 值。将 `res.cookie()` 用于增添的功能。 +
      +

      应用程序迁移示例

      以下是将 Express 3 应用程序迁移到 Express 4 的示例。 涉及的文件包括 `app.js` 和 `package.json`。 +下一步,将 `package.json` 文件中的 `"start": "node ./bin/www"` 更改为 `"start": "node app.js"`。

      V3 应用程序 @@ -302,48 +315,45 @@ V3 应用程序 考虑具有以下 `app.js` 文件的 Express V3 应用程序: -
      -
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var http = require('http');
      -var path = require('path');
      +```js
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var http = require('http')
      +var path = require('path')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(express.favicon());
      -app.use(express.logger('dev'));
      -app.use(express.methodOverride());
      -app.use(express.session({ secret: 'your secret here' }));
      -app.use(express.bodyParser());
      -app.use(app.router);
      -app.use(express.static(path.join(__dirname, 'public')));
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(express.favicon())
      +app.use(express.logger('dev'))
      +app.use(express.methodOverride())
      +app.use(express.session({ secret: 'your secret here' }))
      +app.use(express.bodyParser())
      +app.use(app.router)
      +app.use(express.static(path.join(__dirname, 'public')))
       
       // development only
      -if ('development' == app.get('env')) {
      -  app.use(express.errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(express.errorHandler())
       }
       
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
      -http.createServer(app).listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

      package.json

      随附的 V3 `package.json` 文件可能具有类似于以下的内容: -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -356,8 +366,7 @@ http.createServer(app).listen(app.get('port'), function(){
           "pug": "*"
         }
       }
      -
      -
      +```

      进程 @@ -365,17 +374,17 @@ http.createServer(app).listen(app.get('port'), function(){ 使用以下命令安装 Express 4 应用程序的必需中间件并将 Express 和 Pug 分别更新到其最新版本,从而开始迁移过程: -
      -
      +```bash
       $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
      -
      -
      +``` 对 `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` 对象。您必须手动安装其替代项,然后在应用程序中装入。 You must install their alternatives + manually and load them in the app. -2. 不再需要装入 `app.router` 函数。它不是有效的 Express 4 应用程序对象,所以移除了 `app.use(app.router);` 代码。 +2. You no longer need to load the `app.router` function. + 不再需要装入 `app.router` 函数。它不是有效的 Express 4 应用程序对象,所以移除了 `app.use(app.router);` 代码。 3. 确保以正确顺序装入中间件函数 - 在装入应用程序路由之后装入 `errorHandler`。 @@ -385,8 +394,7 @@ $ npm install serve-favicon morgan method-override express-session body-parser m 运行以上 `npm` 命令会更新 `package.json`,如下所示: -
      -
      +```json
       {
         "name": "application-name",
         "version": "0.0.1",
      @@ -399,86 +407,85 @@ $ npm install serve-favicon morgan method-override express-session body-parser m
           "errorhandler": "^1.1.1",
           "express": "^4.8.0",
           "express-session": "^1.7.2",
      -    "pug": "^2.0.0-beta6",
      +    "pug": "^2.0.0",
           "method-override": "^2.1.2",
           "morgan": "^1.2.2",
           "multer": "^0.1.3",
           "serve-favicon": "^2.0.1"
         }
       }
      -
      -
      +```

      app.js

      -随后,移除无效代码,装入所需中间件,并根据需要进行其他更改。`app.js` 文件如下: +随后,移除无效代码,装入所需中间件,并根据需要进行其他更改。`app.js` 文件如下: The `app.js` file will look like this: -
      -
      -var http = require('http');
      -var express = require('express');
      -var routes = require('./routes');
      -var user = require('./routes/user');
      -var path = require('path');
      +```js
      +var http = require('http')
      +var express = require('express')
      +var routes = require('./routes')
      +var user = require('./routes/user')
      +var path = require('path')
       
      -var favicon = require('serve-favicon');
      -var logger = require('morgan');
      -var methodOverride = require('method-override');
      -var session = require('express-session');
      -var bodyParser = require('body-parser');
      -var multer = require('multer');
      -var errorHandler = require('errorhandler');
      +var favicon = require('serve-favicon')
      +var logger = require('morgan')
      +var methodOverride = require('method-override')
      +var session = require('express-session')
      +var bodyParser = require('body-parser')
      +var multer = require('multer')
      +var errorHandler = require('errorhandler')
       
      -var app = express();
      +var app = express()
       
       // all environments
      -app.set('port', process.env.PORT || 3000);
      -app.set('views', path.join(__dirname, 'views'));
      -app.set('view engine', 'pug');
      -app.use(favicon(__dirname + '/public/favicon.ico'));
      -app.use(logger('dev'));
      -app.use(methodOverride());
      -app.use(session({ resave: true,
      -                  saveUninitialized: true,
      -                  secret: 'uwotm8' }));
      -app.use(bodyParser.json());
      -app.use(bodyParser.urlencoded({ extended: true }));
      -app.use(multer());
      -app.use(express.static(path.join(__dirname, 'public')));
      -
      -app.get('/', routes.index);
      -app.get('/users', user.list);
      +app.set('port', process.env.PORT || 3000)
      +app.set('views', path.join(__dirname, 'views'))
      +app.set('view engine', 'pug')
      +app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
      +app.use(logger('dev'))
      +app.use(methodOverride())
      +app.use(session({
      +  resave: true,
      +  saveUninitialized: true,
      +  secret: 'uwotm8'
      +}))
      +app.use(bodyParser.json())
      +app.use(bodyParser.urlencoded({ extended: true }))
      +app.use(multer())
      +app.use(express.static(path.join(__dirname, 'public')))
      +
      +app.get('/', routes.index)
      +app.get('/users', user.list)
       
       // error handling middleware should be loaded after the loading the routes
      -if ('development' == app.get('env')) {
      -  app.use(errorHandler());
      +if (app.get('env') === 'development') {
      +  app.use(errorHandler())
       }
       
      -var server = http.createServer(app);
      -server.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      -
      +var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```
      除非您需要直接使用 `http` 模块 (socket.io/SPDY/HTTPS),否则不需要将其装入,可按以下方式启动此应用程序: -
      -app.listen(app.get('port'), function(){
      -  console.log('Express server listening on port ' + app.get('port'));
      -});
      -
      + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +

      运行应用程序

      -迁移过程完成,此应用程序现在是 Express 4 版本。要进行确认,可使用以下命令启动此应用程序: +迁移过程完成,此应用程序现在是 Express 4 版本。要进行确认,可使用以下命令启动此应用程序: To confirm, start the app by using the following command: -
      -
      +```bash
       $ node .
      -
      -
      +``` 装入 [http://localhost:3000](http://localhost:3000),然后查看 Express 4 呈现的主页。 @@ -490,22 +497,21 @@ $ node . 如果您已经在系统上安装了 Express 3 应用程序生成器,必须将其卸载: -
      -
      +```bash
       $ npm uninstall -g express
      -
      -
      +``` + 根据您的文件和目录特权的配置方式,可能需要使用 `sudo` 来运行此命令。 立即安装新的生成器: -
      -
      +Now install the new generator:
      +
      +```bash
       $ npm install -g express-generator
      -
      -
      +``` 根据您的文件和目录特权的配置方式,可能需要使用 `sudo` 来运行此命令。 - +立即安装新的生成器: 现在,系统上的 `express` 命令已更新到 Express 4 生成器。 @@ -514,19 +520,18 @@ $ npm install -g express-generator 命令选项和用法大体保持相同,但也存在以下例外: {: .doclist } -* 已移除 `--sessions` 选项。 -* 已移除 `--jshtml` 选项。 -* 已添加 `--hogan` 选项来支持 [Hogan.js](http://twitter.github.io/hogan.js/)。 + +- 已移除 `--sessions` 选项。 +- 已移除 `--jshtml` 选项。 +- 已添加 `--hogan` 选项来支持 [Hogan.js](http://twitter.github.io/hogan.js/)。

      示例

      执行以下命令来创建 Express 4 应用程序: -
      -
      +```bash
       $ express app4
      -
      -
      +``` 如果查看 `app4/app.js` 文件的内容,那么会注意到应用程序所需的所有中间件函数(除了 `express.static`)都作为独立模块装入,而在应用程序中不再显式装入 `router` 中间件。 @@ -534,38 +539,39 @@ $ express app4 在安装依赖项之后,可使用以下命令来启动此应用程序: -
      -
      +```bash
       $ npm start
      -
      -
      +``` 如果查看 `package.json` 文件中的 npm 启动脚本,可以注意到启动应用程序的实际命令是 `node ./bin/www`,而过去在 Express 3 中,该命令是 `node app.js`。 -因为 Express 4 生成器生成的 `app.js` 文件现在是 Node.js 模块,所以不再能够将其作为应用程序独立启动(除非修改代码)。必须在 Node.js 文件中加载此模块,并通过 Node.js 文件启动。在此情况下,Node.js 文件是 `./bin/www`。 +因为 Express 4 生成器生成的 `app.js` 文件现在是 Node.js 模块,所以不再能够将其作为应用程序独立启动(除非修改代码)。必须在 Node.js 文件中加载此模块,并通过 Node.js 文件启动。在此情况下,Node.js 文件是 `./bin/www`。 The module must be loaded in a Node.js file +and started via the Node.js file. The Node.js file is `./bin/www` +in this case. -对于创建 Express 应用程序或启动此应用程序,`bin` 目录或无扩展名的 `www` 文件都不是必需的。它们只是生成器提出的建议,可随意根据自己的需求进行修改。 +对于创建 Express 应用程序或启动此应用程序,`bin` 目录或无扩展名的 `www` 文件都不是必需的。它们只是生成器提出的建议,可随意根据自己的需求进行修改。 They are +just suggestions made by the generator, so feel free to modify them to suit your +needs. 如果不想使用 `www` 目录,而是保持“Express 3 风格”,请删除 `app.js` 文件末尾的 `module.exports = app;` 行,然后将以下代码粘贴在到该位置: -
      -
      -app.set('port', process.env.PORT || 3000);
      +```js
      +app.set('port', process.env.PORT || 3000)
       
      -var server = app.listen(app.get('port'), function() {
      -  debug('Express server listening on port ' + server.address().port);
      -});
      -
      -
      +var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` 确保使用以下代码在 `app.js` 文件之上装入 `debug` 模块: -
      -
      -var debug = require('debug')('app4');
      -
      -
      - -下一步,将 `package.json` 文件中的 `"start": "node ./bin/www"` 更改为 `"start": "node app.js"`。 +```js +var debug = require('debug')('app4') +``` 现在,您已将 `./bin/www` 的功能恢复为 `app.js`。不建议进行此更改,但是此练习可以帮助您理解 `./bin/www` 文件的工作方式,以及为何 `app.js` 文件不再自行启动。 + +You have now moved the functionality of `./bin/www` back to +`app.js`. This change is not recommended, but the exercise helps you +to understand how the `./bin/www` file works, and why the `app.js` file +no longer starts on its own. diff --git a/zh-cn/guide/migrating-5.md b/zh-cn/guide/migrating-5.md old mode 100755 new mode 100644 index d2a87e46c3..23a1ec9102 --- a/zh-cn/guide/migrating-5.md +++ b/zh-cn/guide/migrating-5.md @@ -1,32 +1,44 @@ --- layout: page title: 迁移到 Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: zh-cn +redirect_from: " " --- # 迁移到 Express 5

      概述

      -Express 5.0 仍然处于 α 测试发布阶段,但我们可以在这里先睹为快,了解一下这个发行版中的变化以及如何将 Express 4 应用程序迁移到 Express 5。 +Express 5 与 Express 4 的差异不是很大:对 API 的更改不像 3.0 到 4.0 升级那样大刀阔斧。虽然基本 API 保持相同,但仍有一些重大更改;换言之,如果将现有 Express 4 程序更新为使用 Express 5,那么该程序可能无法工作。 Therefore, an application built with Express 4 might not work if you update it to use Express 5. -Express 5 与 Express 4 的差异不是很大:对 API 的更改不像 3.0 到 4.0 升级那样大刀阔斧。虽然基本 API 保持相同,但仍有一些重大更改;换言之,如果将现有 Express 4 程序更新为使用 Express 5,那么该程序可能无法工作。 +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -要安装最新的 α 测试版以预览 Express 5,请在应用程序根目录中输入以下命令: +```sh +npm install "express@5" +``` -
      -
      -$ npm install express@5.0.0-alpha.2 --save
      -
      -
      +随后,可以运行自动化测试以查看哪些地方发生故障,然后根据以下列出的更新修复问题。在解决测试故障问题之后,运行应用程序以查看发生哪些错误。如果应用程序使用任何不受支持的方法或属性,您马上就可以发现。 After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported. -随后,可以运行自动化测试以查看哪些地方发生故障,然后根据以下列出的更新修复问题。在解决测试故障问题之后,运行应用程序以查看发生哪些错误。如果应用程序使用任何不受支持的方法或属性,您马上就可以发现。 +## Express 5 Codemods -

      Express 5 中的更改

      +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: -以下是将影响 Express 用户的更改的列表(截至在 α R2)。 -请参阅 [pull request](https://github.com/expressjs/express/pull/2237) 以查看所有计划功能的列表。 +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). + +

      Express 5 中的更改

      **已移除的方法和属性** @@ -38,96 +50,497 @@ $ npm install express@5.0.0-alpha.2 --save
    • req.param(name)
    • res.json(obj, status)
    • res.jsonp(obj, status)
    • +
    • res.redirect('back') and res.location('back')
    • +
    • res.redirect(url, status)
    • res.send(body, status)
    • res.send(status)
    • res.sendfile()
    • +
    • router.param(fn)
    • +
    • express.static.mime
    • +
    • express:router debug logs
    -**已更改** +**改进** -**改进** +**已更改** -

    已移除的方法和属性

    +## 已移除的方法和属性 + +If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5. + +

    app.del()

    + +Express 5 不再支持 `app.del()` 函数。如果使用此函数,将抛出错误。要注册 HTTP DELETE 路由,请使用 `app.delete()` 函数。 If you use this function, an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. + +最初之所以使用 `del` 而不是 `delete`,是因为 `delete` 是 JavaScript 中的保留关键字。但在 ECMAScript 6 时,`delete` 和其他保留关键字可以合法地用作属性名称。您可以在此阅读该讨论,这导致我们在此不推荐使用 `app.del` 函数。 However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. -如果在应用程序中使用任何已删除的方法或属性,应用程序将崩溃。所以,需要在更新到 V5 之后更改应用程序。 +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: -

    app.del()

    +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` -Express 5 不再支持 `app.del()` 函数。如果使用此函数,将抛出错误。要注册 HTTP DELETE 路由,请使用 `app.delete()` 函数。 +{% endcapture %} -最初之所以使用 `del` 而不是 `delete`,是因为 `delete` 是 JavaScript 中的保留关键字。但在 ECMAScript 6 时,`delete` 和其他保留关键字可以合法地用作属性名称。您可以在此阅读该讨论,这导致我们在此不推荐使用 `app.del` 函数。 +{% include admonitions/note.html content=codemod-deprecated-signatures %} -

    app.param(fn)

    +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) -`app.param(fn)` 特征符用于修改 `app.param(name, fn)` 函数的行为。自 V4.11.0 起不推荐使用该特征符,而 Express 5 完全不再提供支持。 +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` -

    复数的方法名称

    +

    app.param(fn)

    -以下方法名称已加复数。在 Express 4 中,使用旧方法时会出现不推荐使用的警告。Express 5 则完全不再支持: +`app.param(fn)` 特征符用于修改 `app.param(name, fn)` 函数的行为。自 V4.11.0 起不推荐使用该特征符,而 Express 5 完全不再提供支持。 It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. + +

    复数的方法名称

    + +The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: + +`req.acceptsLanguage()` 由 `req.acceptsLanguages()` 取代。 `req.acceptsCharset()` 由 `req.acceptsCharsets()` 取代。 `req.acceptsEncoding()` 由 `req.acceptsEncodings()` 取代。 -`req.acceptsLanguage()` 由 `req.acceptsLanguages()` 取代。 +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-pluralized-methods %} -

    app.param(name, fn) 的名称中的前置冒号 (:)

    +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') -`app.param(name, fn)` 函数名称中的前置冒号字符 (:) 是 Express 3 的遗留问题,为了向后兼容性,Express 4 提供支持但会显示不推荐使用的提醒。而 Express 5 则静默忽略它,使用不带前置冒号的名称参数。 + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    app.param(name, fn) 的名称中的前置冒号 (:)

    + +`app.param(name, fn)` 函数名称中的前置冒号字符 (:) 是 Express 3 的遗留问题,为了向后兼容性,Express 4 提供支持但会显示不推荐使用的提醒。而 Express 5 则静默忽略它,使用不带前置冒号的名称参数。 Express 5 will silently ignore it and use the name parameter without prefixing it with a colon. 如果您遵循 [app.param](/{{ page.lang }}/4x/api.html#app.param) 的 Express 4 文档进行开发,那么不会影响代码,因为文档中没有提及前置冒号。 -

    req.param(name)

    +

    req.param(name)

    + +This potentially confusing and dangerous method of retrieving form data has been removed. 已移除用于检索表单数据的方法,因为这可能引起混淆,而且很危险。现在,您需要在 `req.params`、`req.body` 或 `req.query` 对象中专门寻找提交的参数名称。 + +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    + +Express 5 不再支持特征符 `res.json(obj, status)`。而是设置状态,然后将其链接到 `res.json()` 方法,如下所示:`res.status(status).json(obj)`。 Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    + +Express 5 不再支持特征符 `res.jsonp(obj, status)`。而是设置状态,然后将其链接到 `res.jsonp()` 方法,如下所示:`res.status(status).jsonp(obj)`。 Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    + +Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    + +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` + +

    res.send(body, status)

    -已移除用于检索表单数据的方法,因为这可能引起混淆,而且很危险。现在,您需要在 `req.params`、`req.body` 或 `req.query` 对象中专门寻找提交的参数名称。 +Express 5 不再支持特征符 `res.send(obj, status)`。而是设置状态,然后将其链接到 `res.send()` 方法,如下所示:`res.status(status).send(obj)`。 Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. -

    res.json(obj, status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} -Express 5 不再支持特征符 `res.json(obj, status)`。而是设置状态,然后将其链接到 `res.json()` 方法,如下所示:`res.status(status).json(obj)`。 +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) -

    res.jsonp(obj, status)

    +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` -Express 5 不再支持特征符 `res.jsonp(obj, status)`。而是设置状态,然后将其链接到 `res.jsonp()` 方法,如下所示:`res.status(status).jsonp(obj)`。 +

    res.send(status)

    -

    res.send(body, status)

    +Express 5 no longer supports the signature `res.send(status)`, where `status` is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. +If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature. -Express 5 不再支持特征符 `res.send(obj, status)`。而是设置状态,然后将其链接到 `res.send()` 方法,如下所示:`res.status(status).send(obj)`。 +{% include admonitions/note.html content=codemod-deprecated-signatures %} -

    res.send(status)

    +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) -Express 5 不再支持特征符 res.send(status),其中 *`status`* 是数字。而是使用 `res.sendStatus(statusCode)` 函数,它会设置 HTTP 响应头状态码并发送该代码的文字版:“Not Found”、“Internal Server Error”等。 -如果需要使用 `res.send()` 函数来发送数字,请对该数字加上引号以将其转换为字符串,以便 Express 不会将其解释为尝试使用不受支持的旧特征符。 +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` -

    res.sendfile()

    +

    res.sendfile()

    在 Express 5 中,`res.sendfile()` 函数已由驼峰式大小写版本 `res.sendFile()` 替换。 -

    已更改

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: -

    app.router

    +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" -在 Express 4 中已移除的 `app.router` 对象在 Express 5 中已恢复。在新版本中,此对象只是对 Express 基本路由器的引用,不像在 Express 3 中应用程序必须显式将该路由器装入。 +{% include admonitions/note.html content=codemod-deprecated-signatures %} -

    req.host

    +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) -在 Express 4 中,如果存在端口号,`req.host` 函数会错误地将其剥离。在 Express 5 中,则会保留端口号。 +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` -

    req.query

    +

    router.param(fn)

    -在 Express 4.7 以及 Express 5 之后,如果您希望使用自己的查询字符串解析逻辑函数,查询解析器选项可以接受 `false` 以禁用查询字符串解析。 +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. -

    改进

    +

    express.static.mime

    -

    res.render()

    +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## 已更改 + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. For example: + +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +For example: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    + +在 Express 4 中已移除的 `app.router` 对象在 Express 5 中已恢复。在新版本中,此对象只是对 Express 基本路由器的引用,不像在 Express 3 中应用程序必须显式将该路由器装入。 In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. + +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    + +在 Express 4 中,如果存在端口号,`req.host` 函数会错误地将其剥离。在 Express 5 中,则会保留端口号。 In Express 5, the port number is maintained. + +

    req.query

    + +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". + +

    res.clearCookie

    + +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. + +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## 改进 + +

    res.render()

    现在,此方法为所有查看引擎强制执行异步行为,避免具有同步实现以及违反建议接口的查看引擎所导致的错误。 + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/zh-cn/guide/overriding-express-api.md b/zh-cn/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/zh-cn/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/zh-cn/guide/routing.md b/zh-cn/guide/routing.md old mode 100755 new mode 100644 index 144166597c..e40709fbde --- a/zh-cn/guide/routing.md +++ b/zh-cn/guide/routing.md @@ -1,32 +1,38 @@ --- layout: page title: Express 路由 +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: zh-cn +redirect_from: " " --- # 路由 -*路由*表示应用程序端点 (URI) 的定义以及端点响应客户机请求的方式。 +_路由_表示应用程序端点 (URI) 的定义以及端点响应客户机请求的方式。 有关路由的简介,请参阅[基本路由](/{{ page.lang }}/starter/basic-routing.html)。 +For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/basic-routing.html). -我们所使用的 app 与 HTTP 方法相对应的 Express 对象方法来定义路由,如 ```app.get()``` 用于处理 GET 请求,而 ```app.post``` 则用于处理 POST 请求。 +我们所使用的 app 与 HTTP 方法相对应的 Express 对象方法来定义路由,如 `app.get()` 用于处理 GET 请求,而 `app.post` 则用于处理 POST 请求。 For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). -这些路由方法都指定了回调函数(或者:“处理程序函数”),当程序接收到指定的路由(端点)的时候(也就是说 HTTP 方法请求时被调用),来调用回调函数,换句话说就是应用程序监听与指定路由和方法匹配的请求,当检测到匹配时,他会调用对应的回调函数。 +这些路由方法都指定了回调函数(或者:“处理程序函数”),当程序接收到指定的路由(端点)的时候(也就是说 HTTP 方法请求时被调用),来调用回调函数,换句话说就是应用程序监听与指定路由和方法匹配的请求,当检测到匹配时,他会调用对应的回调函数。 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 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 +to the next callback. 以下代码是非常基本的路由示例。 -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -// 当对主页发出 GET 请求时,响应“hello world”
    -app.get('/', function(req, res) {
    -  res.send('hello world');
    -});
    -
    -
    +// respond with "hello world" when a GET request is made to the homepage +app.get('/', (req, res) => { + res.send('hello world') +}) +```

    路由方法

    @@ -34,302 +40,354 @@ app.get('/', function(req, res) { 以下代码是为访问应用程序根目录的 GET 和 POST 方法定义的路由示例。 -
    -
    +```js
     // GET method route
    -app.get('/', function (req, res) {
    -  res.send('GET request to the homepage');
    -});
    +app.get('/', (req, res) => {
    +  res.send('GET request to the homepage')
    +})
     
     // POST method route
    -app.post('/', function (req, res) {
    -  res.send('POST request to the homepage');
    -});
    -
    -
    +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` -Express 支持对应于 HTTP 方法的以下路由方法:`get`、`post`、`put`、`head`、`delete`、`options`、`trace`、`copy`、`lock`、`mkcol`、`move`、`purge`、`propfind`、`proppatch`、`unlock`、`report`、`mkactivity`、`checkout`、`merge`、`m-search`、`notify`、`subscribe`、`unsubscribe`、`patch`、`search` 和 `connect`。 +Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). -
    -要路由会转换为无效 JavaScript 变量名称的方法,请使用括号表示法。例如,`app['m-search']('/', function ...` -
    +有一种特殊路由方法:`app.all()`,它并非派生自 HTTP 方法。该方法用于在所有请求方法的路径中装入中间件函数。 在以下示例中,无论您使用 GET、POST、PUT、DELETE 还是在 [http 模块](https://nodejs.org/api/http.html#http_http_methods)中支持的其他任何 HTTP 请求方法,都将为针对“/secret”的请求执行处理程序。 -有一种特殊路由方法:`app.all()`,它并非派生自 HTTP 方法。该方法用于在所有请求方法的路径中装入中间件函数。 +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +``` -在以下示例中,无论您使用 GET、POST、PUT、DELETE 还是在 [http 模块](https://nodejs.org/api/http.html#http_http_methods)中支持的其他任何 HTTP 请求方法,都将为针对“/secret”的请求执行处理程序。 +

    路由路径

    -
    -
    -app.all('/secret', function (req, res, next) {
    -  console.log('Accessing the secret section ...');
    -  next(); // pass control to the next handler
    -});
    -
    -
    +路由路径与请求方法相结合,用于定义可以在其中提出请求的端点。路由路径可以是字符串、字符串模式或正则表达式。 Route paths can be strings, string patterns, or regular expressions. -

    路由路径

    +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -路由路径与请求方法相结合,用于定义可以在其中提出请求的端点。路由路径可以是字符串、字符串模式或正则表达式。 +{% include admonitions/caution.html content=caution-character %} -
    -Express 使用 [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) 来匹配路由路径;请参阅 path-to-regexp 文档以了解定义路由路径时所有的可能性。[Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) 是用于测试基本 Express 路由的便捷工具,但是它不支持模式匹配。 -
    +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} -
    -查询字符串不是路由路径的一部分。 -
    +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [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. -以下是基于字符串的路由路径的一些示例。 +{% endcapture %} -此路由路径将请求与根路由 `/` 匹配。 +{% include admonitions/note.html content=note-path-to-regexp %} -
    -
    -app.get('/', function (req, res) {
    -  res.send('root');
    -});
    -
    -
    +{% capture query-string-note %} + +Query strings are not part of the route path. + +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### 以下是基于字符串的路由路径的一些示例。 + +此路由路径将请求与 `/` 匹配。 + +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` 此路由路径将请求与 `/about` 匹配。 -
    -
    -app.get('/about', function (req, res) {
    -  res.send('about');
    -});
    -
    -
    +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` 此路由路径将请求与 `/random.text` 匹配。 -
    -
    -app.get('/random.text', function (req, res) {
    -  res.send('random.text');
    -});
    -
    -
    +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` -以下是基于字符串模式的路由路径的一些示例。 +### 以下是基于字符串模式的路由路径的一些示例。 -此路由路径将匹配 `acd` 和 `abcd`。 +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
    -
    -app.get('/ab?cd', function(req, res) {
    -  res.send('ab?cd');
    -});
    -
    -
    +{% include admonitions/caution.html content=caution-string-patterns %} + +此路由路径将匹配 `/abe` 和 `/abcde`。 + +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` 此路由路径将匹配 `abcd`、`abbcd`、`abbbcd` 等。 -
    -
    -app.get('/ab+cd', function(req, res) {
    -  res.send('ab+cd');
    -});
    -
    -
    +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` 此路由路径将匹配 `abcd`、`abxcd`、`abRABDOMcd`、`ab123cd` 等。 -
    -
    -app.get('/ab*cd', function(req, res) {
    -  res.send('ab*cd');
    -});
    -
    -
    - -此路由路径将匹配 `/abe` 和 `/abcde`。 +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` -
    -
    -app.get('/ab(cd)?e', function(req, res) {
    - res.send('ab(cd)?e');
    -});
    -
    -
    +此路由路径将匹配 `acd` 和 `abcd`。 -
    -字符 ?、+、* 和 () 是其正则表达式同应项的子集。基于字符串的路径按字面理解连字符 (-) 和点 (.)。 -
    +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` -基于正则表达式的路由路径的示例: +### 基于正则表达式的路由路径的示例: 此路由路径将匹配名称中具有“a”的所有路由。 -
    -
    -app.get(/a/, function(req, res) {
    -  res.send('/a/');
    -});
    -
    -
    +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` 此路由路径将匹配 `butterfly` 和 `dragonfly`,但是不匹配 `butterflyman`、`dragonfly man` 等。 -
    -
    -app.get(/.*fly$/, function(req, res) {
    -  res.send('/.*fly$/');
    -});
    -
    -
    - -

    路由处理程序

    - -您可以提供多个回调函数,以类似于[中间件](/{{ page.lang }}/guide/using-middleware.html)的行为方式来处理请求。唯一例外是这些回调函数可能调用 `next('route')` 来绕过剩余的路由回调。您可以使用此机制对路由施加先决条件,在没有理由继续执行当前路由的情况下,可将控制权传递给后续路由。 - -路由处理程序的形式可以是一个函数、一组函数或者两者的结合,如以下示例中所示。 - -单个回调函数可以处理一个路由。例如: - -
    -
    -app.get('/example/a', function (req, res) {
    -  res.send('Hello from A!');
    -});
    -
    -
    - -多个回调函数可以处理一个路由(确保您指定 `next` 对象)。例如: - -
    -
    -app.get('/example/b', function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from B!');
    -});
    -
    -
    - -一组回调函数可以处理一个路由。例如: - -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +app.get(/.*fly$/, (req, res) => {
    +  res.send('/.*fly$/')
    +})
    +```
    +
    +

    路由处理程序

    + +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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
    +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]). +
    + +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. + +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` + +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` + +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} + +{% include admonitions/caution.html content=warning-regexp %} + +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): + +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` + +{% capture escape-advisory %} + +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. + +{% endcapture %} + +{% include admonitions/warning.html content=escape-advisory %} + +{% capture warning-version %} + +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. + +{% endcapture %} + +{% include admonitions/warning.html content=warning-version %} + +

    Route handlers

    + +您可以提供多个回调函数,以类似于[中间件](/{{ page.lang }}/guide/using-middleware.html)的行为方式来处理请求。唯一例外是这些回调函数可能调用 `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. + +Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples. + +单个回调函数可以处理一个路由。例如: For example: + +```js +app.get('/example/a', (req, res) => { + res.send('Hello from A!') +}) +``` + +多个回调函数可以处理一个路由(确保您指定 `next` 对象)。例如: For example: + +```js +app.get('/example/b', (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from B!') +}) +``` + +一组回调函数可以处理一个路由。例如: For example: + +```js +const cb0 = function (req, res, next) { + console.log('CB0') + next() } -var cb1 = function (req, res, next) { - console.log('CB1'); - next(); +const cb1 = function (req, res, next) { + console.log('CB1') + next() } -var cb2 = function (req, res) { - res.send('Hello from C!'); +const cb2 = function (req, res) { + res.send('Hello from C!') } -app.get('/example/c', [cb0, cb1, cb2]); -
    -
    +app.get('/example/c', [cb0, cb1, cb2]) +``` -独立函数与一组函数的组合可以处理一个路由。例如: +独立函数与一组函数的组合可以处理一个路由。例如: For example: -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/d', [cb0, cb1], function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from D!');
    -});
    -
    -
    +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +```

    响应方法

    -下表中响应对象 (`res`) 的方法可以向客户机发送响应,并终止请求/响应循环。如果没有从路由处理程序调用其中任何方法,客户机请求将保持挂起状态。 +下表中响应对象 (`res`) 的方法可以向客户机发送响应,并终止请求/响应循环。如果没有从路由处理程序调用其中任何方法,客户机请求将保持挂起状态。 If none of these methods are called from a route handler, the client request will be left hanging. -| 方法 | 描述 -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | 提示将要下载文件。 -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | 结束响应进程。 -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | 发送 JSON 响应。 -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | 在 JSONP 的支持下发送 JSON 响应。 -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | 重定向请求。 -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | 呈现视图模板。 -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | 发送各种类型的响应。 -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | 以八位元流形式发送文件。 -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | 设置响应状态码并以响应主体形式发送其字符串表示。 +| 方法 | 描述 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | 提示将要下载文件。 | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | 结束响应进程。 | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | 发送 JSON 响应。 | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | 在 JSONP 的支持下发送 JSON 响应。 | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | 重定向请求。 | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | 呈现视图模板。 | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | 发送各种类型的响应。 | +| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | 以八位元流形式发送文件。 | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | 设置响应状态码并以响应主体形式发送其字符串表示。 |

    app.route()

    您可以使用 `app.route()` 为路由路径创建可链接的路由处理程序。 因为在单一位置指定路径,所以可以减少冗余和输入错误。有关路由的更多信息,请参阅 [Router() 文档](/{{ page.lang }}/4x/api.html#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](/{{ page.lang }}/5x/api.html#router). 以下是使用 `app.route()` 定义的链式路由处理程序的示例。 -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    + .put((req, res) => { + res.send('Update the book') + }) +```

    express.Router

    -使用 `express.Router` 类来创建可安装的模块化路由处理程序。`Router` 实例是完整的中间件和路由系统;因此,常常将其称为“微型应用程序”。 +使用 `express.Router` 类来创建可安装的模块化路由处理程序。`Router` 实例是完整的中间件和路由系统;因此,常常将其称为“微型应用程序”。 A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app". 以下示例将路由器创建为模块,在其中装入中间件,定义一些路由,然后安装在主应用程序的路径中。 在应用程序目录中创建名为 `birds.js` 的路由器文件,其中包含以下内容: -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const router = express.Router()
     
     // middleware that is specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +const timeLog = (req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +}
    +router.use(timeLog)
    +
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` 接着,在应用程序中装入路由器模块: -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +const birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` 此应用程序现在可处理针对 `/birds` 和 `/birds/about` 的请求,调用特定于此路由的 `timeLog` 中间件函数。 + +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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/zh-cn/guide/using-middleware.md b/zh-cn/guide/using-middleware.md old mode 100755 new mode 100644 index 437fcc81b2..dfb2f0e9cf --- a/zh-cn/guide/using-middleware.md +++ b/zh-cn/guide/using-middleware.md @@ -1,260 +1,260 @@ --- layout: page title: 使用 Express 中间件 +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: zh-cn +redirect_from: " " --- # 使用中间件 Express 是一个路由和中间件 Web 框架,其自身只具有最低程度的功能:Express 应用程序基本上是一系列中间件函数调用。 -*中间件*函数能够访问[请求对象](/{{ page.lang }}/4x/api.html#req) (`req`)、[响应对象](/{{ page.lang }}/4x/api.html#res) (`res`) 以及应用程序的请求/响应循环中的下一个中间件函数。下一个中间件函数通常由名为 `next` 的变量来表示。 +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#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`. 中间件函数可以执行以下任务: -* 执行任何代码。 -* 对请求和响应对象进行更改。 -* 结束请求/响应循环。 -* 调用堆栈中的下一个中间件函数。 +- 执行任何代码。 +- 对请求和响应对象进行更改。 +- 结束请求/响应循环。 +- 调用堆栈中的下一个中间件函数。 -如果当前中间件函数没有结束请求/响应循环,那么它必须调用 `next()`,以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。 +如果当前中间件函数没有结束请求/响应循环,那么它必须调用 `next()`,以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。 Otherwise, the request will be left hanging. Express 应用程序可以使用以下类型的中间件: - - [应用层中间件](#middleware.application) - - [路由器层中间件](#middleware.router) - - [错误处理中间件](#middleware.error-handling) - - [内置中间件](#middleware.built-in) - - [第三方中间件](#middleware.third-party) +- [应用层中间件](#middleware.application) +- [路由器层中间件](#middleware.router) +- [错误处理中间件](#middleware.error-handling) +- [内置中间件](#middleware.built-in) +- [第三方中间件](#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.

    应用层中间件

    -使用 `app.use()` 和 `app.METHOD()` 函数将应用层中间件绑定到[应用程序对象](/{{ page.lang }}/4x/api.html#app)的实例,其中 `METHOD` 是中间件函数处理的请求的小写 HTTP 方法(例如 GET、PUT 或 POST)。 +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. -此示例显示没有安装路径的中间件函数。应用程序每次收到请求时执行该函数。 +This example shows a middleware function with no mount path. The function is executed every time the app receives a request. -
    -
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    -
    -
    +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` -此示例显示安装在 `/user/:id` 路径中的中间件函数。在 `/user/:id` 路径中为任何类型的 HTTP 请求执行此函数。 +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. -
    -
    -app.use('/user/:id', function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    - -此示例显示一个路由及其处理程序函数(中间件系统)。此函数处理针对 `/user/:id` 路径的 GET 请求。 - -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  res.send('USER');
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` -以下是在安装点使用安装路径装入一系列中间件函数的示例。 -它演示一个中间件子堆栈,用于显示针对 `/user/:id` 路径的任何类型 HTTP 请求的信息。 +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) => { + 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. -
    -
    -app.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` -路由处理程序使您可以为一个路径定义多个路由。以下示例为针对 `/user/:id` 路径的 GET 请求定义两个路由。第二个路由不会导致任何问题,但是永远都不会被调用,因为第一个路由结束了请求/响应循环。 +Route handlers enable you to define multiple routes for a path. 路由处理程序使您可以为一个路径定义多个路由。以下示例为针对 `/user/:id` 路径的 GET 请求定义两个路由。第二个路由不会导致任何问题,但是永远都不会被调用,因为第一个路由结束了请求/响应循环。 The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. 此示例显示一个中间件子堆栈,用于处理针对 `/user/:id` 路径的 GET 请求。 -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -}, function (req, res, next) {
    -  res.send('User Info');
    -});
    +```js
    +app.get('/user/:id', (req, res, next) => {
    +  console.log('ID:', req.params.id)
    +  next()
    +}, (req, res, next) => {
    +  res.send('User Info')
    +})
     
     // handler for the /user/:id path, which prints the user ID
    -app.get('/user/:id', function (req, res, next) {
    -  res.end(req.params.id);
    -});
    -
    -
    +app.get('/user/:id', (req, res, next) => { + res.send(req.params.id) +}) +``` 要跳过路由器中间件堆栈中剩余的中间件函数,请调用 `next('route')` 将控制权传递给下一个路由。 **注**:`next('route')` 仅在使用 `app.METHOD()` 或 `router.METHOD()` 函数装入的中间件函数中有效。 +{% capture next-function %} + +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} + 此示例显示一个中间件子堆栈,用于处理针对 `/user/:id` 路径的 GET 请求。 -
    -
    -app.get('/user/:id', function (req, res, next) {
    +```js
    +app.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next route
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass the control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    -  // render a regular page
    -  res.render('regular');
    -});
    +  else next()
    +}, (req, res, next) => {
    +  // send a regular response
    +  res.send('regular')
    +})
     
    -// handler for the /user/:id path, which renders a special page
    -app.get('/user/:id', function (req, res, next) {
    -  res.render('special');
    -});
    -
    -
    +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +此示例显示安装在 `/user/:id` 路径中的中间件函数。在 `/user/:id` 路径中为任何类型的 HTTP 请求执行此函数。 + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

    路由器层中间件

    路由器层中间件的工作方式与应用层中间件基本相同,差异之处在于它绑定到 `express.Router()` 的实例。 -
    -
    -var router = express.Router();
    -
    -
    +```js +const router = express.Router() +``` + +以下是在安装点使用安装路径装入一系列中间件函数的示例。 +它演示一个中间件子堆栈,用于显示针对 `/user/:id` 路径的任何类型 HTTP 请求的信息。 + 使用 `router.use()` 和 `router.METHOD()` 函数装入路由器层中间件。 以下示例代码使用路由器层中间件复制以上为应用层中间件显示的中间件系统: -
    -
    -var app = express();
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const app = express()
    +const router = express.Router()
     
     // a middleware function with no mount path. This code is executed for every request to the router
    -router.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time:', Date.now())
    +  next()
    +})
     
     // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    -router.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    +router.use('/user/:id', (req, res, next) => {
    +  console.log('Request URL:', req.originalUrl)
    +  next()
    +}, (req, res, next) => {
    +  console.log('Request Type:', req.method)
    +  next()
    +})
     
     // a middleware sub-stack that handles GET requests to the /user/:id path
    -router.get('/user/:id', function (req, res, next) {
    +router.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next router
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    +  else next()
    +}, (req, res, next) => {
       // render a regular page
    -  res.render('regular');
    -});
    +  res.render('regular')
    +})
     
     // handler for the /user/:id path, which renders a special page
    -router.get('/user/:id', function (req, res, next) {
    -  console.log(req.params.id);
    -  res.render('special');
    -});
    +router.get('/user/:id', (req, res, next) => {
    +  console.log(req.params.id)
    +  res.render('special')
    +})
     
     // mount the router on the app
    -app.use('/', router);
    -
    -
    +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. + +此示例显示一个中间件子堆栈,用于处理针对 `/user/:id` 路径的 GET 请求。 + +```js +const express = require('express') +const app = express() +const router = express.Router() + +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) + +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) + +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +```

    错误处理中间件

    -错误处理中间件始终采用*四个*自变量。必须提供四个自变量,以将函数标识为错误处理中间件函数。即使无需使用 `next` 对象,也必须指定该对象以保持特征符的有效性。否则,`next` 对象将被解释为常规中间件,从而无法处理错误。 +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.
    错误处理中间件函数的定义方式与其他中间件函数基本相同,差别在于错误处理函数有四个自变量而不是三个,专门具有特征符 `(err, req, res, next)`: -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` 有关错误处理中间件的详细信息,请参阅:[错误处理](/{{ page.lang }}/guide/error-handling.html)。

    内置中间件

    -自 V4.x 起,Express 不再依赖于 [Connect](https://github.com/senchalabs/connect)。除 `express.static` 外,先前 Express 随附的所有中间件函数现在以单独模块的形式提供。请查看[中间件函数的列表](https://github.com/senchalabs/connect#middleware)。 - -

    express.static(root, [options])

    - -Express 中唯一内置的中间件函数是 `express.static`。此函数基于 [serve-static](https://github.com/expressjs/serve-static),负责提供 Express 应用程序的静态资源。 - -`root` 自变量指定从其中提供静态资源的根目录。 - -可选的 `options` 对象可以具有以下属性: - -| 属性 | 描述 | 类型 | 缺省值 | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | 是否对外输出文件名以点(.)开头的文件。有效值包括“allow”、“deny”和“ignore” | 字符串 | “ignore” | -| `etag` | 启用或禁用 etag 生成 | 布尔 | `true` | -| `extensions` | 用于设置后备文件扩展名。 | 数组 | `[]` | -| `index` | 发送目录索引文件。设置为 `false` 可禁用建立目录索引。 | 混合 | “index.html” | - `lastModified` | 将 `Last-Modified` 的头设置为操作系统上该文件的上次修改日期。有效值包括 `true` 或 `false`。 | 布尔 | `true` | -| `maxAge` | 设置 Cache-Control 头的 max-age 属性(以毫秒或者 [ms 格式](https://www.npmjs.org/package/ms)中的字符串为单位) | 数字 | 0 | -| `redirect` | 当路径名是目录时重定向到结尾的“/”。 | 布尔 | `true` | -| `setHeaders` | 用于设置随文件一起提供的 HTTP 头的函数。 | 函数 | | - -以下示例将使用了 `express.static` 中间件,并且提供了一个详细的'options'对象(作为示例): - -
    -
    -var options = {
    -  dotfiles: 'ignore',
    -  etag: false,
    -  extensions: ['htm', 'html'],
    -  index: false,
    -  maxAge: '1d',
    -  redirect: false,
    -  setHeaders: function (res, path, stat) {
    -    res.set('x-timestamp', Date.now());
    -  }
    -}
    -
    -app.use(express.static('public', options));
    -
    -
    - -对于每个应用程序,可以有多个静态目录: +Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). 自 V4.x 起,Express 不再依赖于 [Connect](https://github.com/senchalabs/connect)。除 `express.static` 外,先前 Express 随附的所有中间件函数现在以单独模块的形式提供。请查看[中间件函数的列表](https://github.com/senchalabs/connect#middleware)。 -
    -
    -app.use(express.static('public'));
    -app.use(express.static('uploads'));
    -app.use(express.static('files'));
    -
    -
    +Express has the following built-in middleware functions: -有关 `serve-static` 函数及其选项的更多详细信息,请参阅:[serve-static](https://github.com/expressjs/serve-static) 文档。 +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**

    第三方中间件

    @@ -264,21 +264,17 @@ app.use(express.static('files')); 以下示例演示如何安装和装入 cookie 解析中间件函数 `cookie-parser`。 -
    -
    +```bash
     $ npm install cookie-parser
    -
    -
    +``` -
    -
    -var express = require('express');
    -var app = express();
    -var cookieParser = require('cookie-parser');
    +```js
    +const express = require('express')
    +const app = express()
    +const cookieParser = require('cookie-parser')
     
     // load the cookie-parsing middleware
    -app.use(cookieParser());
    -
    -
    +app.use(cookieParser()) +``` 有关 Express 常用的第三方中间件函数的部分列表,请参阅:[第三方中间件](../resources/middleware.html)。 diff --git a/zh-cn/guide/using-template-engines.md b/zh-cn/guide/using-template-engines.md old mode 100755 new mode 100644 index 51f0694cb4..03f5841b06 --- a/zh-cn/guide/using-template-engines.md +++ b/zh-cn/guide/using-template-engines.md @@ -1,61 +1,66 @@ --- layout: page title: 将模板引擎用于 Express +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: zh-cn +redirect_from: " " --- # 将模板引擎用于 Express -在 Express 可以呈现模板文件之前,必须设置以下应用程序设置: +A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces +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. -* `views`:模板文件所在目录。例如:`app.set('views', './views')` -* `view engine`:要使用的模板引擎。例如:`app.set('view engine', 'pug')` +The [Express application generator](/{{ page.lang }}/starter/generator.html) 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. + +To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: + +- `views`, the directory where the template files are located. `views`:模板文件所在目录。例如:`app.set('views', './views')` + This defaults to the `views` directory in the application root directory. +- `view engine`, the template engine to use. `view engine`:要使用的模板引擎。例如:`app.set('view engine', 'pug')` 然后安装对应的模板引擎 npm 包: -
    -
    +```bash
     $ npm install pug --save
    -
    -
    +```
    与 Express 兼容的模板引擎(例如 Pug)导出名为 `__express(filePath, options, callback)` 的函数,该函数由 `res.render()` 函数调用以呈现模板代码。 某些模板引擎并不遵循此约定。[Consolidate.js](https://www.npmjs.org/package/consolidate) 库通过映射所有流行的 Node.js 模板引擎来遵循此约定,因此可以在 Express 内无缝工作。 + + +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. +
    在设置视图引擎之后,不必指定该引擎或者在应用程序中装入模板引擎模块;Express 在内部装入此模块,如下所示(针对以上示例)。 -
    -
    -app.set('view engine', 'pug');
    -
    -
    +```js +app.set('view engine', 'pug') +``` 在 `views` 目录中创建名为 `index.pug` 的 Pug 模板文件,其中包含以下内容: -
    -
    +```pug
     html
       head
         title= title
       body
         h1= message
    -
    -
    +``` -随后创建路由以呈现 `index.pug` 文件。如果未设置 `view engine` 属性,必须指定 `view` 文件的扩展名。否则,可以将其忽略。 +Create a route to render the `index.pug` file. If the `view engine` property is not set, +you must specify the extension of the `view` file. Otherwise, you can omit it. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` 向主页发出请求时,`index.pug` 文件将呈现为 HTML。 - -要了解有关模板引擎在 Express 中如何工作的更多信息,请参阅:[“为 Express 开发模板引擎”](/{{ page.lang }}/advanced/developing-template-engines.html)。 +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/zh-cn/guide/writing-middleware.md b/zh-cn/guide/writing-middleware.md old mode 100755 new mode 100644 index b78d503f4d..1b4e617399 --- a/zh-cn/guide/writing-middleware.md +++ b/zh-cn/guide/writing-middleware.md @@ -1,33 +1,35 @@ --- layout: page title: 编写中间件以用于 Express 应用程序 +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: zh-cn +redirect_from: " " --- # 编写中间件以用于 Express 应用程序

    概述

    -*中间件*函数能够访问[请求对象](/{{ page.lang }}/4x/api.html#req) (`req`)、[响应对象](/{{ page.lang }}/4x/api.html#res) (`res`) 以及应用程序的请求/响应循环中的下一个中间件函数。下一个中间件函数通常由名为 `next` 的变量来表示。 +_中间件_函数能够访问[请求对象](/{{ page.lang }}/4x/api.html#req) (`req`)、[响应对象](/{{ page.lang }}/4x/api.html#res) (`res`) 以及应用程序的请求/响应循环中的下一个中间件函数。下一个中间件函数通常由名为 `next` 的变量来表示。 The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware. 中间件函数可以执行以下任务: -* 执行任何代码。 -* 对请求和响应对象进行更改。 -* 结束请求/响应循环。 -* 调用堆栈中的下一个中间件。 +- 执行任何代码。 +- 对请求和响应对象进行更改。 +- 结束请求/响应循环。 +- 调用堆栈中的下一个中间件。 -如果当前中间件函数没有结束请求/响应循环,那么它必须调用 `next()`,以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。 +如果当前中间件函数没有结束请求/响应循环,那么它必须调用 `next()`,以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。 Otherwise, the request will be left hanging. 以下示例显示中间件函数调用的元素: - -
    - +
    + +
    中间件函数适用的路径(路由)。
    @@ -40,62 +42,67 @@ lang: zh-cn
    中间件函数的 HTTP 请求自变量,按约定称为“req”。
    +Elements of a middleware function call -
    中间件函数适用的 HTTP 方法。
    +
    中间件函数适用的 HTTP 方法。
    +
    -以下是“Hello World”Express 应用程序的简单示例,将为其定义两个中间件函数: +Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error. -
    -
    -var express = require('express');
    -var app = express();
    +

    示例

    + +以下是“Hello World”Express 应用程序的简单示例,将为其定义两个中间件函数: +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. -app.get('/', function (req, res) { - res.send('Hello World!'); -}); +```js +const express = require('express') +const app = express() -app.listen(3000); -
    -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -

    开发

    +app.listen(3000) +``` -以下是称为“myLogger”的中间件函数的简单示例。此函数仅在应用程序的请求通过它时显示“LOGGED”。中间件函数会分配给名为 `myLogger` 的变量。 +

    Middleware function myLogger

    +Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. 以下是称为“myLogger”的中间件函数的简单示例。此函数仅在应用程序的请求通过它时显示“LOGGED”。中间件函数会分配给名为 `myLogger` 的变量。 -
    -
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    -
    -
    +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
    +Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. + 请注意以上对 `next()` 的调用。调用此函数时,将调用应用程序中的下一个中间件函数。 `next()` 函数不是 Node.js 或 Express API 的一部分,而是传递给中间件函数的第三自变量。`next()` 函数可以命名为任何名称,但是按约定,始终命名为“next”。为了避免混淆,请始终使用此约定。 + The `next()` function could be named anything, but by convention it is always named "next". +To avoid confusion, always use this convention.
    -要装入中间件函数,请调用 `app.use()` 并指定中间件函数。 -例如,以下代码在根路径 (/) 的路由之前装入 `myLogger` 中间件函数。 +To load the middleware function, call `app.use()`, specifying the middleware function. +For example, the following code loads the `myLogger` middleware function before the route to the root path (/). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    +const myLogger = function (req, res, next) {
    +  console.log('LOGGED')
    +  next()
    +}
     
    -app.use(myLogger);
    +app.use(myLogger)
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    +app.listen(3000) +``` 应用程序每次收到请求时,会在终端上显示消息“LOGGED”。 @@ -105,43 +112,112 @@ app.listen(3000); 中间件函数 `myLogger` 只是显示消息,然后通过调用 `next()` 函数将请求传递到堆栈中的下一个中间件函数。 +

    Middleware function requestTime

    + 下一个示例将名为 `requestTime` 的属性添加到请求对象。我们将此中间件函数命名为“requestTime”。 -
    -
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    -
    -
    +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` -现在,该应用程序使用 `requestTime` 中间件函数。此外,根路径路由的回调函数使用由中间件函数添加到 `req`(请求对象)的属性。 +The app now uses the `requestTime` middleware function. 现在,该应用程序使用 `requestTime` 中间件函数。此外,根路径路由的回调函数使用由中间件函数添加到 `req`(请求对象)的属性。 -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    +const requestTime = function (req, res, next) {
    +  req.requestTime = Date.now()
    +  next()
    +}
     
    -app.use(requestTime);
    +app.use(requestTime)
     
    -app.get('/', function (req, res) {
    -  var responseText = 'Hello World!
    '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) -app.listen(3000); -
    -
    +app.listen(3000) +``` 您向应用程序根发出请求时,此应用程序当前在浏览器中显示请求的时间戳记。 +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    + 因为您拥有请求对象、响应对象、堆栈中的下一个中间件函数以及整个 Node.js API 的访问权,所以中间件函数的可能性是无穷的。 有关 Express 中间件的更多信息,请参阅:[使用 Express 中间件](/{{ page.lang }}/guide/using-middleware.html)。 + +

    Configurable middleware

    + +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. + +File: `my-middleware.js` + +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` + +The middleware can now be used as shown below. + +```js +const mw = require('./my-middleware.js') + +app.use(mw({ option1: '1', option2: '2' })) +``` + +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/zh-cn/index.md b/zh-cn/index.md index 9750573408..c2d7097ab8 100644 --- a/zh-cn/index.md +++ b/zh-cn/index.md @@ -1,50 +1,61 @@ --- layout: home -title: Express - Node.js Web 应用程序框架 +title: Express - Node.js web 应用框架 +description: "Express 是 Node.js 的一个快速、灵活、极简的Web框架,为网页和移动应用提供了一套强大的功能特性。" menu: home -lang: zh-cn +redirect_from: " " --- +
    - {% include header/header-{{ page.lang }}.html %} -
    - - 高度包容、快速而极简的 Node.js Web 框架 + +

    快速、灵活、极简的 Node.js Web 框架

    -
    $ npm install express --save
    -
    -
    - +
    $ npm install express --save
    -
    - - -
    - -
    -
    -

    Web 应用程序

    Express 是一种保持最低程度规模的灵活 Node.js Web 应用程序框架,为 Web 和移动应用程序提供一组强大的功能。
    +
    -
    -

    API

    使用您提议的各种 HTTP 实用程序方法和中间件,快速方便地创建强大的 API。
    +```javascript +const express = require('express') +const app = express() +const port = 3000 -
    -

    性能

    Express 提供精简的基本 Web 应用程序功能,而不会隐藏您了解和青睐的 Node.js 功能。
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -
    -

    框架

    许多基于 Express 的 流行框架 。 -
    +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +```
    -
    - diff --git a/zh-cn/resources/community.md b/zh-cn/resources/community.md old mode 100755 new mode 100644 index 871529e56e..fc0c994161 --- a/zh-cn/resources/community.md +++ b/zh-cn/resources/community.md @@ -1,34 +1,88 @@ --- layout: page title: Express 社区 +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: zh-cn +redirect_from: " " --- # 社区 -## 邮件发送列表 +## Technical committee -在 [Google Group](https://groups.google.com/group/express-js) 中加入超过 2000 名 Express 用户的行列,浏览超过 5000 个讨论。 +The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, +and other issues relevant to the Express project. Each meeting is typically announced in an +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is +open to all observers. -## Gitter +The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -[expressjs/express 聊天室](https://gitter.im/expressjs/express)是对 Express 相关的日常讨论感兴趣的开发人员的理想去处。 +Members of the Express technical committee are: -## IRC 频道 +**Active:** -数百名开发人员每天参与讨论 freenode 的 #express 话题。 -如果您存在有关框架的问题,请马上加入讨论以获得快速反馈。 +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida -## 示例 +**Inactive:** -查看存储库中数十个 Express 应用程序[示例](https://github.com/expressjs/express/tree/master/examples),这些示例涵盖从 API 设计和认证到模板引擎集成的一切内容。 +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express is made of many modules + +我们充满活力的社区已创建了大量各种各样的扩展、[中间件模块](/{{ page.lang }}/resources/middleware.html)和更高层次的框架。请在 [wiki](https://github.com/expressjs/express/wiki) 中了解详细信息。 + +Additionally, the Express community maintains modules in these two GitHub orgs: + +- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. + +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). ## 问题 如果您发现程序中存在错误,或者只是希望提出功能请求,请在[问题队列](https://github.com/expressjs/express/issues)中开具凭证。 -## 第三方 +## 示例 -我们充满活力的社区已创建了大量各种各样的扩展、[中间件模块](/{{ page.lang }}/resources/middleware.html)和更高层次的框架。请在 [wiki](https://github.com/expressjs/express/wiki) 中了解详细信息。 +查看存储库中数十个 Express 应用程序[示例](https://github.com/expressjs/express/tree/master/examples),这些示例涵盖从 API 设计和认证到模板引擎集成的一切内容。 + +## Github Discussions + +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. + +# Branding of Express.js + +## Express.js Logo + +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/zh-cn/resources/contributing.md b/zh-cn/resources/contributing.md new file mode 100644 index 0000000000..e37cee3122 --- /dev/null +++ b/zh-cn/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/zh-cn/resources/frameworks.md b/zh-cn/resources/frameworks.md deleted file mode 100644 index 7898e6b997..0000000000 --- a/zh-cn/resources/frameworks.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -layout: page -title: 基于 Express 的流行框架 -menu: frameworks -lang: zh-cn ---- - -# 基于 Express 的流行框架 - -很多基于 Express 构建的 Node.js 框架: - -- **[Feathers](http://feathersjs.com)**: 在几分钟内建立原型,并在几天内生产就绪的实时应用程序。 -- **[ItemsAPI](https://www.itemsapi.com/)**: 在 Express 和 Elasticsearch 上构建的 Web 和移动应用程序搜索后端。 -- **[KeystoneJS](http://keystonejs.com/)**: 基于 Express 和 MongoDB 搭建的 Node.js CMS 和 web 应用程序平台。 -- **[Kraken](http://krakenjs.com/)**: 通过提供结构和约定来扩展 Express 的安全和可扩展层。 -- **[LEAN-STACK](http://lean-stack.io)**: 纯粹的 JavaScript Stack。 -- **[LoopBack](http://loopback.io)**: 用于快速创建动态端到端 REST API 的高度可扩展的开源 Node.js 框架。 -- **[MEAN](http://mean.io/)**: 完整的全栈 JavaScript 框架,简化和加速 Web 应用程序开发。 -- **[Sails](http://sailsjs.org/)**: Node.js 的 MVC 框架,用于构建实用、生产就绪的应用程序。 -- **[Bottr](http://bottr.co/)**: 简化构建 chatbot 应用程序的框架。 -- **[Hydra-Express](https://github.com/flywheelsports/fwsp-hydra-express)**: Hydra-Express 是一个轻量级库,有助于构建使用 ExpressJS 的 Node.js 微服务。 -- **[Blueprint](http://github.com/onehilltech/blueprint)**: 高度可配置的 MVC 框架,用于从可重用组件组合生产就绪的服务。 -- **[Locomotive](http://locomotivejs.org/)**: 来自 Passport.js 作者, 为 Node.js 构建的强大 MVC Web 框架。 -- **[graphql-yoga](https://github.com/graphcool/graphql-yoga)**: 功能齐全,简单轻便的 GraphQL 服务器。 diff --git a/zh-cn/resources/glossary.md b/zh-cn/resources/glossary.md old mode 100755 new mode 100644 index b4b4801fc8..9890b6793d --- a/zh-cn/resources/glossary.md +++ b/zh-cn/resources/glossary.md @@ -1,56 +1,65 @@ --- layout: page title: Express 词汇表 +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: zh-cn +redirect_from: " " --- # 词汇表 -### 开放源码 (open-source, open source) +### 应用程序 (application) -英文中用作形容词时,以连字符连接;例如:“This is open-source software”。请参阅 [Wikipedia 上的开源软件](http://en.wikipedia.org/wiki/Open-source_software)。注:虽然不对此术语添加连字符也很常见,但是我们使用标准英语规则对复合形容词添加连字符。 +In general, one or more programs that are designed to carry out operations for a specific purpose. 一般而言,表示设计为针对特定目的执行操作的一个或多个程序。在 Express 的上下文中,表示使用 Node.js 平台上运行的 Express API 的一个程序。可能还指[应用程序对象](/{{ page.lang }}/api.html#express)。 Might also refer to an [app object](/{{ page.lang }}/api.html#express). -### 路由 (route) +### API -标识资源的部分 URL。例如,在 `http://foo.com/products/id` 中,“/products/id”是路由。 +应用程序编程接口。在首次使用时包含此缩写。 Spell out the abbreviation when it is first used. -### 路由器 (router) +### Express -请参阅“API 参考”中的[路由器](/{{ page.lang }}/4x/api.html#router)。 +Node.js 应用程序的一种高度包容、快速而极简的 Web 框架。一般而言,“Express”优先于“Express.js”,但是后者也可接受。 In general, "Express" is preferred to "Express.js," though the latter is acceptable. -### 请求 (request) +### libuv -HTTP 请求。客户机向服务器提交 HTTP 请求消息,然后服务器返回响应。该请求必须使用若干[请求方法](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods)之一,例如 GET、POST 等。 +一种多平台支持库,关注异步 I/O,主要供 Node.js 使用。 -### 响应 (response) +### middleware -HTTP 响应。服务器将 HTTP 响应消息返回给客户机。此响应包含关于请求的完整状态信息,可能还在消息体中包含请求的内容。 +在最终请求处理程序之前由 Express 路由层调用的函数,因此位于原始请求与最终期望的路由之间的中间位置。有关中间件的术语有几点说明: A few fine points of terminology around middleware: -### 应用程序 (application) +- 调用 `var foo = require('middleware')`:_需要_或_使用_ Node.js 模块。随后 `var mw = foo()` 语句通常返回中间件。 Then the statement `var mw = foo()` typically returns the middleware. +- 调用 `app.use(mw)`:_将中间件添加到全局处理堆栈_。 +- 调用 `app.get('/foo', mw, function (req, res) { ... })`:_将中间件添加到“GET /foo”处理堆栈_。 + +### Node.js -一般而言,表示设计为针对特定目的执行操作的一个或多个程序。在 Express 的上下文中,表示使用 Node.js 平台上运行的 Express API 的一个程序。可能还指[应用程序对象](/{{ page.lang }}/api.html#express)。 +A software platform that is used to build scalable network applications. 用于构建可扩展网络应用程序的一种软件平台。Node.js 将 JavaScript 用作其脚本编制语言,并通过非阻塞 I/O 和单线程事件循环实现大吞吐量。请参阅 [nodejs.org](http://nodejs.org/)。**使用说明**:最初为“Node.js”,后来成为“Node”。 See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". -### 中间件 (middleware) +### 开放源码 (open-source, open source) -在最终请求处理程序之前由 Express 路由层调用的函数,因此位于原始请求与最终期望的路由之间的中间位置。有关中间件的术语有几点说明: +英文中用作形容词时,以连字符连接;例如:“This is open-source software”。请参阅 [Wikipedia 上的开源软件](http://en.wikipedia.org/wiki/Open-source_software)。注:虽然不对此术语添加连字符也很常见,但是我们使用标准英语规则对复合形容词添加连字符。 See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). - * 调用 `var foo = require('middleware')`:*需要*或*使用* Node.js 模块。随后 `var mw = foo()` 语句通常返回中间件。 - * 调用 `app.use(mw)`:*将中间件添加到全局处理堆栈*。 - * 调用 `app.get('/foo', mw, function (req, res) { ... })`:*将中间件添加到“GET /foo”处理堆栈*。 +{% capture english-rules %} -### API +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. -应用程序编程接口。在首次使用时包含此缩写。 +{% endcapture %} -### Express +{% include admonitions/note.html content=english-rules %} -Node.js 应用程序的一种高度包容、快速而极简的 Web 框架。一般而言,“Express”优先于“Express.js”,但是后者也可接受。 +### 请求 (request) -### libuv +An HTTP request. HTTP 响应。服务器将 HTTP 响应消息返回给客户机。此响应包含关于请求的完整状态信息,可能还在消息体中包含请求的内容。 HTTP 请求。客户机向服务器提交 HTTP 请求消息,然后服务器返回响应。该请求必须使用若干[请求方法](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods)之一,例如 GET、POST 等。 -一种多平台支持库,关注异步 I/O,主要供 Node.js 使用。 +### 响应 (response) -### Node.js +An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body. + +### 路由 (route) + +Part of a URL that identifies a resource. 标识资源的部分 URL。例如,在 `http://foo.com/products/id` 中,“/products/id”是路由。 -用于构建可扩展网络应用程序的一种软件平台。Node.js 将 JavaScript 用作其脚本编制语言,并通过非阻塞 I/O 和单线程事件循环实现大吞吐量。请参阅 [nodejs.org](http://nodejs.org/)。**使用说明**:最初为“Node.js”,后来成为“Node”。 +### 路由器 (router) + +请参阅“API 参考”中的[路由器](/{{ page.lang }}/4x/api.html#router)。 diff --git a/zh-cn/resources/learning.md b/zh-cn/resources/learning.md deleted file mode 100755 index 9d540a701f..0000000000 --- a/zh-cn/resources/learning.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -layout: page -title: 额外学习 -menu: resources -lang: zh-cn ---- - -# 额外学习 - -
    免责声明:未经认可的社区内容。
    - -## 书籍 - -以下是有关 Express 的众多书籍中的一些: - -- **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, April 2016. - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Getting MEAN with Mongo, Express, Angular, and Node, Second Edition](http://www.manning.com/sholmes2/)**, -Manning Publications, April 2017. - - **[Pro Express.js: Master Express.js: The Node.js Framework For Your Web Development](http://www.apress.com/9781484200384)**, -Apress, December 2014. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 -- **[Builder Book: Build a Full Stack JavaScript Web App from Scratch](https://builderbook.org/book)**, -self-published, February 2018. -- **[MERN Quick Start Guide](https://www.amazon.com/dp/1787281086)**, Packt Publishing, May 2018 -- **[Functional Design Patterns for Express.js](https://jonathanleemartin.com/books/)**, self-published, June 2019. - -### 将你的书籍添加到这! - -[编辑 Markdown 文件](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) 并添加指向您的书籍的链接,然后提交拉取请求(需要 GitHub 登录)。请遵循上述清单的格式。 - -## 博客 - -- [StrongLoop Blog: Express category](https://strongloop.com/strongblog/tag_Express.html) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) -- [Baboon Blog: Express category](http://www.baboon.ir/tutorials/expressjs/) (波斯语) -- [Techforgeek Blog: Express category](http://techforgeek.com/expressjs/) -- [RoseHosting.com Blog: Express tag](https://www.rosehosting.com/blog/tag/express/) -- [ThisHosting.Rocks: Express tag](https://thishosting.rocks/tag/express-js/) -- [Code with Hugo blog: Express tag](https://codewithhugo.com/tags/express) -- [Dev.to blog: Express category](https://dev.to/ghvstcode/understanding-express-middleware-a-beginners-guide-g73) - -### 将你的博客添加到这! - -[编辑 Markdown 文件](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) 并添加指向您的博客的链接,然后提交拉取请求(需要 GitHub 登录)。请遵循上述清单的格式。 - -## DEV 社区 - -[DEV 的 express 标签](https://dev.to/t/express) 是共享 Express 项目,文章和教程以及开始讨论并征求有关 Express 相关主题的反馈的地方。欢迎所有技能水平的开发人员参加。 - -## 视频教程 -- [Learning ExpressJS: Express category](https://getbuzz.io/c/learning-expressjs) -- [Learn Express.js in 14 days](https://iLoveCoding.org/courses/expressjs) - Practice Projects included diff --git a/zh-cn/resources/middleware.md b/zh-cn/resources/middleware.md old mode 100755 new mode 100644 index c63de83d7b..9c642526cb --- a/zh-cn/resources/middleware.md +++ b/zh-cn/resources/middleware.md @@ -1,63 +1,44 @@ --- -layout: page +layout: middleware title: Express 中间件 +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: zh-cn +redirect_from: " " +module: mw-home --- -# 第三方中间件 +## Express 中间件 -以下是一些 Express 中间件模块: +The Express middleware modules listed here are maintained by the +[Expressjs team](https://github.com/orgs/expressjs/people). - - [body-parser](https://github.com/expressjs/body-parser):先前为 `express.bodyParser`、`json` 和 `urlencoded`。另请参阅: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression):先前为 `express.compress`。 - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus):用于提供最优映像的 Connect/Express 中间件模块。如有可能,可将映像切换为 `.webp` 或 `.jxr`。 - - [connect-timeout](https://github.com/expressjs/timeout):先前为 `express.timeout`。 - - [cookie-parser](https://github.com/expressjs/cookie-parser):先前为 `express.cookieParser`。 - - [cookie-session](https://github.com/expressjs/cookie-session):先前为 `express.cookieSession`。 - - [csurf](https://github.com/expressjs/csurf):先前为 `express.csrf`。 - - [errorhandler](https://github.com/expressjs/errorhandler):先前为 `express.errorHandler`。 - - [express-debug](https://github.com/devoidfury/express-debug):不引人注目的开发工具,用于向应用程序添加一个选项卡,其中包含有关模板变量(本地)、当前会话、有用请求数据等方面的信息。 - - [express-partial-response](https://github.com/nemtsov/express-partial-response):Express 中间件模块,使用 Google API 的 Partial Response,根据 `fields` 查询字符串过滤掉 JSON 响应的各个部分。 - - [express-session](https://github.com/expressjs/session):先前为 `express.session`。 - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn):Express 中间件模块,将 CDN 用于静态资产,具有多主机支持(例如:cdn1.host.com、cdn2.host.com)。 - - [express-slash](https://github.com/ericf/express-slash):Express 中间件模块,适用于对末尾斜杠有很严格要求的人员。 - - [express-stormpath](https://github.com/stormpath/stormpath-express):实现用户存储、认证、授权、SSO 和数据安全性的 Express 中间件模块。 - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize):中间件模块,用于将包含大写字母的 HTTP 请求转换为标准的小写形式。 - - [helmet](https://github.com/helmetjs/helmet):一个模块,用于通过设置各种 HTTP 头来帮助保护应用程序。 - - [join-io](https://github.com/coderaiser/join-io "join-io"):一个模块,用于实时联接文件以减少请求数目。 - - [method-override](https://github.com/expressjs/method-override):先前为 `express.methodOverride`。 - - [morgan](https://github.com/expressjs/morgan):先前为 `logger`。 - - [passport](https://github.com/jaredhanson/passport):用于认证的 Express 中间件模块。 - - [response-time](https://github.com/expressjs/response-time):先前为 `express.responseTime`。 - - [serve-favicon](https://github.com/expressjs/serve-favicon):先前为 `express.favicon`。 - - [serve-index](https://github.com/expressjs/serve-index):先前为 `express.directory`。 - - [serve-static](https://github.com/expressjs/serve-static):用于提供静态内容的模块。 - - [static-expiry](https://github.com/paulwalker/connect-static-expiry):静态资产的指纹式 URL 或高速缓存头,包含对一个或多个外部域的支持。 - - [vhost](https://github.com/expressjs/vhost):先前为 `express.vhost`。 - - [view-helpers](https://github.com/madhums/node-view-helpers):Express 中间件模块,用于向视图提供常见助手方法。 - - [sriracha-admin](https://github.com/hdngr/siracha):Express 中间件模块,为 Mongoose 动态生成管理站点。 +| Middleware module | 描述 | +| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | -Connect 先前随附的一些中间件模块不再受到 Connect/Express 团队的支持。这些模块由替代模块所取代,或者应该被更好的模块取代。请使用以下替代模块之一: +## Additional middleware modules - - express.cookieParser - - [cookies](https://github.com/jed/cookies) 和 [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) +These are some additional popular middleware modules. -有关更多中间件模块,请参阅: +{% include community-caveat.html %} - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| Middleware module | 描述 | +| --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet):一个模块,用于通过设置各种 HTTP 头来帮助保护应用程序。 | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport):用于认证的 Express 中间件模块。 | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/zh-cn/resources/middleware/body-parser.md b/zh-cn/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/zh-cn/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/zh-cn/resources/middleware/compression.md b/zh-cn/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/zh-cn/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/zh-cn/resources/middleware/connect-rid.md b/zh-cn/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/zh-cn/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/zh-cn/resources/middleware/cookie-parser.md b/zh-cn/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/zh-cn/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/zh-cn/resources/middleware/cookie-session.md b/zh-cn/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/zh-cn/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/zh-cn/resources/middleware/cors.md b/zh-cn/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/zh-cn/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/zh-cn/resources/middleware/errorhandler.md b/zh-cn/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/zh-cn/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/zh-cn/resources/middleware/method-override.md b/zh-cn/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/zh-cn/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/zh-cn/resources/middleware/morgan.md b/zh-cn/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/zh-cn/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/zh-cn/resources/middleware/multer.md b/zh-cn/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/zh-cn/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/zh-cn/resources/middleware/response-time.md b/zh-cn/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/zh-cn/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/zh-cn/resources/middleware/serve-favicon.md b/zh-cn/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/zh-cn/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/zh-cn/resources/middleware/serve-index.md b/zh-cn/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/zh-cn/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/zh-cn/resources/middleware/serve-static.md b/zh-cn/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/zh-cn/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/zh-cn/resources/middleware/session.md b/zh-cn/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/zh-cn/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/zh-cn/resources/middleware/timeout.md b/zh-cn/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/zh-cn/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/zh-cn/resources/middleware/vhost.md b/zh-cn/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/zh-cn/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/zh-cn/resources/utils.md b/zh-cn/resources/utils.md new file mode 100644 index 0000000000..2ea63990f2 --- /dev/null +++ b/zh-cn/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/zh-cn/starter/basic-routing.md b/zh-cn/starter/basic-routing.md old mode 100755 new mode 100644 index 25dfba7cfc..b41ac8da7c --- a/zh-cn/starter/basic-routing.md +++ b/zh-cn/starter/basic-routing.md @@ -1,24 +1,24 @@ --- layout: page title: Express 基本路由 +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: zh-cn +redirect_from: " " --- # 基本路由 -*路由*用于确定应用程序如何响应对特定端点的客户机请求,包含一个 URI(或路径)和一个特定的 HTTP 请求方法(GET、POST 等)。 +_路由_用于确定应用程序如何响应对特定端点的客户机请求,包含一个 URI(或路径)和一个特定的 HTTP 请求方法(GET、POST 等)。 每个路由可以具有一个或多个处理程序函数,这些函数在路由匹配时执行。 路由定义采用以下结构: -
    -
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` -其中: +Where: - `app` 是 `express` 的实例。 - `METHOD` 是 [HTTP 请求方法](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol)。 @@ -26,49 +26,45 @@ app.METHOD(PATH, HANDLER) - `HANDLER` 是在路由匹配时执行的函数。
    +This tutorial assumes that an instance of `express` named `app` is created and the server is running. 本教程假定创建了名为 `app` 的 `express` 实例且服务器正在运行。如果您对创建和启动应用程序并不熟悉,请参阅 [Hello world 示例](/{{ page.lang }}/starter/hello-world.html)。 +
    以下示例演示了如何定义简单路由。 以主页上的 `Hello World!` 进行响应: -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -在根路由 (`/`) 上(应用程序的主页)对 POST 请求进行响应: +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` 对 `/user` 路由的 PUT 请求进行响应: -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` 对 `/user` 路由的 DELETE 请求进行响应: -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` 有关路由的更多详细信息,请参阅[路由指南](/{{ page.lang }}/guide/routing.html)。 + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/zh-cn/starter/examples.md b/zh-cn/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/zh-cn/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/zh-cn/starter/faq.md b/zh-cn/starter/faq.md old mode 100755 new mode 100644 index 76a3f62eeb..9fcbcb10e6 --- a/zh-cn/starter/faq.md +++ b/zh-cn/starter/faq.md @@ -1,72 +1,97 @@ --- layout: page title: Express 常见问题及解答 +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: zh-cn +redirect_from: " " --- # 常见问题及解答 ## 如何构造自己的应用程序? -这个问题没有固定答案。具体取决于您的应用程序以及参与团队的规模。为了实现尽可能的灵活性,Express 在结构方面不作任何假设。 +There is no definitive answer to this question. 这个问题没有固定答案。具体取决于您的应用程序以及参与团队的规模。为了实现尽可能的灵活性,Express 在结构方面不作任何假设。 To be as +flexible as possible, Express makes no assumptions in terms of structure. -路由和其他特定于应用程序的逻辑可以存在于您首选的任何目录结构的任意数量的文件中。请查看以下示例以获取灵感: +路由和其他特定于应用程序的逻辑可以存在于您首选的任何目录结构的任意数量的文件中。请查看以下示例以获取灵感: View the following +examples for inspiration: -* [路由列表](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [路由图](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [MVC 样式控制器](https://github.com/expressjs/express/tree/master/examples/mvc) +- [路由列表](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [路由图](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [MVC 样式控制器](https://github.com/expressjs/express/tree/master/examples/mvc) 另外还有针对 Express 的第三方扩展,这有助于简化某些模式: -* [资源丰富的路由](https://github.com/expressjs/express-resource) +- [资源丰富的路由](https://github.com/expressjs/express-resource) ## 如何定义模型? -Express 没有数据库概念。此概念留给第三方 Node 模块实现,因此可以接入几乎任何数据库。 +Express 没有数据库概念。此概念留给第三方 Node 模块实现,因此可以接入几乎任何数据库。 This concept is +left up to third-party Node modules, allowing you to +interface with nearly any database. 请参阅 [LoopBack](http://loopback.io) 以了解处于模型中心的基于 Express 的框架。 ## 如何对用户进行认证? +Authentication is another opinionated area that Express does not +venture into. You may use any authentication scheme you wish. 认证是 Express 没有涉足的另一严格领域。您可使用所希望的任何认证方案。 要了解简单的“用户名/密码”方案,请参阅[此示例](https://github.com/expressjs/express/tree/master/examples/auth)。 - ## Express 支持哪些模板引擎? Express 支持符合 `(path, locals, callback)` 特征符的任何模板引擎。 为了使模板引擎接口和高速缓存实现标准化,请参阅 [consolidate.js](https://github.com/visionmedia/consolidate.js) 项目以获得支持。未列出的模板引擎可能也支持 Express 特征符。 +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](/{{page.lang}}/guide/using-template-engines.html). ## 如何处理 404 响应? -在 Express 中,404 响应不是错误的结果,所以错误处理程序中间件不会将其捕获。此行为是因为 404 响应只是表明缺少要执行的其他工作;换言之,Express 执行了所有中间件函数和路由,且发现它们都没有响应。您需要做的只是在堆栈的最底部(在其他所有函数之下)添加一个中间件函数来处理 404 响应: +在 Express 中,404 响应不是错误的结果,所以错误处理程序中间件不会将其捕获。此行为是因为 404 响应只是表明缺少要执行的其他工作;换言之,Express 执行了所有中间件函数和路由,且发现它们都没有响应。您需要做的只是在堆栈的最底部(在其他所有函数之下)添加一个中间件函数来处理 404 响应: This behavior is +because a 404 response simply indicates the absence of additional work to do; +in other words, Express has executed all middleware functions and routes, +and found that none of them responded. All you need to +do is add a middleware function at the very bottom of the stack (below all other functions) +to handle a 404 response: + +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## 如何设置错误处理程序? 错误处理中间件的定义方式与其他中间件基本相同,差别在于错误处理中间件有四个自变量而不是三个,专门具有特征符 `(err, req, res, next)`: -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` 有关更多信息,请参阅[错误处理](/{{ page.lang }}/guide/error-handling.html)。 ## 如何呈现纯 HTML? -您不必这么做!无需使用 `res.render()` 函数来“呈现”HTML。 +You don't! 您不必这么做!无需使用 `res.render()` 函数来“呈现”HTML。 如果您具有特定文件,请使用 `res.sendFile()` 函数。 如果您希望从目录提供许多资产,请使用 `express.static()` 中间件函数。 +If you have a specific file, use the `res.sendFile()` function. +If you are serving many assets from a directory, use the `express.static()` +middleware function. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/zh-cn/starter/generator.md b/zh-cn/starter/generator.md old mode 100755 new mode 100644 index d02d56217e..e7232935b7 --- a/zh-cn/starter/generator.md +++ b/zh-cn/starter/generator.md @@ -1,8 +1,9 @@ --- layout: page title: Express 应用程序生成器 +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: zh-cn +redirect_from: " " --- # Express 应用程序生成器 @@ -11,28 +12,23 @@ lang: zh-cn 您可以使用 `npx` 命令(在 Node.js 8.2.0 中可用)运行应用程序生成器。 -
    -
    +```bash
     $ npx express-generator
    -
    -
    +``` 对于早期的 Node 版本,可将应用程序生成器作为全局 npm 软件包安装,然后启动它。 -
    -
    +```bash
     $ npm install -g express-generator
     $ express
    -
    -
    +``` 使用 `-h` 选项显示命令选项: -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -43,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` -例如,以下语句在当前工作目录中创建名为 _myapp_ 的 Express 应用程序并将视图引擎将设置为 [Pug](https://pugjs.org/) : +For example, the following creates an Express app named _myapp_. 例如,以下语句在当前工作目录中创建名为 _myapp_ 的 Express 应用程序并将视图引擎将设置为 [Pug](https://pugjs.org/) : -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -73,48 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` 然后安装依赖项: -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` 在 MacOS 或 Linux 上,采用以下命令运行此应用程序: -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` 在 Windows 命令提示符上,使用以下命令: -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` 在 Windows PowerShell 上,使用以下命令: -
    -
    +```bash
     PS> $env:DEBUG='myapp:*'; npm start
    -
    -
    +``` 然后在浏览器中输入 `http://localhost:3000/` 以访问此应用程序。 生成的应用程序具有以下目录结构: -
    -
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -134,9 +118,12 @@ PS> $env:DEBUG='myapp:*'; npm start
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    + 生成器创建的应用程序结构只是构造 Express 应用程序的众多方法之一。请随意使用此结构或者对其进行修改以最大程度满足自己的需求。 + Feel free to use this structure or modify it to best suit your needs.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/zh-cn/starter/hello-world.md b/zh-cn/starter/hello-world.md old mode 100755 new mode 100644 index 2ecf833c78..e414620d38 --- a/zh-cn/starter/hello-world.md +++ b/zh-cn/starter/hello-world.md @@ -1,22 +1,18 @@ --- layout: page title: Express“Hello World”示例 +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: zh-cn +redirect_from: " " --- # Hello world 示例
    -这基本上是您可以创建的最简单的 Express 应用程序。这是单个文件应用程序 — 根本*不*需要动用 [Express 生成器](/{{ page.lang }}/starter/generator.html)。Express 生成器的作用就像是为完整的应用程序建立一个“脚手架”,包含各种用途的 JavaScript 文件、Jade 模板和子目录。 +Embedded below is essentially the simplest Express app you can create. It is a single file app — _not_ what you'd get if you use the [Express generator](/{{ page.lang }}/starter/generator.html), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes.
    -首先创建名为 `myapp` 的目录,切换到此目录,然后运行 `npm init`。根据[安装指南](/{{ page.lang }}/starter/installing.html)将 `express` 安装为依赖项。 - -在 `myapp` 目录中,创建名为 `app.js` 的文件,然后添加以下代码: - -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -26,12 +22,17 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    -
    +``` + +This app starts a server and listens on port 3000 for connections. 应用程序会启动服务器,并在端口 3000 上侦听连接。此应用程序以“Hello World!”响应针对根 URL (`/`) 或_路由_的请求。对于其他所有路径,它将以 **404 Not Found** 进行响应。 For every other path, it will respond with a **404 Not Found**. -应用程序会启动服务器,并在端口 3000 上侦听连接。此应用程序以“Hello World!”响应针对根 URL (`/`) 或*路由*的请求。对于其他所有路径,它将以 **404 Not Found** 进行响应。 +### Running Locally + +首先创建名为 `myapp` 的目录,切换到此目录,然后运行 `npm init`。根据[安装指南](/{{ page.lang }}/starter/installing.html)将 `express` 安装为依赖项。 Then, install `express` as a dependency, as per the [installation guide](/{{ page.lang }}/starter/installing.html). + +在 `myapp` 目录中,创建名为 `app.js` 的文件,然后添加以下代码:
    `req`(请求)和 `res`(响应)与 Node 提供的对象完全相同,所以您可以在不涉及 Express 的情况下调用 `req.pipe()`、`req.on('data', callback)` 和要执行的其他任何函数。 @@ -39,11 +40,10 @@ app.listen(port, () => { 使用以下命令运行应用程序: -
    -
    +```bash
     $ node app.js
    -
    -
    +``` 然后,在浏览器中输入 [http://localhost:3000/](http://localhost:3000/) 以查看输出。 +### 这基本上是您可以创建的最简单的 Express 应用程序。这是单个文件应用程序 — 根本_不_需要动用 [Express 生成器](/{{ page.lang }}/starter/generator.html)。Express 生成器的作用就像是为完整的应用程序建立一个“脚手架”,包含各种用途的 JavaScript 文件、Jade 模板和子目录。 diff --git a/zh-cn/starter/installing.md b/zh-cn/starter/installing.md old mode 100755 new mode 100644 index f4a067e118..64741f8fcd --- a/zh-cn/starter/installing.md +++ b/zh-cn/starter/installing.md @@ -1,58 +1,57 @@ --- layout: page title: 安装 Express +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: zh-cn +redirect_from: " " --- # 安装 假设您已经安装了 [Node.js](https://nodejs.org/),创建目录以保存应用程序,并将其设置为工作目录。 -
    -
    +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher.
    +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher.
    +
    +```bash
     $ mkdir myapp
     $ cd myapp
    -
    -
    +``` 使用 `npm init` 命令为应用程序创建 `package.json` 文件。 有关 `package.json` 工作方式的更多信息,请参阅 [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json)。 +For more information on how `package.json` works, see [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). -
    -
    +```bash
     $ npm init
    -
    -
    +``` -此命令提示您输入若干项,例如应用程序的名称和版本。 -现在,只需按回车键以接受其中大多数项的缺省值,但以下情况例外: +This command prompts you for a number of things, such as the name and version of your application. +For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception: -
    -
    +```
     entry point: (index.js)
    -
    -
    +``` -输入 `app.js`,或者您希望使用的任何主文件名称。如果希望文件名为 `index.js`,请按回车键以接受建议的缺省文件名。 +输入 `app.js`,或者您希望使用的任何主文件名称。如果希望文件名为 `index.js`,请按回车键以接受建议的缺省文件名。 If you want it to be `index.js`, hit RETURN to accept the suggested default file name. -在 `myapp` 目录中安装 Express,然后将其保存在依赖项列表中。例如: +在 `myapp` 目录中安装 Express,然后将其保存在依赖项列表中。例如: For example: -
    -
    -$ npm install express --save
    -
    -
    +```bash +$ npm install express +``` 要暂时安装 Express 而不将其添加到依赖项列表中: -
    -
    +```bash
     $ npm install express --no-save
    -
    -
    +```
    + 默认情况下,版本为 npm 5.0+ 的 npm install 将模块添加到 `package.json` 文件中的 `dependencies` 列表;对于较早版本的 npm,必须显式指定 `--save` 选项。 今后运行 `app` 目录中的 `npm install` 将自动安装依赖项列表中的模块。 + Then, afterwards, running `npm install` in the app directory will automatically install modules in the dependencies list.
    + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/zh-cn/starter/static-files.md b/zh-cn/starter/static-files.md old mode 100755 new mode 100644 index a332310ac9..4f3c9f9fa8 --- a/zh-cn/starter/static-files.md +++ b/zh-cn/starter/static-files.md @@ -1,33 +1,39 @@ --- layout: page title: 在 Express 中提供静态文件 +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: zh-cn +redirect_from: " " --- # 在 Express 中提供静态文件 为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 `express.static` 内置中间件函数。 -将包含静态资源的目录的名称传递给 `express.static` 中间件函数,以便开始直接提供这些文件。例如,使用以下代码在名为 `public` 的目录中提供图像、CSS 文件和 JavaScript 文件: +The function signature is: -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +For example, use the following code to serve images, CSS files, and JavaScript files in a directory named `public`: + +```js +app.use(express.static('public')) +``` 现在,可以访问位于 `public` 目录中的文件: -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +```
    Express 相对于静态目录查找文件,因此静态目录的名称不是此 URL 的一部分。 @@ -35,39 +41,41 @@ Express 相对于静态目录查找文件,因此静态目录的名称不是此 要使用多个静态资源目录,请多次调用 `express.static` 中间件函数: -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` Express 以您使用 `express.static` 中间件函数设置静态目录的顺序来查找文件。 -要为 `express.static` 函数提供的文件创建虚拟路径前缀(路径并不实际存在于文件系统中),请为静态目录[指定安装路径](/{{ page.lang }}/4x/api.html#app.use),如下所示: +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` 现在,可以访问具有 `/static` 路径前缀的 `public` 目录中的文件。 -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` + +然而,向 `express.static` 函数提供的路径相对于您在其中启动 `node` 进程的目录。如果从另一个目录运行 Express 应用程序,那么对于提供资源的目录使用绝对路径会更安全: If you run the express app from another directory, it's safer to use the absolute path of the directory that you want to serve: + +```js +const path = require('path') +app.use('/static', express.static(path.join(__dirname, 'public'))) +``` -然而,向 `express.static` 函数提供的路径相对于您在其中启动 `node` 进程的目录。如果从另一个目录运行 Express 应用程序,那么对于提供资源的目录使用绝对路径会更安全: +For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static.html). -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/zh-cn/support/index.md b/zh-cn/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/zh-cn/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page) diff --git a/zh-tw/3x/api.md b/zh-tw/3x/api.md old mode 100755 new mode 100644 index 80faa60f2b..f0334bab23 --- a/zh-tw/3x/api.md +++ b/zh-tw/3x/api.md @@ -1,32 +1,26 @@ --- -layout: 3x-api +layout: api +version: 3x title: Express 3.x - API 參照 +description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api -lang: zh-tw +redirect_from: " " --- +
    **Express 3.x 已不再維護** - 從前次更新(2015 年 8 月 1 日)起,不再處理 3.x 中的已知和不明的安全與效能問題。強烈建議您使用 Express 最新版本。 -
    - -

    3.x API

    +Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. - - {% include api/en/3x/express.md %} +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). - - {% include api/en/3x/app.md %} - - - {% include api/en/3x/req.md %} +
    - - {% include api/en/3x/res.md %} +

    3.x API

    - - {% include api/en/3x/middleware.md %} + +{% include api/en/3x/app.md %}
    diff --git a/zh-tw/4x/api.md b/zh-tw/4x/api.md old mode 100755 new mode 100644 index 8daa694cb0..f9b702a977 --- a/zh-tw/4x/api.md +++ b/zh-tw/4x/api.md @@ -1,26 +1,25 @@ --- -layout: 4x-api +layout: api +version: 4x title: Express 4.x - API 參照 +description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api -lang: zh-tw +redirect_from: " " --- +

    4.x API

    - - {% include api/en/4x/express.md %} +{% capture node-version %} - - {% include api/en/4x/app.md %} +Express 4.0 requires Node.js 0.10 or higher. - - {% include api/en/4x/req.md %} +{% endcapture %} - - {% include api/en/4x/res.md %} +{% include admonitions/note.html content=node-version %} - - {% include api/en/4x/router.md %} + +{% include api/en/4x/app.md %}
    diff --git a/zh-tw/5x/api.md b/zh-tw/5x/api.md new file mode 100644 index 0000000000..e4fc0d72a3 --- /dev/null +++ b/zh-tw/5x/api.md @@ -0,0 +1,28 @@ +--- +layout: api +version: 5x +title: Express 5.x - API 參照 +description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. +menu: api +redirect_from: " " +--- + +
    + +

    5.x API

    + +{% capture node-version %} + +Express 5.0 requires Node.js 18 or higher. + +{% endcapture %} + +{% include admonitions/note.html content=node-version %} + +{% include api/en/5x/express.md %} +{% include api/en/5x/app.md %} +{% include api/en/5x/req.md %} +{% include api/en/5x/res.md %} +{% include api/en/5x/router.md %} + +
    diff --git a/zh-tw/advanced/best-practice-performance.md b/zh-tw/advanced/best-practice-performance.md old mode 100755 new mode 100644 index 658a64615a..20e2b94726 --- a/zh-tw/advanced/best-practice-performance.md +++ b/zh-tw/advanced/best-practice-performance.md @@ -1,118 +1,102 @@ --- layout: page title: 在正式作業中使用 Express 的效能最佳作法 +description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced -lang: zh-tw +redirect_from: " " --- # 正式作業最佳作法:效能和可靠性 -## 概觀 - 本文討論部署至正式作業之 Express 應用程式的效能與可靠性最佳作法。 -顯然地,這個主題屬於 "devops" 領域,涵蓋了傳統開發和作業兩者。因此,資訊分為兩大部分: - -* [在程式碼中的作法](#code)(開發部分)。 -* [在環境 / 設定中的作法](#env)(作業部分)。 +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 (the dev part): + - 採用 gzip 壓縮 + - [Don't use synchronous functions](#dont-use-synchronous-functions) + - [Do logging correctly](#do-logging-correctly) + - [Handle exceptions properly](#handle-exceptions-properly) +- Things to do in your environment / setup (the ops part): + - 將 NODE_ENV 設為 "production" + - 確定您的應用程式自動重新啟動 + - [Run your app in a cluster](#run-your-app-in-a-cluster) + - [Cache request results](#cache-request-results) + - 負載平衡器通常是一個反向 Proxy,負責協調與多個應用程式實例和伺服器之間的資料流量。利用 [Nginx](http://nginx.org/en/docs/http/load_balancing.html) 或 [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts),就能輕鬆設定您應用程式的負載平衡器。 + - 反向 Proxy 位於 Web 應用程式前面,除了將要求引導至應用程式,也會對要求執行支援的作業。除此之外,它還可以處理錯誤頁面、壓縮、快取、提供的檔案,以及負載平衡。 -## 在程式碼中的作法 +## Things to do in your code {#in-code} 以下是您可以在程式碼中執行的一些作法,藉以改良您應用程式的效能: -* 採用 gzip 壓縮 -* 不使用同步函數 -* 使用中介軟體來提供靜態檔案 -* 正確執行記載 -* 適當處理異常狀況 +- 採用 gzip 壓縮 +- [Don't use synchronous functions](#dont-use-synchronous-functions) +- [Do logging correctly](#do-logging-correctly) +- [Handle exceptions properly](#handle-exceptions-properly) ### 採用 gzip 壓縮 -Gzip 壓縮可以大幅減少回應內文的大小,從而提高 Web 應用程式的速度。請使用 [compression](https://www.npmjs.com/package/compression) 中介軟體,在您的 Express 應用程式中進行 gzip 壓縮。例如: +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: ```js -var compression = require('compression') -var express = require('express') -var app = express() +const compression = require('compression') +const express = require('express') +const app = express() + app.use(compression()) ``` -在正式作業中,如果網站的資料流量極高,落實執行壓縮最好的作法是在反向 Proxy 層次實作它(請參閱[使用反向 Proxy](#proxy))。在該情況下,就不需使用壓縮中介軟體。如需在 Nginx 中啟用 gzip 壓縮的詳細資料,請參閱 Nginx 說明文件中的 [ngx_http_gzip_module 模組](http://nginx.org/en/docs/http/ngx_http_gzip_module.html)。 +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. 在正式作業中,如果網站的資料流量極高,落實執行壓縮最好的作法是在反向 Proxy 層次實作它(請參閱[使用反向 Proxy](#proxy))。在該情況下,就不需使用壓縮中介軟體。如需在 Nginx 中啟用 gzip 壓縮的詳細資料,請參閱 Nginx 說明文件中的 [ngx_http_gzip_module 模組](http://nginx.org/en/docs/http/ngx_http_gzip_module.html)。 ### 不使用同步函數 -同步函數和方法直到傳回前,會阻礙執行程序的進行。單次呼叫同步函數,可能在數微秒或毫秒傳回,不過,在高資料流量的網站中,這些呼叫往往會累加,並降低應用程式效能。請避免在正式作業中使用它們。 - -雖然 Node 和許多模組會提供其函數的同步與非同步版本,在正式作業中,請一律使用非同步版本。唯一有理由使用同步函數的時機是在最初啟動之時。 - -如果您使用 Node.js 4.0+ 或 io.js 2.1.0+,每當您的應用程式使用同步 API 時,您可以使用 `--trace-sync-io` 指令行旗標,來列印警告和堆疊追蹤。當然,在正式作業中您其實不會想使用此旗標,但這可確保您的程式碼可準備用於正式作業中。如需相關資訊,請參閱 [io.js 2.1.0 每週更新](https://nodejs.org/en/blog/weekly-updates/weekly-update.2015-05-22/#2-1-0)。 +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. -### 使用中介軟體來提供靜態檔案 +雖然 Node 和許多模組會提供其函數的同步與非同步版本,在正式作業中,請一律使用非同步版本。唯一有理由使用同步函數的時機是在最初啟動之時。 The only time when a synchronous function can be justified is upon initial startup. -在開發中,您可以使用 [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) 來提供靜態檔案。但是在正式作業中卻不能這樣做,因為此函數得讀取檔案系統,才能取得每一個檔案要求,如此會遇到明顯的延遲,並影響應用程式的整體效能。請注意,`res.sendFile()` *並非*透過更具效率的 [sendfile](http://linux.die.net/man/2/sendfile) 系統呼叫來實作。 +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#cli_trace_sync_io) for more information. -請改用 [serve-static](https://www.npmjs.com/package/serve-static) 中介軟體(或同等項目),此中介軟體能有效提供 Express 應用程式的檔案。 +### Do logging correctly -甚至更好的作法是使用反向 Proxy 來提供靜態檔案;如需相關資訊,請參閱[使用反向 Proxy](#proxy)。 +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 -一般而言,從您的應用程式進行記載的原因有二:為了除錯,以及為了記載應用程式活動(其實就是除錯之外的每一項)。使用 `console.log()` 或 `console.err()` 將日誌訊息列印至終端機,在開發中是常見作法。但是當目的地是終端機或檔案時,[這些函數是同步的](https://nodejs.org/api/console.html#console_console_1),除非您將輸出引導至另一個程式,這些函數並不適用於正式作業。 - -#### 為了除錯 - -如果您為了除錯而記載,則不要使用 `console.log()`,請改用 [debug](https://www.npmjs.com/package/debug) 之類的特殊除錯模組。這個模組可讓您使用 DEBUG 環境變數,來控制哪些除錯訊息(若有的話)要送往 `console.err()`。為了讓應用程式完全維持非同步,您仍得將 `console.err()` 引導至另一個程式。但之後在正式作業中,實際上您並不會進行除錯,不是嗎? +如果您為了除錯而記載,則不要使用 `console.log()`,請改用 [debug](https://www.npmjs.com/package/debug) 之類的特殊除錯模組。這個模組可讓您使用 DEBUG 環境變數,來控制哪些除錯訊息(若有的話)要送往 `console.err()`。為了讓應用程式完全維持非同步,您仍得將 `console.err()` 引導至另一個程式。但之後在正式作業中,實際上您並不會進行除錯,不是嗎? 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? #### 為了應用程式活動 -如果您要記載應用程式活動(例如,追蹤資料流量或 API 呼叫),則不要使用 `console.log()`,請改用 [Winston](https://www.npmjs.com/package/winston) 或 -[Bunyan](https://www.npmjs.com/package/bunyan) 之類的記載程式庫。如需這兩種程式庫的詳細比較,請參閱 StrongLoop 部落格文章 [Comparing Winston and Bunyan Node.js Logging](https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/)。 +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 應用程式一旦遇到未捕捉到的異常狀況,就會當機。如果不處理異常狀況,並採取適當的動作,您的 Express 應用程式會當機並且離線。如果您遵循下方[確定您的應用程式自動重新啟動](#restart)中的建議,應用程式就能從當機回復。幸好 Express 應用程式的啟動時間通常很短。然而,您會希望一開始就避免當機,如果要這樣做,您需要適當處理異常狀況。 +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. 為了確保您能處理所有的異常狀況,請使用下列技術: -* [使用 try-catch](#try-catch) -* [使用 promise](#promises) +- [使用 try-catch](#try-catch) +- [使用 promise](#promises) -在分別討論這兩個主題之前,您對 Node/Express 錯誤處理方式應有基本的瞭解:使用「錯誤優先回呼」,並將錯誤傳播至中介軟體。Node 從非同步函數傳回錯誤時,會採用「錯誤優先回呼」慣例,其中,回呼函數的第一個參數是錯誤物件,接著是後續參數中的結果資料。如果要指出無錯誤,會傳遞 null 作為第一個參數。回呼函數必須同樣遵循「錯誤優先回呼」慣例,才能實際處理錯誤。在 Express 中,最佳作法是使用 next() 函數,透過中介軟體鏈來傳播錯誤。 +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. 如需進一步瞭解錯誤處理的基本概念,請參閱: -* [Error Handling in Node.js](https://www.joyent.com/developers/node/design/errors) -* [Building Robust Node Applications: Error Handling](https://strongloop.com/strongblog/robust-node-applications-error-handling/) (StrongLoop blog) - -#### 禁止事項 - -有一件事*不能*做,就是接聽 `uncaughtException` 事件,此事件是在回歸事件迴圈期間不斷引發異常狀況時產生的。新增 `uncaughtException` 的事件接聽器,會使遇到異常狀況的程序變更其預設行為;儘管發生異常狀況,該程序會繼續執行。阻止應用程式當機,似乎是個好辦法,但是在未捕捉到異常狀況之後,又繼續執行應用程式,卻是危險作法而不建議這麼做,因為程序的狀態會變得不可靠且無法預測。 - -此外,使用 `uncaughtException` 被公認為[拙劣作法](https://nodejs.org/api/process.html#process_event_uncaughtexception),這裡有一份[提案](https://github.com/nodejs/node-v0.x-archive/issues/2582),指出如何將它從核心移除。因此,接聽 `uncaughtException` 並不可取。這是我們建議採取多重程序和監督程式等事項的原因:當機再重新啟動,通常是從錯誤回復最可靠的作法。 - -我們也不建議使用 [domains](https://nodejs.org/api/domain.html)。它通常不能解決問題,並且是個已淘汰的模組。 - - +- [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### 使用 try-catch -try-catch 是一種 JavaScript 語言建構,可用來捕捉同步程式碼中的異常狀況。例如,如以下所示,利用 try-catch 來處理 JSON 剖析錯誤。 - -使用 [JSHint](http://jshint.com/) 或 [JSLint](http://www.jslint.com/) 之類的工具,有助您尋找隱含的異常狀況,例如[參照未定義變數中的錯誤](http://www.jshint.com/docs/options/#undef)。 +try-catch 是一種 JavaScript 語言建構,可用來捕捉同步程式碼中的異常狀況。例如,如以下所示,利用 try-catch 來處理 JSON 剖析錯誤。 Use try-catch, for example, to handle JSON parsing errors as shown below. -下列範例顯示如何使用 try-catch 來處理潛在的程序當機異常狀況。此中介軟體函數接受名稱是 "params" 的查詢欄位參數,它是一個 JSON 物件。 +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(() => { - var jsonStr = req.query.params + const jsonStr = req.query.params try { - var jsonObj = JSON.parse(jsonStr) + const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') @@ -121,171 +105,124 @@ app.get('/search', (req, res) => { }) ``` -不過,try-catch 只適用於同步程式碼。由於 Node 平台主要是非同步(尤其是在正式作業環境),try-catch 不會捕捉大量的異常狀況。 - - +However, try-catch works only for synchronous code. 不過,try-catch 只適用於同步程式碼。由於 Node 平台主要是非同步(尤其是在正式作業環境),try-catch 不會捕捉大量的異常狀況。 #### 使用 promise -只要非同步程式碼區塊使用 `then()`,promise 就會處理其中的任何異常狀況(包括明確和隱含)。只需在 promise 鏈尾端新增 `.catch(next)` 即可。例如: +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('/', (req, res, next) => { - // do some sync stuff - queryDb() - .then((data) => makeCsv(data)) // handle data - .then((csv) => { /* handle csv */ }) - .catch(next) +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) => { - // handle error + res.status(err.status ?? 500).send({ error: err.message }) }) ``` -現在,所有非同步與同步錯誤都會傳播到錯誤中介軟體。 - -不過,請注意下列兩項警告: - -1. 您所有的非同步程式碼都必須傳回 promise(不包括發射程式)。如果特定程式庫沒有傳回 promise,請使用 [Bluebird.promisifyAll()](http://bluebirdjs.com/docs/api/promise.promisifyall.html) 等之類的 helper 函數來轉換基本物件。 -2. 事件發射程式(例如:串流)仍可能造成未捕捉到的異常狀況。因此,請確定錯誤事件的處理適當;例如: +Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js -const wrap = fn => (...args) => fn(...args).catch(args[2]) +app.use(async (req, res, next) => { + req.locals.user = await getUser(req) -app.get('/', wrap(async (req, res, next) => { - const company = await getCompanyById(req.query.id) - const stream = getLogoStreamById(company.id) - stream.on('error', next).pipe(res) -})) + next() // This will be called if the promise does not throw an error. +}) ``` -如需使用 promise 來處理錯誤的相關資訊,請參閱: +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. -* [Asynchronous Error Handling in Express with Promises, Generators and ES7](https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/) -* [Promises in Node.js with Q – An Alternative to Callbacks](https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/) +此外,使用 `uncaughtException` 被公認為[拙劣作法](https://nodejs.org/api/process.html#process_event_uncaughtexception),這裡有一份[提案](https://github.com/nodejs/node-v0.x-archive/issues/2582),指出如何將它從核心移除。因此,接聽 `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. - +我們也不建議使用 [domains](https://nodejs.org/api/domain.html)。它通常不能解決問題,並且是個已淘汰的模組。 It generally doesn't solve the problem and is a deprecated module. ## 在環境 / 設定中的作法 以下是您可以在系統環境中執行的一些作法,藉以改良您應用程式的效能: -* 將 NODE_ENV 設為 "production" -* 確定您的應用程式自動重新啟動 -* 在叢集中執行應用程式 -* 快取要求結果 -* 使用負載平衡器 -* 使用反向 Proxy +- 將 NODE_ENV 設為 "production" +- 確定您的應用程式自動重新啟動 +- [Run your app in a cluster](#run-your-app-in-a-cluster) +- [Cache request results](#cache-request-results) +- 負載平衡器通常是一個反向 Proxy,負責協調與多個應用程式實例和伺服器之間的資料流量。利用 [Nginx](http://nginx.org/en/docs/http/load_balancing.html) 或 [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts),就能輕鬆設定您應用程式的負載平衡器。 +- 反向 Proxy 位於 Web 應用程式前面,除了將要求引導至應用程式,也會對要求執行支援的作業。除此之外,它還可以處理錯誤頁面、壓縮、快取、提供的檔案,以及負載平衡。 ### 將 NODE_ENV 設為 "production" -NODE_ENV 環境變數用來指定應用程式的執行環境(通常是開發或正式作業)。若要改良效能,其中一個最簡單的作法是將 NODE_ENV 設為 "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`. 將 NODE_ENV 設為 "production",可讓 Express: -* 快取視圖範本。 -* 快取從 CSS 延伸項目產生的 CSS 檔案。 -* 產生簡略的錯誤訊息。 - -[測試指出](http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/)單單這樣做,就能提高 3 倍的應用程式效能! - -如果您需要撰寫環境特定的程式碼,您可以使用 `process.env.NODE_ENV` 來檢查 NODE_ENV 的值。請注意,檢查任何環境變數的值都會影響效能,因此請慎行。 +- Cache view templates. +- 快取從 CSS 延伸項目產生的 CSS 檔案。 +- Generate less verbose error messages. -在開發中,您通常是在互動式 Shell 中設定環境變數,例如,使用 `export` 或您的 `.bash_profile` 檔。但是在正式作業伺服器中,通常您應該不會這樣做;反而是使用您作業系統的 init 系統(systemd 或 Upstart)。下一節詳述一般性的 init 系統用法,但由於設定 NODE_ENV 對於效能來說很重要(而且輕而易舉),這裡仍特別強調。 +[Tests indicate](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! -採用 Upstart 時,請在您的工作檔中使用 `env` 關鍵字。例如: +如果您需要撰寫環境特定的程式碼,您可以使用 `process.env.NODE_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. -
    -
    -# /etc/init/env.conf
    - env NODE_ENV=production
    -
    -
    +採用 systemd 時,請在單位檔案中使用 `Environment` 指引。例如: For example: -如需相關資訊,請參閱 [Upstart Intro, Cookbook and Best Practices](http://upstart.ubuntu.com/cookbook/#environment-variables)。 - -採用 systemd 時,請在單位檔案中使用 `Environment` 指引。例如: - - -
    -
    +```sh
     # /etc/systemd/system/myservice.service
     Environment=NODE_ENV=production
    -
    -
    - -如需相關資訊,請參閱 [Using Environment Variables In systemd Units](https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html)。 - -如果您使用 StrongLoop Process Manager,您也可以[在將 StrongLoop PM 安裝成服務時,設定環境變數](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-Setenvironmentvariables)。 +``` - +For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### 確定您的應用程式自動重新啟動 -在正式作業中,您始終不希望您的應用程式離線。也就是說,不論是應用程式當機,或是伺服器本身當機,您都需要確保它會重新啟動。儘管最好這些事件都不要發生,您仍必須務實看待這兩種可能的情況,其作法如下: +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: -* 當應用程式(和 Node)當機時,使用程序管理程式重新啟動它。 -* 當作業系統當機時,使用您作業系統提供的 init 系統,來重新啟動程序管理程式。也有可能可以使用 init 系統,而不使用程序管理程式。 +- 當應用程式(和 Node)當機時,使用程序管理程式重新啟動它。 +- 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 應用程式一旦遇到未捕捉到的異常狀況,就會當機。首要之務是確定您的應用程式已妥善測試,且已處理所有的異常狀況(請參閱[適當處理異常狀況](#exceptions),以取得詳細資料)。但是萬全的作法是落實執行機制,以確保萬一您的應用程式當機,它會自動重新啟動。 +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. #### 使用程序管理程式 -在開發中,只需從指令行使用 `node server.js` 或類似指令,就會啟動應用程式。但在正式作業中這樣做,卻會成為禍因。如果應用程式當機,就會離線直到您重新啟動它為止。為了確保應用程式會在當機時重新啟動,請使用程序管理程式。程序管理程式是一個應用程式的「儲存器」,有助於部署、提供高可用性,並可讓您在執行時期管理應用程式。 +在開發中,只需從指令行使用 `node server.js` 或類似指令,就會啟動應用程式。但在正式作業中這樣做,卻會成為禍因。如果應用程式當機,就會離線直到您重新啟動它為止。為了確保應用程式會在當機時重新啟動,請使用程序管理程式。程序管理程式是一個應用程式的「儲存器」,有助於部署、提供高可用性,並可讓您在執行時期管理應用程式。 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. 除了在應用程式當機時重新啟動它,程序管理程式還可讓您: -* 洞察執行時期效能和資源的耗用情況。 -* 動態修改設定,以改良效能。 -* 控制叢集作業(StrongLoop PM 和 pm2)。 - -最普及的 Node 程序管理程式如下: - -* [StrongLoop Process Manager](http://strong-pm.io/) -* [PM2](https://github.com/Unitech/pm2) -* [Forever](https://www.npmjs.com/package/forever) - -有關這三種程序管理程式的特性比較,請參閱 [http://strong-pm.io/compare/](http://strong-pm.io/compare/)。如需這三種的詳細介紹,請參閱 [Express 應用程式的程序管理程式](/{{ page.lang }}/advanced/pm.html)。 +- 洞察執行時期效能和資源的耗用情況。 +- 動態修改設定,以改良效能。 +- Control clustering (pm2). -即使您的應用程式不時發生當機,這些程序管理程式不論哪一個都足以讓您的應用程式維持作用中。 - -不過,StrongLoop PM 有許多特性明確以正式作業部署為目標。您可以使用它和相關的 StrongLoop 工具來: - -* 在本端建置和包裝您的應用程式,然後安全地部署到正式作業系統。 -* 在應用程式當機時(不論任何原因),自動重新啟動。 -* 遠端管理叢集。 -* 檢視 CPU 設定檔和資料堆 Snapshot,使效能達到最佳,並診斷記憶體洩漏情況。 -* 檢視您應用程式的效能度量。 -* 藉由 Nginx 負載平衡器的整合控制,輕鬆調整至多部主機。 - -如同以下說明,當您使用 init 系統將 StrongLoop PM 安裝成作業系統服務時,它會自動隨系統一起重新啟動。因此,它會讓您的應用程式程序和叢集永遠維持作用中。 +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. #### 使用 init 系統 -接下來的可靠性層級是確保您的應用程式會隨伺服器一起重新啟動。系統仍可能因各種不同的原因而關閉。為了確保您的應用程式會在伺服器當機時重新啟動,請使用您作業系統內建的 init 系統。現今兩個通行的主要 init 系統是 [systemd](https://wiki.debian.org/systemd) 和 [Upstart](http://upstart.ubuntu.com/)。 +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). init 系統若要與 Express 應用程式搭配使用,其作法有二: -* 在程序管理程式中執行應用程式,並利用 init 系統將程序管理程式安裝成服務。當應用程式當機時,程序管理程式會重新啟動應用程式,且 init 系統會在作業系統重新啟動時,重新啟動程序管理程式。這是建議的作法。 -* 直接使用 init 系統來執行應用程式(和 Node)。這樣做比較簡單,但卻少了使用程序管理程式時的其他好處。 +- 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 是一個 Linux 系統和服務管理程式。大部分主要的 Linux 發行套件已採用 systemd 作為其預設 init 系統。 +Systemd 是一個 Linux 系統和服務管理程式。大部分主要的 Linux 發行套件已採用 systemd 作為其預設 init 系統。 Most major Linux distributions have adopted systemd as their default init system. -systemd 服務配置檔稱為*單位檔案*,其副名結尾是 .service。以下是範例單位檔案,用來直接管理 Node 應用程式(請以您的系統和應用程式值取代粗體字): +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=Awesome Express App
    +Description=
     
     [Service]
     Type=simple
    -ExecStart=/usr/local/bin/node /projects/myapp/index.js
    -WorkingDirectory=/projects/myapp
    +ExecStart=/usr/local/bin/node 
    +WorkingDirectory=
     
     User=nobody
     Group=nogroup
    @@ -306,158 +243,68 @@ Restart=always
     
     [Install]
     WantedBy=multi-user.target
    -
    -
    -如需 systemd 的相關資訊,請參閱 [systemd 參照(線上指令說明)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html)。 - -##### 將 StrongLoop PM 當成 systemd 服務 - -將 StrongLoop Process Manager 安裝成 systemd 服務很簡單。完成之後,當伺服器重新啟動時,就會自動重新啟動 StrongLoop PM,之後它就會重新啟動其所管理的所有應用程式。 - -將 StrongLoop PM 安裝成 systemd 服務: - -
    -
    -$ sudo sl-pm-install --systemd
    -
    -
    - -然後使用下列指令來啟動服務: - -
    -
    -$ sudo /usr/bin/systemctl start strong-pm
    -
    -
    - -如需相關資訊,請參閱 [Setting up a production host(StrongLoop 說明文件)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHEL7+,Ubuntu15.04or15.10)。 - -##### Upstart - -Upstart 是一個可在許多 Linux 發行套件中使用的系統工具,它會在系統啟動期間啟動作業和服務、在關機期間停止它們,並且監督它們。您可以將 Express 應用程式或程序管理程式配置成服務,之後 Express 應用程式或程序管理程式一旦發生當機,Upstart 就會自動重新啟動它。 - -Upstart 服務定義在工作配置檔(亦稱為 "job")中,其副名結尾是 `.conf`。下列範例顯示如何為名稱是 "myapp" 的應用程式,建立一項名稱是 "myapp" 的工作,且其主要檔案位於 `/projects/myapp/index.js`。 - -在 `/etc/init/` 建立名稱是 `myapp.conf` 的檔案,且其內容如下(請以您系統和應用程式的值取代粗體字): - -
    -
    -# When to start the process
    -start on runlevel [2345]
    -
    -# When to stop the process
    -stop on runlevel [016]
    -
    -# Increase file descriptor limit to be able to handle more requests
    -limit nofile 50000 50000
    -
    -# Use production mode
    -env NODE_ENV=production
    -
    -# Run as www-data
    -setuid www-data
    -setgid www-data
    -
    -# Run from inside the app dir
    -chdir /projects/myapp
    -
    -# The process to start
    -exec /usr/local/bin/node /projects/myapp/index.js
    -
    -# Restart the process if it is down
    -respawn
    -
    -# Limit restart attempt to 10 times within 10 seconds
    -respawn limit 10 10
    -
    -
    - -附註:這個 Script 需要 Upstart 1.4 或更新版本,且 Ubuntu 12.04-14.10 支援該 Upstart 版本。 - -由於工作是配置成在系統啟動時執行,您的應用程式會隨作業系統一起啟動,並在應用程式當機或系統關閉時自動重新啟動。 - -除了自動重新啟動應用程式,Upstart 可讓您使用下列指令: - -* `start myapp` – 啟動應用程式 -* `restart myapp` – 重新啟動應用程式 -* `stop myapp` – 停止應用程式。 - -如需 Upstart 的相關資訊,請參閱 [Upstart Intro, Cookbook and Best Practises](http://upstart.ubuntu.com/cookbook)。 - -##### 將 StrongLoop PM 當成 Upstart 服務 - -將 StrongLoop Process Manager 安裝成 Upstart 服務很簡單。完成之後,當伺服器重新啟動時,就會自動重新啟動 StrongLoop PM,之後它就會重新啟動其所管理的所有應用程式。 - -將 StrongLoop PM 安裝成 Upstart 1.4 服務: +``` -
    -
    -$ sudo sl-pm-install
    -
    -
    +如需 systemd 的相關資訊,請參閱 [systemd 參照(線上指令說明)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html)。 -然後使用下列指令來執行服務: +### Run your app in a cluster -
    -
    -$ sudo /sbin/initctl start strong-pm
    -
    -
    +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. -附註:在不支援 Upstart 1.4 的系統上,指令略有不同。如需相關資訊,請參閱 [Setting up a production host(StrongLoop 說明文件)](https://docs.strongloop.com/display/SLC/Setting+up+a+production+host#Settingupaproductionhost-RHELLinux5and6,Ubuntu10.04-.10,11.04-.10)。 +![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](http://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. -在多核心系統中,您可以啟動程序叢集,多次提高 Node 應用程式的效能。叢集會執行該應用程式的多個實例,理論上,每一個 CPU 核心上各有一個實例,因此負載和作業會分散在這些實例之間。 +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(). - +#### 使用 Node 的叢集模組 -重要事項:由於應用程式實例是以個別程序形式執行,因此不會共用相同的記憶體空間。也就是說,物件位於每一個應用程式實例本端。因此,您無法在應用程式碼中維護狀態。不過,您可以利用 [Redis](http://redis.io/) 等之類的記憶體內資料儲存庫,來儲存階段作業的相關資料和狀態。不論叢集是由多個程序或多部實體伺服器組成,這項警告其實適用於所有的水平調整形式。 +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. -在叢集化的應用程式中,工作者程序可個別當機,而不會影響其餘的程序。除了效能優點,執行應用程式程序叢集的另一個原因是,可將失效隔離。只要有工作者程序當機,一律要確定會記載事件,並利用 cluster.fork() 來衍生新程序。 +#### Using PM2 -#### 使用 Node 的叢集模組 +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). -利用 Node 的[叢集模組](https://nodejs.org/docs/latest/api/cluster.html),即可達成叢集作業。這可讓主要程序衍生工作者程序,並將送入的連線分散在這些工作者之間。不過,與其直接使用這個模組,更好的作法是使用其中提供的一個工具,自動為您執行叢集作業; -例如 [node-pm](https://www.npmjs.com/package/node-pm) 或 [cluster-service](https://www.npmjs.com/package/cluster-service)。 +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. -#### 使用 StrongLoop PM +To enable cluster mode, start your application like so: -如果您將應用程式部署至 StrongLoop Process Manager (PM),您可以善用叢集作業,且*不需*修改應用程式碼。 +```bash +# Start 4 worker processes +$ pm2 start npm --name my-app -i 4 -- start +# Auto-detect number of available CPUs and start that many worker processes +$ pm2 start npm --name my-app -i max -- start +``` -當 StrongLoop Process Manager (PM) 執行應用程式時,它會自動在叢集中執行它,且該叢集中的工作者數目等於系統上的 CPU 核心數。您可以使用 slc 指令行工具,直接手動變更工作者程序數目,而不需停止應用程式。 +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. -舉例來說,假設您將應用程式部署至 prod.foo.com,且 StrongLoop PM 是在埠 8701(預設值)接聽,請使用 slc 將叢集大小設為 8: +Once running, the application can be scaled like so: -
    -
    -$ slc ctl -C http://prod.foo.com:8701 set-size my-app 8
    -
    -
    +```bash +# Add 3 more workers +$ pm2 scale my-app +3 +# Scale to a specific number of workers +$ pm2 scale my-app 2 +``` -如需利用 StrongLoop PM 執行叢集作業的相關資訊,請參閱 StrongLoop 說明文件中的[叢集作業](https://docs.strongloop.com/display/SLC/Clustering)。 +For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. ### 快取要求結果 在正式作業中改良效能的另一項策略是快取要求的結果,這樣您的應用程式就不會重複執行作業而反覆處理相同的要求。 -使用 [Varnish](https://www.varnish-cache.org/) 或 [Nginx](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/)(另請參閱 [Nginx 快取](https://serversforhackers.com/nginx-caching/))等之類的快取伺服器,可大幅改良您應用程式的速度與效能。 +Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### 使用負載平衡器 -不論如何將應用程式最佳化,單一實例所能處理的負載量與資料流量有限。調整應用程式的其中一個作法是執行其多個實例,並透過負載平衡器來分散資料流量。設定負載平衡器可改良您應用程式的效能和速度,且透過其單一實例,使該應用程式得以多次調整。 - -負載平衡器通常是一個反向 Proxy,負責協調與多個應用程式實例和伺服器之間的資料流量。利用 [Nginx](http://nginx.org/en/docs/http/load_balancing.html) 或 [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts),就能輕鬆設定您應用程式的負載平衡器。 - -如果進行負載平衡,您可能得確定與特定階段作業 ID 相關聯的要求,會連接至發出該要求的程序。這就是所謂的*階段作業親緣性*或*組合階段作業*,如果要解決此情況,可按照上述建議,使用 Redis 等之類的資料儲存庫來儲存階段作業資料(視您的應用程式而定)。相關討論請參閱[使用多個節點](http://socket.io/docs/using-multiple-nodes/)。 +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. -#### StrongLoop PM 與 Nginx 負載平衡器搭配使用 +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). -[StrongLoop Process Manager](http://strong-pm.io/) 整合了 Nginx Controller,因此配置多主機正式作業環境配置更簡單。如需相關資訊,請參閱 [Scaling to multiple servers](https://docs.strongloop.com/display/SLC/Scaling+to+multiple+servers)(StrongLoop 說明文件)。 - +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/). ### 使用反向 Proxy -反向 Proxy 位於 Web 應用程式前面,除了將要求引導至應用程式,也會對要求執行支援的作業。除此之外,它還可以處理錯誤頁面、壓縮、快取、提供的檔案,以及負載平衡。 +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. -將不需要瞭解應用程式狀態的作業移交給反向 Proxy,使 Express 更有餘裕執行特殊的應用程式作業。基於此因,在正式作業中,建議讓 Express 在 [Nginx](https://www.nginx.com/) 或 [HAProxy](http://www.haproxy.org/) 等之類的反向 Proxy 背後執行。 +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://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. diff --git a/zh-tw/advanced/best-practice-security.md b/zh-tw/advanced/best-practice-security.md old mode 100755 new mode 100644 index 2585774e10..a68919409c --- a/zh-tw/advanced/best-practice-security.md +++ b/zh-tw/advanced/best-practice-security.md @@ -1,81 +1,173 @@ --- layout: page title: 正式作業中的 Express 安全最佳作法 +description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced -lang: zh-tw +redirect_from: " " --- # 正式作業最佳作法:安全 ## 概觀 -「*正式作業*」術語是指軟體生命週期中,應用程式或 API 通用於其一般使用者或消費者的階段。相對地,在「*開發*」階段,您仍在積極撰寫和測試程式碼,且應用程式尚未開放給外部存取。對應的系統環境分別稱為*正式作業*環境和*開發*環境。 +The term _"production"_ refers to the stage in the software lifecycle when an application or API is generally available to its end-users or consumers. In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively. -開發環境和正式作業環境的設定方式通常不同,且其需求差異頗大。適合用於開發中的,在正式作業中不見得合用。舉例來說,在開發環境中,您可能希望詳細記載錯誤以便除錯,而相同的行為在正式作業環境中卻可能成為安全隱憂。在開發中,您不必擔心可調整性、可靠性和效能,但在正式作業中這些顧慮相形重要。 +Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production. -本文討論部署至正式作業之 Express 應用程式的一些安全最佳作法。 +{% capture security-note %} + +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). + +{% endcapture %} + +{% include admonitions/note.html content=security-note %} + +Security best practices for Express applications in production include: + +- [Production Best Practices: Security](#production-best-practices-security) + - [Overview](#overview) + - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) + - 您可能熟悉 Secure Socket Layer (SSL) 加密。[TLS 就是 SSL 後繼的演進](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx)。換句話說,如果您之前使用 SSL,請考量升級至 TLS。一般而言,我們建議由 Nginx 來處理 TLS。如需有關在 Nginx(和其他伺服器)上配置 TLS 的適當參考資料,請參閱 [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations)。 + - [Do not trust user input](#do-not-trust-user-input) + - [Prevent open redirects](#prevent-open-redirects) + - [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) 會移除 `X-Powered-By` 標頭。 + - [Reduce fingerprinting](#reduce-fingerprinting) + - `domain` - 指出 Cookie 的網域;用來與發出 URL 要求之伺服器的網域相互比較。如果相符,接著會檢查路徑屬性。 + - 相對地,[cookie-session](https://www.npmjs.com/package/cookie-session) 中介軟體會實作以 Cookie 為基礎的儲存體:它會將整個階段作業序列化為 Cookie,而非只是一個階段作業金鑰。只有在階段作業資料相對較小,且易於編碼成基本值(而非物件)時,才使用此項。雖然瀏覽器對於每個 Cookie 理應可以支援至少 + 4096 個位元組,為了確保您不會超出限制,對於每一個網域,請勿超過 4093 個位元組大小。此外要留意的是,用戶端可以看見 Cookie 資料,因此,若有任何原因需要保護該資料的安全或加以遮蔽,最好選擇 express-session。 + - 使用預設階段作業 Cookie 名稱可能開放您的應用程式遭受攻擊。引發的安全問題類似於 `X-Powered-By`:潛在的攻擊者可能用它來對伺服器進行指紋辨識,從而發動目標攻擊。 + - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) + - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) + - 最後,如同其他任何的 Web 應用程式,Express 應用程式仍可能遭到各種 Web 型攻擊。請多加熟悉已知的 [Web 漏洞](https://www.owasp.org/www-project-top-ten/),並採取預防措施,來避免這些攻擊。 + - [Additional considerations](#additional-considerations) ## 請勿使用已淘汰或有漏洞的 Express 版本 -Express 2.x 和 3.x 不再維護。不會修正這些版本中的安全與效能問題。請勿使用它們!如果您尚未移至第 4 版,請遵循[移轉手冊](/{{ page.lang }}/guide/migrating-4.html)。 +Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html) or consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). -另請確定您沒有使用[「安全更新」頁面](/{{ page.lang }}/advanced/security-updates.html)中列出的任何有漏洞的 Express 版本。若有使用,請更新為其中一個穩定版本,最好是最新版本。 +另請確定您沒有使用[「安全更新」頁面](/{{ page.lang }}/advanced/security-updates.html)中列出的任何有漏洞的 Express 版本。若有使用,請更新為其中一個穩定版本,最好是最新版本。 If you are, update to one of the stable releases, preferably the latest. ## 使用 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)。 +If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). -您可能熟悉 Secure Socket Layer (SSL) 加密。[TLS 就是 SSL 後繼的演進](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx)。換句話說,如果您之前使用 SSL,請考量升級至 TLS。一般而言,我們建議由 Nginx 來處理 TLS。如需有關在 Nginx(和其他伺服器)上配置 TLS 的適當參考資料,請參閱 [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations)。 +You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515\(v=vs.85\).aspx). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). 此外,可方便您取得免費 TLS 憑證的工具是 [Let's Encrypt](https://letsencrypt.org/about/),這是一個免費的自動化開放憑證管理中心 (CA),由 [Internet Security Research Group (ISRG)](https://letsencrypt.org/isrg/) 提供。 +## Do not trust user input + +For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. +Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. + +### Prevent open redirects + +An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and +return a 3xx status. + +An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. + +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') { + return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) + } + } catch (e) { + return res.status(400).end(`Invalid url: ${req.query.url}`) + } + res.redirect(req.query.url) +}) +``` + ## 使用 Helmet [Helmet](https://www.npmjs.com/package/helmet) 會適當設定 HTTP 標頭,有助於防範您的應用程式出現已知的 Web 漏洞。 -Helmet 實際上只由 9 個小型中介軟體函數組成,這些函數會設定安全相關的 HTTP 標頭: +Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: + +- `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks +- `Cross-Origin-Opener-Policy`: Helps process-isolate your page +- `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin +- `Origin-Agent-Cluster`: Changes process isolation to be origin-based +- `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header +- `Strict-Transport-Security`: Tells browsers to prefer HTTPS +- `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) +- `X-DNS-Prefetch-Control`: Controls DNS prefetching +- `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) +- `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks +- `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat +- `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks +- `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it -* [csp](https://github.com/helmetjs/csp) 會設定 `Content-Security-Policy` 標頭,以防範跨網站 Scripting 攻擊和其他跨網站注入。 -* [hidePoweredBy](https://github.com/helmetjs/hide-powered-by) 會移除 `X-Powered-By` 標頭。 -* [hsts](https://github.com/helmetjs/hsts) 會設定 `Strict-Transport-Security` 標頭,以施行安全的 (HTTP over SSL/TLS) 伺服器連線。 -* [ieNoOpen](https://github.com/helmetjs/ienoopen) 會設定 `X-Download-Options`(適用於 IE8+)。 -* [noCache](https://github.com/helmetjs/nocache) 會設定 `Cache-Control` 和 Pragma 標頭,以停用用戶端快取。 -* [noSniff](https://github.com/helmetjs/dont-sniff-mimetype) 會設定 `X-Content-Type-Options`,以阻止瀏覽器對脫離所宣告內容類型的回應進行 MIME 探查。 -* [frameguard](https://github.com/helmetjs/frameguard) 會設定 `X-Frame-Options` 標頭,以提供 [clickjacking](https://www.owasp.org/index.php/Clickjacking) 保護。 -* [xssFilter](https://github.com/helmetjs/x-xss-protection) 會設定 `X-XSS-Protection`,以便在最新的 Web 瀏覽器中啟用跨網站 Scripting (XSS) 過濾器。 +Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. 安裝 Helmet 等之類的其他任何模組: -
    -
    -$ npm install --save helmet
    -
    -
    +```bash +$ npm install helmet +``` 然後在您的程式碼中使用它: -
    -
    -...
    -var helmet = require('helmet');
    -app.use(helmet());
    -...
    -
    -
    +```js +// ... + +const helmet = require('helmet') +app.use(helmet()) + +// ... +``` + +## Reduce fingerprinting + +It can help to provide an extra layer of security to reduce the ability of attackers to determine +the software that a server uses, known as "fingerprinting." Though not a security issue itself, +reducing the ability to fingerprint an application improves its overall security posture. +Server software can be fingerprinted by quirks in how it responds to specific requests, for example in +the HTTP response headers. + +By default, Express sends the `X-Powered-By` response header that you can +disable using the `app.disable()` method: + +```js +app.disable('x-powered-by') +``` + +{% capture powered-advisory %} -### 至少停用 X-Powered-By 標頭 +Disabling the `X-Powered-By header` does not prevent +a sophisticated attacker from determining that an app is running Express. It may +discourage a casual exploit, but there are other ways to determine an app is running +Express. -如果您不想使用 Helmet,最起碼請停用 `X-Powered-By` 標頭。攻擊者可能使用這個標頭(依預設,會啟用),來偵測執行 Express 的應用程式,然後啟動特定目標的攻擊。 +{% endcapture %} -因此最佳作法是使用 `app.disable()` 方法來關閉標頭: +{% include admonitions/note.html content=powered-advisory %} -
    -
    -app.disable('x-powered-by');
    -
    -
    +Express also sends its own formatted "404 Not Found" messages and formatter error +response messages. These can be changed by +[adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) +and +[writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): -如果您使用 `helmet.js`,自會為您處理此事。 +```js +// last app.use calls right before app.listen(): + +// custom 404 +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) + +// custom error handler +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` ## 安全地使用 Cookie @@ -83,82 +175,112 @@ app.disable('x-powered-by'); 以下是兩個主要的中介軟體 Cookie 階段作業模組: -* [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` 中介軟體。 +- [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 本身中。依預設,它使用記憶體內儲存體,且並非設計成用於正式作業環境。在正式作業中,您需要設定可調式階段作業儲存庫; -請參閱[相容的階段作業儲存庫](https://github.com/expressjs/session#compatible-session-stores)清單。 +請參閱[相容的階段作業儲存庫](https://github.com/expressjs/session#compatible-session-stores)清單。 The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. 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 個位元組,為了確保您不會超出限制,對於每一個網域,請勿超過 4093 個位元組大小。此外要留意的是,用戶端可以看見 Cookie 資料,因此,若有任何原因需要保護該資料的安全或加以遮蔽,最好選擇 express-session。 +In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then `express-session` may be a better choice. ### 請勿使用預設階段作業 Cookie 名稱 -使用預設階段作業 Cookie 名稱可能開放您的應用程式遭受攻擊。引發的安全問題類似於 `X-Powered-By`:潛在的攻擊者可能用它來對伺服器進行指紋辨識,從而發動目標攻擊。 +Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. 為了避免發生此問題,請使用通用 Cookie 名稱; 例如,使用 [express-session](https://www.npmjs.com/package/express-session) 中介軟體: -
    -
    -var session = require('express-session');
    +```js
    +const session = require('express-session')
     app.set('trust proxy', 1) // trust first proxy
    -app.use( session({
    -   secret : 's3Cur3',
    -   name : 'sessionId',
    -  })
    -);
    -
    -
    +app.use(session({ + secret: 's3Cur3', + name: 'sessionId' +})) +``` ### 設定 Cookie 安全選項 設定下列 Cookie 選項來加強安全: -* `secure` - 確保瀏覽器只透過 HTTPS 傳送 Cookie。 -* `httpOnly` - 確保只透過 HTTP(S) 傳送 Cookie,而不透過用戶端 JavaScript 傳送,如此有助於防範跨網站 Scripting 攻擊。 -* `domain` - 指出 Cookie 的網域;用來與發出 URL 要求之伺服器的網域相互比較。如果相符,接著會檢查路徑屬性。 -* `path` - 指出 Cookie 的路徑;用來與要求路徑相互比較。如果此項與網域相符,則會傳送要求中的 Cookie。 -* `expires` - 用來設定持續性 Cookie 的到期日。 +- `secure` - 確保瀏覽器只透過 HTTPS 傳送 Cookie。 +- `httpOnly` - 確保只透過 HTTP(S) 傳送 Cookie,而不透過用戶端 JavaScript 傳送,如此有助於防範跨網站 Scripting 攻擊。 +- `domain` - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next. +- `path` - 指出 Cookie 的路徑;用來與要求路徑相互比較。如果此項與網域相符,則會傳送要求中的 Cookie。 If this and domain match, then send the cookie in the request. +- `expires` - 用來設定持續性 Cookie 的到期日。 下列範例使用 [cookie-session](https://www.npmjs.com/package/cookie-session) 中介軟體: -
    -
    -var session = require('cookie-session');
    -var express = require('express');
    -var app = express();
    +```js
    +const session = require('cookie-session')
    +const express = require('express')
    +const app = express()
     
    -var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour
    +const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
     app.use(session({
       name: 'session',
       keys: ['key1', 'key2'],
    -  cookie: { secure: true,
    -            httpOnly: true,
    -            domain: 'example.com',
    -            path: 'foo/bar',
    -            expires: expiryDate
    -          }
    -  })
    -);
    -
    -
    + cookie: { + secure: true, + httpOnly: true, + domain: 'example.com', + path: 'foo/bar', + expires: expiryDate + } +})) +``` -## 其他注意事項 +## Prevent brute-force attacks against authorization + +Make sure login endpoints are protected to make private data more secure. + +A simple and powerful technique is to block authorization attempts using two metrics: + +1. The number of consecutive failed attempts by the same user name and IP address. +2. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. + +[rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) + +## Ensure your dependencies are secure + +Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. -以下是優異的 [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/) 所提供的進一步建議。如需這些建議的所有詳細資料,請參閱該部落格文章: +Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. -* 實作速率限制,以防對鑑別發動強制入侵攻擊。其中一個作法是使用 [StrongLoop API Gateway](https://strongloop.com/node-js/api-gateway/) 來施行速率限制原則。或者,您可以使用 [express-limiter](https://www.npmjs.com/package/express-limiter) 之類的中介軟體,但是如果這樣做,您需要稍微修改程式碼。 -* 使用 [csurf](https://www.npmjs.com/package/csurf) 中介軟體,來防範偽造跨網站要求 (CSRF)。 -* 一律對使用者輸入進行過濾和消毒,來防範跨網站 Scripting (XSS) 和指令注入攻擊。 -* 使用參數化查詢或備妥陳述式,來防禦 SQL 注入攻擊。 -* 使用開放程式碼 [sqlmap](http://sqlmap.org/) 工具,來偵測您應用程式中的 SQL 注入漏洞。 -* 使用 [nmap](https://nmap.org/) 和 [sslyze](https://github.com/nabla-c0d3/sslyze) 工具,來測試您 SSL 密碼、金鑰和重新協議的配置,以及測試您憑證的有效性。 -* 使用 [safe-regex](https://www.npmjs.com/package/safe-regex),確定您的正規表示式不易受到[正規表示式阻斷服務](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)攻擊。 +```bash +$ 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: + +```bash +$ npm install -g snyk +$ cd your-app +``` + +Use this command to test your application for vulnerabilities: + +```bash +$ snyk test +``` + +### 避免其他已知的漏洞 + +Keep an eye out for [Node Security Project](https://npmjs.com/advisories) or [Snyk](https://snyk.io/vuln/) 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. + +## 其他注意事項 -## 避免其他已知的漏洞 +以下是優異的 [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/) 所提供的進一步建議。如需這些建議的所有詳細資料,請參閱該部落格文章: Refer to that blog post for all the details on these recommendations: -關注 [Node Security Project](https://npmjs.com/advisories) 中有關可能影響您應用程式所用之 Express 或其他模組的公告。一般而言,Node Security Project 是一個絕佳的資源,它提供 Node 安全的相關知識和工具。 +- 一律對使用者輸入進行過濾和消毒,來防範跨網站 Scripting (XSS) 和指令注入攻擊。 +- 使用參數化查詢或備妥陳述式,來防禦 SQL 注入攻擊。 +- 使用開放程式碼 [sqlmap](http://sqlmap.org/) 工具,來偵測您應用程式中的 SQL 注入漏洞。 +- 使用 [nmap](https://nmap.org/) 和 [sslyze](https://github.com/nabla-c0d3/sslyze) 工具,來測試您 SSL 密碼、金鑰和重新協議的配置,以及測試您憑證的有效性。 +- 使用 [safe-regex](https://www.npmjs.com/package/safe-regex),確定您的正規表示式不易受到[正規表示式阻斷服務](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)攻擊。 -最後,如同其他任何的 Web 應用程式,Express 應用程式仍可能遭到各種 Web 型攻擊。請多加熟悉已知的 [Web 漏洞](https://www.owasp.org/index.php/Top_10_2013-Top_10),並採取預防措施,來避免這些攻擊。 +[helmet]: <如果您使用 `helmet.js`,自會為您處理此事。> \ No newline at end of file diff --git a/zh-tw/advanced/developing-template-engines.md b/zh-tw/advanced/developing-template-engines.md old mode 100755 new mode 100644 index 55deec6465..a85d6fcd31 --- a/zh-tw/advanced/developing-template-engines.md +++ b/zh-tw/advanced/developing-template-engines.md @@ -1,48 +1,46 @@ --- layout: page title: 開發 Express 範本引擎 +description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced -lang: zh-tw +redirect_from: " " --- # 開發 Express 範本引擎 -利用 `app.engine(ext, callback)` 方法,來建立您自己的範本引擎。`ext` 是指副檔名,`callback` 是範本引擎函數,它可接受下列項目作為參數:檔案的位置、options 物件,以及回呼函數。 +利用 `app.engine(ext, callback)` 方法,來建立您自己的範本引擎。`ext` 是指副檔名,`callback` 是範本引擎函數,它可接受下列項目作為參數:檔案的位置、options 物件,以及回呼函數。 `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. 下列程式碼範例說明如何實作一個相當簡單的範本引擎,以呈現 `.ntl` 檔。 -
    -
    -var fs = require('fs'); // this engine requires the fs module
    -app.engine('ntl', function (filePath, options, callback) { // define the template engine
    -  fs.readFile(filePath, function (err, content) {
    -    if (err) return callback(new Error(err));
    +```js
    +const fs = require('fs') // this engine requires the fs module
    +app.engine('ntl', (filePath, options, callback) => { // define the template engine
    +  fs.readFile(filePath, (err, content) => {
    +    if (err) return callback(err)
         // this is an extremely simple template engine
    -    var rendered = content.toString().replace('#title#', ''+ options.title +'')
    -    .replace('#message#', '

    '+ options.message +'

    '); - return callback(null, rendered); - }); -}); -app.set('views', './views'); // specify the views directory -app.set('view engine', 'ntl'); // register the template engine -
    -
    - -現在,您的應用程式能夠呈現 `.ntl` 檔。請在 `views` 目錄中建立一個名稱是 `index.ntl` 的檔案,內含下列內容。 - -
    -
    +    const rendered = content.toString()
    +      .replace('#title#', `${options.title}`)
    +      .replace('#message#', `

    ${options.message}

    `) + return callback(null, rendered) + }) +}) +app.set('views', './views') // specify the views directory +app.set('view engine', 'ntl') // register the template engine +``` + +Your app will now be able to render `.ntl` files. 現在,您的應用程式能夠呈現 `.ntl` 檔。請在 `views` 目錄中建立一個名稱是 `index.ntl` 的檔案,內含下列內容。 + +```pug #title# #message# -
    -
    -然後在應用程式中建立下列路由。 - -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    -當您向首頁提出要求時,`index.ntl` 會呈現成 HTML。 +``` + +Then, create the following route in your app. + +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` + +當您向首頁提出要求時,`index.ntl` 會呈現成 HTML。 \ No newline at end of file diff --git a/zh-tw/advanced/healthcheck-graceful-shutdown.md b/zh-tw/advanced/healthcheck-graceful-shutdown.md new file mode 100644 index 0000000000..623189df3f --- /dev/null +++ b/zh-tw/advanced/healthcheck-graceful-shutdown.md @@ -0,0 +1,33 @@ +--- +layout: page +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. +menu: advanced +redirect_from: " " +--- + +# Health Checks and Graceful Shutdown + +## 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-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. \ No newline at end of file diff --git a/zh-tw/advanced/pm.md b/zh-tw/advanced/pm.md deleted file mode 100755 index 2a87c90cb9..0000000000 --- a/zh-tw/advanced/pm.md +++ /dev/null @@ -1,282 +0,0 @@ ---- -layout: page -title: Express 應用程式的程序管理程式 -menu: advanced -lang: zh-tw ---- - -# Express 應用程式的程序管理程式 - -當您在正式作業中執行 Express 應用程式時,使用*程序管理程式*有助您達成下列作業: - -- 在應用程式當機時,自動重新啟動它。 -- 洞察執行時期效能和資源的耗用情況。 -- 動態修改設定,以改良效能。 -- 控制叢集作業。 - -程序管理程式有點像應用程式伺服器;它是一個應用程式的「儲存器」,有助於部署、提供高可用性,並可讓您在執行時期管理應用程式。 - -對 Express 和其他 Node.js 應用程式來說,最普及的程序管理程式如下: - -- [StrongLoop Process Manager](#sl) -- [PM2](#pm2) -- [Forever](#forever) - - -這三種工具都非常好用,但是 StrongLoop Process Manager 是唯一可以全面提供執行時期和部署解決方案的工具,單以一個統一的介面,就能針對正式作業前後的每一個步驟提供相關工具,來處理整個 Node.js 應用程式的生命週期。 - -以下是這每一個工具的簡要概觀。如需詳細比較,請參閱 [http://strong-pm.io/compare/](http://strong-pm.io/compare/)。 - -## StrongLoop Process Manager - -StrongLoop Process Manager (StrongLoop PM) 是 Node.js 應用程式的正式作業程序管理程式。StrongLoop PM 具有內建的負載平衡、 -監視和多主機部署,以及一個圖形主控台。您可以利用 StrongLoop PM 來執行下列作業: - -- 建置和包裝 Node.js 應用程式,並部署至本端或遠端系統。 -- 檢視 CPU 設定檔和資料堆 Snapshot,使效能達到最佳,並診斷記憶體洩漏情況。 -- 讓程序和叢集永遠維持作用中。 -- 檢視您應用程式上的效能度量。 -- 透過 Nginx 整合,輕鬆管理多主機部署。 -- 將多個 StrongLoop PM 統整成一個分散式微服務執行時期,以便從 Arc 來管理。 - -您可以利用 `slc` 這個功能強大的指令行介面或名為 Arc 的圖形工具,來處理 StrongLoop PM。Arc 是開放程式碼,StrongLoop 會提供專業人員支援。 - -如需相關資訊,請參閱 [http://strong-pm.io/](http://strong-pm.io/)。 - -完整說明文件: - -- [Operating Node apps(StrongLoop 說明文件)](http://docs.strongloop.com/display/SLC) -- [Using StrongLoop Process Manager](http://docs.strongloop.com/display/SLC/Using+Process+Manager). - -### 安裝 -
    -
    -$ [sudo] npm install -g strongloop
    -
    -
    - -### 基本用法 -
    -
    -$ cd my-app
    -$ slc start
    -
    -
    - -檢視 Process Manager 和所有已部署應用程式的狀態: - -
    -
    -$ slc ctl
    -Service ID: 1
    -Service Name: my-app
    -Environment variables:
    -  No environment variables defined
    -Instances:
    -    Version  Agent version  Cluster size
    -     4.1.13      1.5.14           4
    -Processes:
    -        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?
    -    1.1.57692  57692   0
    -    1.1.57693  57693   1     0.0.0.0:3001
    -    1.1.57694  57694   2     0.0.0.0:3001
    -    1.1.57695  57695   3     0.0.0.0:3001
    -    1.1.57696  57696   4     0.0.0.0:3001
    -
    -
    - -列出所有受管理的應用程式(服務): - -
    -
    -$ slc ctl ls
    -Id          Name         Scale
    - 1          my-app       1
    -
    -
    - -停止應用程式: - -
    -
    -$ slc ctl stop my-app
    -
    -
    - -重新啟動應用程式: - -
    -
    -$ slc ctl restart my-app
    -
    -
    - -您也可以「軟重新啟動」,這會提供工作者程序一個寬限期,使其有時間關閉現有的連線,再重新啟動現行應用程式: - -
    -
    -$ slc ctl soft-restart my-app
    -
    -
    - -從管理中移除應用程式: - -
    -
    -$ slc ctl remove my-app
    -
    -
    - -## PM2 - -PM2 是 Node.js 應用程式的正式作業程序管理程式,具有一個內建的負載平衡器。PM2 容許您讓應用程式永遠維持作用中,並在重新載入時不需關閉,且能協助進行一般的系統管理作業。PM2 也可讓您管理應用程式記載、監視和叢集作業。 - -如需相關資訊,請參閱 [https://github.com/Unitech/pm2](https://github.com/Unitech/pm2)。 - -### 安裝 - -
    -
    -$ [sudo] npm install pm2 -g
    -
    -
    - -### 基本用法 - -當您使用 `pm2` 指令啟動應用程式時,必須指定應用程式的路徑。不過,當您停止、重新啟動或刪除應用程式時,只需指定應用程式的名稱或 ID 即可。 - -
    -
    -$ pm2 start npm --name my-app -- start
    -[PM2] restartProcessId process id 0
    -┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
    -│ App name │ id │ mode │ pid   │ status │ restart │ uptime │ memory      │ watching │
    -├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
    -│ my-app   │ 0  │ fork │ 64029 │ online │ 1       │ 0s     │ 17.816 MB   │ disabled │
    -└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
    - Use the `pm2 show ` command to get more details about an app.
    -
    -
    - -當您使用 `pm2` 指令啟動應用程式時,會立即將應用程式傳送至背景。您可以從指令行使用各種 `pm2` 指令來控制背景的應用程式。 - -使用 `pm2` 指令啟動應用程式之後,會使用 ID 將它登錄在 PM2 的程序清單中。因此,您可以使用其 ID 來管理系統不同目錄中同名的應用程式。 - -請注意,如果有多個同名的應用程式正在執行,全會受到 `pm2` 指令的影響。因此請使用 ID 而非名稱,來管理個別的應用程式。 - -列出所有正在執行的程序: - -
    -
    -$ pm2 list
    -
    -
    - -停止應用程式: - -
    -
    -$ pm2 stop 0
    -
    -
    - -重新啟動應用程式: - -
    -
    -$ pm2 restart 0
    -
    -
    - -檢視應用程式的詳細資訊: - -
    -
    -$ pm2 show 0
    -
    -
    - -將應用程式從 PM2 登錄移除: - -
    -
    -$ pm2 delete 0
    -
    -
    - - -## Forever - -Forever 是一個簡式指令行介面工具,可確保給定的 Script 持續(永遠)執行。Forever 的簡式介面很適合用來執行小型的 Node.js 應用程式和 Script 部署。 - -如需相關資訊,請參閱 [https://github.com/foreverjs/forever](https://github.com/foreverjs/forever)。 - -### 安裝 - -
    -
    -$ [sudo] npm install forever -g
    -
    -
    - -### 基本用法 - -如果要啟動 Script,請使用 `forever start` 指令,並指定 Script 路徑: - -
    -
    -$ forever start script.js
    -
    -
    - -這個指令會以常駐程式模式(在背景中)執行 Script。 - -如果要執行 Script,使其附加至終端機,請省略 `start`: - -
    -
    -$ forever script.js
    -
    -
    - -建議您使用記載選項 `-l`、`-o` 和 `-e`,記載 Forever 工具和 Script 的輸出,如下列範例所示: - -
    -
    -$ forever start -l forever.log -o out.log -e err.log script.js
    -
    -
    - -檢視 Forever 已啟動的 Script 清單: - -
    -
    -$ forever list
    -
    -
    - -如果要停止 Forever 已啟動的 Script,請使用 `forever stop` 指令,並指定程序索引(如 `forever list` 指令所列)。 - -
    -
    -$ forever stop 1
    -
    -
    - -或者,指定檔案的路徑: - -
    -
    -$ forever stop script.js
    -
    -
    - -停止 Forever 已啟動的所有 Script: - -
    -
    -$ forever stopall
    -
    -
    - -Forever 還有諸多選項,也會提供一個程式化 API。 diff --git a/zh-tw/advanced/security-updates.md b/zh-tw/advanced/security-updates.md old mode 100755 new mode 100644 index 524b044f53..4b53fa528e --- a/zh-tw/advanced/security-updates.md +++ b/zh-tw/advanced/security-updates.md @@ -1,44 +1,89 @@ --- layout: page title: Express 安全更新 +description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced -lang: zh-tw +redirect_from: " " --- # 安全更新
    -Node.js 的漏洞會直接影響 Express。因此,請[隨時監看 Node.js 漏洞](http://blog.nodejs.org/vulnerability/),並確保您所用的是最新的 Node.js 穩定版本。 + +Node.js 的漏洞會直接影響 Express。因此,請[隨時監看 Node.js 漏洞](https://nodejs.org +/en/blog/vulnerability/),並確保您所用的是最新的 Node.js 穩定版本。 + Therefore, [keep a watch on Node.js vulnerabilities](https://nodejs.org/en/blog/vulnerability/) and make sure you are using the latest stable version of Node.js.
    以下列舉已在指定的版本更新中修正的 Express 漏洞。 +{% capture security-policy %} +If you believe you have discovered a security vulnerability in Express, please see +[Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). +{% endcapture %} + +{% include admonitions/note.html content=security-policy %} + ## 4.x - * 4.11.1 - * 已修正 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路徑揭露漏洞 - * 4.10.7 - * 已修正 `express.static`([諮詢](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中的開放重新導向漏洞。 - * 4.8.8 - * 已修正 `express.static`([諮詢](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` 錯誤和伺服器無回應。 - * 4.8.0 - * 如果稀疏陣列在查詢字串中的索引過多,可能導致程序耗盡記憶體,而使伺服器當機。 - * 巢狀過深的查詢字串物件可能造成程序封鎖,使伺服器暫時沒有回應。 +- 4.21.2 + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). +- 4.21.1 + - The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. +- 4.20.0 + - Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). + - The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). + - The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). + - The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). + - The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. +- 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 + - The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. +- 4.16.0 + - The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `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. + - The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. +- 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). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +- 4.15.3 + - The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +- 4.15.2 + - The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. +- 4.11.1 + - 已修正 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路徑揭露漏洞 +- 4.10.7 + - 已修正 `express.static`([諮詢](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中的開放重新導向漏洞。 +- 4.8.8 + - 已修正 `express.static`([諮詢](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` 錯誤和伺服器無回應。 Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. +- 4.8.0 + - 如果稀疏陣列在查詢字串中的索引過多,可能導致程序耗盡記憶體,而使伺服器當機。 + - Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. ## 3.x - * 3.19.1 - * 已修正 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路徑揭露漏洞 - * 3.19.0 - * 已修正 `express.static`([諮詢](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中的開放重新導向漏洞。 - * 3.16.10 - * 已修正 `express.static` 中的目錄遍訪漏洞。 - * 3.16.6 - * 在某些情況下,Node.js 0.10 可能洩漏 `fd`,而影響 `express.static` 和 `res.sendfile`。惡意的要求可能造成 `fd` 洩漏,最後導致 `EMFILE` 錯誤和伺服器無回應。 - * 3.16.0 - * 如果稀疏陣列在查詢字串中的索引過多,可能導致程序耗盡記憶體,而使伺服器當機。 - * 巢狀過深的查詢字串物件可能造成程序封鎖,使伺服器暫時沒有回應。 - * 3.3.0 - * 404 回應(試圖進行不支援的方法置換)容易受到跨網站 Scripting 攻擊。 +
    + **Express 3.x 已不再維護** + +Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. + +If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). + +
    + +- 3.19.1 + - 已修正 `express.static`、`res.sendfile` 和 `res.sendFile` 中的根路徑揭露漏洞 +- 3.19.0 + - 已修正 `express.static`([諮詢](https://npmjs.com/advisories/35)、[CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164))中的開放重新導向漏洞。 +- 3.16.10 + - 已修正 `express.static` 中的目錄遍訪漏洞。 +- 3.16.6 + - 在某些情況下,Node.js 0.10 可能洩漏 `fd`,而影響 `express.static` 和 `res.sendfile`。惡意的要求可能造成 `fd` 洩漏,最後導致 `EMFILE` 錯誤和伺服器無回應。 Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. +- 3.16.0 + - 如果稀疏陣列在查詢字串中的索引過多,可能導致程序耗盡記憶體,而使伺服器當機。 + - Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. +- 3.3.0 + - 404 回應(試圖進行不支援的方法置換)容易受到跨網站 Scripting 攻擊。 \ No newline at end of file diff --git a/zh-tw/api.md b/zh-tw/api.md old mode 100755 new mode 100644 index fed44dfde2..4075da84b0 --- a/zh-tw/api.md +++ b/zh-tw/api.md @@ -1,25 +1,21 @@ --- -layout: 4x-api -title: Express 4.x - API 參照 -lang: zh-tw +layout: api +version: 5x +title: Express 5.x - API 參照 +description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. +menu: api +redirect_from: " " --- -
    - -

    4.x API

    - - - {% include api/en/4x/express.md %} +
    +

    5.x API

    + {% include api/en/5x/express.md %} - {% include api/en/4x/app.md %} - + {% include api/en/5x/app.md %} - {% include api/en/4x/req.md %} - + {% include api/en/5x/req.md %} - {% include api/en/4x/res.md %} - + {% include api/en/5x/res.md %} - {% include api/en/4x/router.md %} - + {% include api/en/5x/router.md %}
    diff --git a/zh-tw/changelog/index.md b/zh-tw/changelog/index.md new file mode 100644 index 0000000000..2456265b18 --- /dev/null +++ b/zh-tw/changelog/index.md @@ -0,0 +1,634 @@ +--- +layout: page +title: Express changelog +description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. +sitemap: false +redirect_from: + - " " + - " " +--- + + + +
    + +# Release changelog + +All the latest updates, improvements, and fixes to Express + +## Express v5 + +{: id="5.x"} + +### 5.1.0 - Release date: 2025-03-31 + +{: id="5.0.1"} + +The 5.1.0 minor release includes some new features and improvements: + +- Support for sending responses as Uint8Array +- Added support for ETag option in `res.sendFile()` +- Added support for adding multiple links with the same rel with `res.links()` +- Performance: Use loop for acceptParams +- [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) + - Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` + - Remove `unpipe` & `destroy` +- [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) + - Restore `debug`. Now with the `router` scope instead of `express`. + - Remove legacy node.js support checks for `setImmediate` + - Deprecate non-native promise support + - Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` +- [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) + - Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support + - Remove `unpipe` +- Transitioned all remaining dependencies to use `^` ranges instead of locked versions +- Add package.json funding field to highlight our OpenCollective +- See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) + +### 5.0.1 - Release date: 2024-10-08 + +{: id="5.0.1"} + +The 5.0.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 5.0.0 - Release date: 2024-09-09 + +{: id="5.0.0"} + +Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. + +## Express v4 + +{: id="4.x"} + +### 4.21.2 - Release date: 2024-11-06 + +{: id="4.21.2"} + +The 4.21.2 patch release includes one security fix: + +- Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). + +### 4.21.1 - Release date: 2024-10-08 + +{: id="4.21.1"} + +The 4.21.1 patch release includes one security fix: + +- Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). + +### 4.21.0 - Release date: 2024-09-11 + +{: id="4.21.0"} + +The 4.21.0 minor release includes one new feature: + +- Deprecate `res.location("back")` and `res.redirect("back")` magic string + +### 4.20.0 - Release date: 2024-09-10 + +{: id="4.20.0"} + +The 4.20.0 minor release includes bug fixes and some new features, including: + +- The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. +- The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. +- The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. +- Adds support for named matching groups in the routes using a regex +- Removes encoding of `\`, `|`, and `^` to align better with URL spec + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) + +### 4.19.2 - Release date: 2024-03-25 + +{: id="4.19.2"} + +- Improved fix for open redirect allow list bypass + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) + +### 4.19.1 - Release date: 2024-03-20 + +{: id="4.19.1"} + +- Allow passing non-strings to res.location with new encoding handling checks + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) + +### 4.19.0 - Release date: 2024-03-20 + +{: id="4.19.0"} + +- Prevent open redirect allow list bypass due to encodeurl +- deps: cookie@0.6.0 + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) + +### 4.18.3 - Release date: 2024-02-29 + +{: id="4.18.3"} + +The 4.18.3 patch release includes the following bug fix: + +
      +
    • + Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) + +### 4.18.2 - Release date: 2022-10-08 + +{: id="4.18.2"} + +The 4.18.2 patch release includes the following bug fix: + +
      +
    • + Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b)) +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) + +### 4.18.1 - Release date: 2022-04-29 + +{: id="4.18.1"} + +The 4.18.1 patch release includes the following bug fix: + +
      +
    • + Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). + +### 4.18.0 - Release date: 2022-04-25 + +{: id="4.18.0"} + +The 4.18.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option. +
    • + +
    • + The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument. +
    • + +
    • + Starting with this version, Express supports Node.js 18.x. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile). +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired. +
    • + +
    • + The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`). +
    • + +
    • + The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205. +
    • + +
    • + The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously. +
    • + +
    • + The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection". +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). + +### 4.17.3 - Release date: 2022-02-16 + +{: id="4.17.3"} + +The 4.17.3 patch release includes one bug fix: + +
      +
    • + Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). + +### 4.17.2 - Release date: 2021-12-16 + +{: id="4.17.2"} + +The 4.17.2 patch release includes the following bug fixes: + +
      +
    • + Fix handling of `undefined` in `res.jsonp` when a callback is provided. +
    • + +
    • + Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled. +
    • + +
    • + Fix handling of invalid values to the `maxAge` option of `res.cookie()`. +
    • + +
    • + Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`. +
    • + +
    • + Starting with this version, Express supports Node.js 14.x. +
    • + +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). + +### 4.17.1 - Release date: 2019-05-25 + +{: id="4.17.1"} + +The 4.17.1 patch release includes one bug fix: + +
      +
    • + The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). + +### 4.17.0 - Release date: 2019-05-16 + +{: id="4.17.0"} + +The 4.17.0 minor release includes bug fixes and some new features, including: + +
      +
    • + The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The `res.cookie()` API now supports the `"none"` value for the `sameSite` option. +
    • + +
    • + When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request. +
    • + +
    • + Starting with this version, Express supports Node.js 10.x and 12.x. +
    • + +
    • + The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument. +
    • + +
    • + The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). + +### 4.16.4 - Release date: 2018-10-10 + +{: id="4.16.4"} + +The 4.16.4 patch release includes various bug fixes: + +
      +
    • + Fix issue where `"Request aborted"` may be logged in `res.sendfile`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). + +### 4.16.3 - Release date: 2018-03-12 + +{: id="4.16.3"} + +The 4.16.3 patch release includes various bug fixes: + +
      +
    • + Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`. +
    • + +
    • + Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling. +
    • + +
    • + Fix the generated HTML document for `express.static` redirect responses to properly include ``. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). + +### 4.16.2 - Release date: 2017-10-09 + +{: id="4.16.2"} + +The 4.16.2 patch release includes a regression bug fix: + +
      +
    • + Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). + +### 4.16.1 - Release date: 2017-09-29 + +{: id="4.16.1"} + +The 4.16.1 patch release includes a regression bug fix: + +
      +
    • + Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). + +### 4.16.0 - Release date: 2017-09-28 + +{: id="4.16.0"} + +The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including: + +
      +
    • + Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. +
    • + +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Starting with this version, Express supports Node.js 8.x. +
    • + +
    • + The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks. +
    • + +
    • + The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object. +
    • + +
    • + The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache. +
    • + +
    • + The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). + +### 4.15.5 - Release date: 2017-09-24 + +{: id="4.15.5"} + +The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix: + +
      +
    • + Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. +
    • + +
    • + Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). + +### 4.15.4 - Release date: 2017-08-06 + +{: id="4.15.4"} + +The 4.15.4 patch release includes some minor bug fixes: + +
      +
    • + Fix array being set for `"trust proxy"` value being manipulated in certain conditions. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). + +### 4.15.3 - Release date: 2017-05-16 + +{: id="4.15.3"} + +The 4.15.3 patch release includes a security update and some minor bug fixes: + +
      +
    • + Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. +
    • + +
    • + Fix error when `res.set` cannot add charset to `Content-Type`. +
    • + +
    • + Fix missing `` in HTML document. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). + +### 4.15.2 - Release date: 2017-03-06 + +{: id="4.15.2"} + +The 4.15.2 patch release includes a minor bug fix: + +
      +
    • + Fix regression parsing keys starting with `[` in the extended (default) query parser. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). + +### 4.15.1 - Release date: 2017-03-05 + +{: id="4.15.1"} + +The 4.15.1 patch release includes a minor bug fix: + +
      +
    • + Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). + +### 4.15.0 - Release date: 2017-03-01 + +{: id="4.15.0"} + +The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 7.x. +
    • + +
    • + The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers. +
    • + +
    • + Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips). +
    • + +
    • + Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). + +### 4.14.1 - Release date: 2017-01-28 + +{: id="4.14.1"} + +The 4.14.1 patch release includes bug fixes and performance improvements, including: + +
      +
    • + Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). + +### 4.14.0 - Release date: 2016-06-16 + +{: id="4.14.0"} + +The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including: + +
      +
    • + Starting with this version, Express supports Node.js 6.x. +
    • + +
    • + Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106). +
    • + +
    • + The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. + +- `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. + +- `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. + +- `res.sendFile` has also been updated to handle `Range` header and redirections better. + +
    • + +
    • + The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded. +
    • + +
    • + The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases. +
    • + +
    • + The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). + +{% capture note-4-14-0 %} + +``` +This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. +``` + +{% endcapture %} +{% include admonitions/note.html content=note-4-14-0 %} + +The possible value for the `sameSite` option are: + +- `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. +- `false`, which does not set the `SameSite` attribute. +- `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. +- `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. + +
    • + +
    • + Absolute path checking on Windows, which was incorrect for some cases, has been fixed. +
    • + +
    • + IP address resolution with proxies has been greatly improved. +
    • + +
    • + The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header. +
    • +
    + +For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16). + +
    diff --git a/zh-tw/guide/behind-proxies.md b/zh-tw/guide/behind-proxies.md old mode 100755 new mode 100644 index 12a5d4cee8..b3c6945c2f --- a/zh-tw/guide/behind-proxies.md +++ b/zh-tw/guide/behind-proxies.md @@ -1,18 +1,21 @@ --- layout: page title: 位於 Proxy 背後的 Express +description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide -lang: zh-tw +redirect_from: " " --- # 位於 Proxy 背後的 Express -當 Express 應用程式是在 Proxy 背後執行時,請使用 [app.set()](/{{ page.lang }}/4x/api.html#app.set),將 `trust proxy` 應用程式變數設為下表列出的其中一值。 +When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
    -雖然未設定 `trust proxy` 應用程式變數時,應用程式並不會無法執行,但除非配置 `trust proxy`,否則,它會將 Proxy 的 IP 位址登錄成錯誤的用戶端 IP 位址。 +When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
    +The application setting `trust proxy` may be set to one of the values listed in the following table. + @@ -21,60 +24,72 @@ lang: zh-tw - + - +
    類型
    若為 `true`,會將用戶端的 IP 位址視為 `X-Forwarded-*` 標頭中的最左側項目。 -若為 `false`,會將應用程式視為直接面對網際網路,且用戶端的 IP 位址衍生自 `req.connection.remoteAddress`。這是預設值。 +若為 `false`,會將應用程式視為直接面對網際網路,且用戶端的 IP 位址衍生自 `req.connection.remoteAddress`。這是預設值。 This is the default setting. + +
    +When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value. +
    IP 位址IP addresses -要信任的 IP 位址、子網路,或是 IP 位址與子網路陣列。下列清單顯示預先配置的子網路名稱: +An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: -* loopback - `127.0.0.1/8`、`::1/128` -* linklocal - `169.254.0.0/16`、`fe80::/10` -* uniquelocal - `10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16`、`fc00::/7` +- loopback - `127.0.0.1/8`、`::1/128` +- linklocal - `169.254.0.0/16`、`fe80::/10` +- uniquelocal - `10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16`、`fc00::/7` 您可以採下列任何方式來設定 IP 位址: -
    -app.set('trust proxy', 'loopback') // specify a single subnet
    +```js
    +app.set('trust proxy', 'loopback') // specify a single subnet
     app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
     app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
    -app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
    -
    +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array +``` + +When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address. -若有指定,位址判定程序中會排除 IP 位址或子網路,且會將最接近應用程式伺服器的未授信 IP 位址判斷為用戶端的 IP 位址。
    號碼 -信任來自正面 Proxy 伺服器的第 `n` 個躍點就是用戶端。 +Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy. + +
    +When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value. +
    函數Function -自訂信任實作。只有在您清楚自己要做什麼時,才能使用此項。 -
    -app.set('trust proxy', function (ip) {
    -  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
    -  else return false;
    -});
    -
    +Custom trust implementation. + +```js +app.set('trust proxy', (ip) => { + if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs + else return false +}) +``` +
    -如果設定 `false` `trust proxy` 以外的值,會造成三項重要的變更: +Enabling `trust proxy` will have the following impact:
    • [req.hostname](/{{ page.lang }}/api.html#req.hostname) 值會衍生自 `X-Forwarded-Host` 標頭中所設定的值,且該值可能由用戶端或 Proxy 所設定。
    • 反向 Proxy 可能設定 `X-Forwarded-Proto`,以告知應用程式它是 `https` 或 `http` 或甚至是無效的名稱。[req.protocol](/{{ page.lang }}/api.html#req.protocol) 會反映此值。 + This value is reflected by [req.protocol](/{{ page.lang }}/api.html#req.protocol).
    • [req.ip](/{{ page.lang }}/api.html#req.ip) 和 [req.ips](/{{ page.lang }}/api.html#req.ips) 值中會移入 `X-Forwarded-For` 中的位址清單。
    -會使用 [proxy-addr](https://www.npmjs.com/package/proxy-addr) 套件來實作 `trust proxy` 設定。如需相關資訊,請參閱其說明文件。 +會使用 [proxy-addr](https://www.npmjs.com/package/proxy-addr) 套件來實作 `trust proxy` 設定。如需相關資訊,請參閱其說明文件。 For more information, see its documentation. diff --git a/zh-tw/guide/database-integration.md b/zh-tw/guide/database-integration.md old mode 100755 new mode 100644 index aea55819fd..e5fb3b40c7 --- a/zh-tw/guide/database-integration.md +++ b/zh-tw/guide/database-integration.md @@ -1,354 +1,490 @@ --- layout: page title: Express 資料庫整合 +description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide -lang: zh-tw +redirect_from: " " --- # 資料庫整合 -如果要在 Express 應用程式中新增連接資料庫的功能,只需在您的應用程式中載入資料庫的適當 Node.js 驅動程式即可。本文件簡要說明如何在您的 Express 應用程式中新增和使用一些最常用的 Node.js 資料庫系統模組。 - -* [Cassandra](#cassandra) -* [CouchDB](#couchdb) -* [LevelDB](#leveldb) -* [MySQL](#mysql) -* [MongoDB](#mongo) -* [Neo4j](#neo4j) -* [PostgreSQL](#postgres) -* [Redis](#redis) -* [SQLite](#sqlite) -* [ElasticSearch](#elasticsearch) +Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app: + +- [Cassandra](#cassandra) +- [Couchbase](#couchbase) +- [CouchDB](#couchdb) +- [LevelDB](#leveldb) +- [MySQL](#mysql) +- [MongoDB](#mongo) +- [Neo4j](#neo4j) +- [Oracle](#oracle) +- [PostgreSQL](#postgres) +- [Redis](#redis) +- +- [SQLite](#sqlite) +- [ElasticSearch](#elasticsearch)
    -這些資料庫驅動程式只是眾多可用驅動程式中的一部分。如需其他選項,請在 [npm](https://www.npmjs.com/) 網站中搜尋。 +These database drivers are among many that are available. For other options, +search on the [npm](https://www.npmjs.com/) site.
    - - ## Cassandra **模組**:[cassandra-driver](https://github.com/datastax/nodejs-driver) **安裝** -
    -
    +### Installation
    +
    +```bash
     $ npm install cassandra-driver
    -
    -
    +``` + +### 範例 + +```js +const cassandra = require('cassandra-driver') +const client = new cassandra.Client({ contactPoints: ['localhost'] }) + +client.execute('select key from system.local', (err, result) => { + if (err) throw err + console.log(result.rows[0]) +}) +``` + +## Couchbase + +**Module**: [couchnode](https://github.com/couchbase/couchnode) + +### Installation + +```bash +$ npm install couchbase +``` -**範例** +### 範例 -
    -
    -var cassandra = require('cassandra-driver');
    -var client = new cassandra.Client({ contactPoints: ['localhost']});
    +```js
    +const couchbase = require('couchbase')
    +const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName')
     
    -client.execute('select key from system.local', function(err, result) {
    -  if (err) throw err;
    -  console.log(result.rows[0]);
    -});
    -
    -
    +// add a document to a bucket +bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) - +// get all documents with shoe size 13 +const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' +const query = N1qlQuery.fromString(n1ql) +bucket.query(query, [13], (err, result) => { + if (err) { + console.log(err) + } else { + console.log(result) + } +}) +``` ## CouchDB **模組**:[nano](https://github.com/dscape/nano) **安裝** -
    -
    +### Installation
    +
    +```bash
     $ npm install nano
    -
    -
    +``` -**範例** +### 範例 -
    -
    -var nano = require('nano')('http://localhost:5984');
    -nano.db.create('books');
    -var books = nano.db.use('books');
    +```js
    +const nano = require('nano')('http://localhost:5984')
    +nano.db.create('books')
    +const books = nano.db.use('books')
     
    -//Insert a book document in the books database
    -books.insert({name: 'The Art of war'}, null, function(err, body) {
    -  if (!err){
    -    console.log(body);
    +// Insert a book document in the books database
    +books.insert({ name: 'The Art of war' }, null, (err, body) => {
    +  if (err) {
    +    console.log(err)
    +  } else {
    +    console.log(body)
       }
    -});
    +})
     
    -//Get a list of all books
    -books.list(function(err, body){
    -  console.log(body.rows);
    -}
    -
    -
    - - +// Get a list of all books +books.list((err, body) => { + if (err) { + console.log(err) + } else { + console.log(body.rows) + } +}) +``` ## LevelDB **模組**:[levelup](https://github.com/rvagg/node-levelup) **安裝** -
    -
    -$ npm install level levelup leveldown
    -
    -
    +### Installation -**範例** +```bash +$ npm install level levelup leveldown +``` -
    -
    -var levelup = require('levelup');
    -var db = levelup('./mydb');
    +### 範例
     
    -db.put('name', 'LevelUP', function (err) {
    +```js
    +const levelup = require('levelup')
    +const db = levelup('./mydb')
     
    -  if (err) return console.log('Ooops!', err);
    -  db.get('name', function (err, value) {
    -    if (err) return console.log('Ooops!', err);
    -    console.log('name=' + value)
    -  });
    +db.put('name', 'LevelUP', (err) => {
    +  if (err) return console.log('Ooops!', err)
     
    -});
    -
    -
    + db.get('name', (err, value) => { + if (err) return console.log('Ooops!', err) - + console.log(`name=${value}`) + }) +}) +``` ## MySQL **模組**:[mysql](https://github.com/felixge/node-mysql/) **安裝** -
    -
    +### Installation
    +
    +```bash
     $ npm install mysql
    -
    -
    +``` -**範例** +### 範例 -
    -
    -var mysql      = require('mysql');
    -var connection = mysql.createConnection({
    -  host     : 'localhost',
    -  user     : 'dbuser',
    -  password : 's3kreee7'
    -});
    +```js
    +const mysql = require('mysql')
    +const connection = mysql.createConnection({
    +  host: 'localhost',
    +  user: 'dbuser',
    +  password: 's3kreee7',
    +  database: 'my_db'
    +})
     
    -connection.connect();
    +connection.connect()
     
    -connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
    -  if (err) throw err;
    -  console.log('The solution is: ', rows[0].solution);
    -});
    +connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => {
    +  if (err) throw err
     
    -connection.end();
    -
    -
    + console.log('The solution is: ', rows[0].solution) +}) - +connection.end() +``` ## MongoDB **模組**:[mongodb](https://github.com/mongodb/node-mongodb-native) **安裝** -
    -
    +### Installation
    +
    +```bash
     $ npm install mongodb
    -
    -
    +``` -**範例** +### Example (v2.\*) -
    -
    -var MongoClient = require('mongodb').MongoClient;
    +```js
    +const MongoClient = require('mongodb').MongoClient
     
    -MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
    -  if (err) {
    -    throw err;
    -  }
    -  db.collection('mammals').find().toArray(function(err, result) {
    -    if (err) {
    -      throw err;
    -    }
    -    console.log(result);
    -  });
    -});
    -
    -
    +MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { + if (err) throw err -如果您需要 MongoDB 物件模型驅動程式,請查看 [Mongoose](https://github.com/LearnBoost/mongoose)。 + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +### Example (v3.\*) + +```js +const MongoClient = require('mongodb').MongoClient - +MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { + if (err) throw err + + const db = client.db('animals') + + db.collection('mammals').find().toArray((err, result) => { + if (err) throw err + + console.log(result) + }) +}) +``` + +如果您需要 MongoDB 物件模型驅動程式,請查看 [Mongoose](https://github.com/LearnBoost/mongoose)。 ## Neo4j -**模組**:[apoc](https://github.com/hacksparrow/apoc) -**安裝** +這些資料庫驅動程式只是眾多可用驅動程式中的一部分。如需其他選項,請在 [npm](https://www.npmjs.com/) 網站中搜尋。 + +### Installation -
    -
    -$ npm install apoc
    -
    -
    +```bash +$ npm install neo4j-driver +``` -**範例** +### 範例 -
    -
    -var apoc = require('apoc');
    +```js
    +const neo4j = require('neo4j-driver')
    +const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein'))
     
    -apoc.query('match (n) return n').exec().then(
    -  function (response) {
    -    console.log(response);
    -  },
    -  function (fail) {
    -    console.log(fail);
    +const session = driver.session()
    +
    +session.readTransaction((tx) => {
    +  return tx.run('MATCH (n) RETURN count(n) AS count')
    +    .then((res) => {
    +      console.log(res.records[0].get('count'))
    +    })
    +    .catch((error) => {
    +      console.log(error)
    +    })
    +})
    +```
    +
    +## Oracle
    +
    +**Module**: [oracledb](https://github.com/oracle/node-oracledb)
    +
    +### Installation
    +
    +NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation).
    +
    +```bash
    +$ npm install oracledb
    +```
    +
    +### 範例
    +
    +```js
    +const oracledb = require('oracledb')
    +const config = {
    +  user: '',
    +  password: '',
    +  connectString: 'localhost:1521/orcl'
    +}
    +
    +async function getEmployee (empId) {
    +  let conn
    +
    +  try {
    +    conn = await oracledb.getConnection(config)
    +
    +    const result = await conn.execute(
    +      'select * from employees where employee_id = :id',
    +      [empId]
    +    )
    +
    +    console.log(result.rows[0])
    +  } catch (err) {
    +    console.log('Ouch!', err)
    +  } finally {
    +    if (conn) { // conn assignment worked, need to close
    +      await conn.close()
    +    }
       }
    -);
    -
    -
    +} - +getEmployee(101) +``` ## PostgreSQL **模組**:[pg-promise](https://github.com/vitaly-t/pg-promise) **安裝** -
    -
    -$ npm install pg-promise
    -
    -
    +### Installation -**範例** +```bash +$ npm install pg-promise +``` -
    -
    -var pgp = require("pg-promise")(/*options*/);
    -var db = pgp("postgres://username:password@host:port/database");
    +### 範例
     
    -db.one("SELECT $1 AS value", 123)
    -    .then(function (data) {
    -        console.log("DATA:", data.value);
    -    })
    -    .catch(function (error) {
    -        console.log("ERROR:", error);
    -    });
    -
    -
    +```js +const pgp = require('pg-promise')(/* options */) +const db = pgp('postgres://username:password@host:port/database') - +db.one('SELECT $1 AS value', 123) + .then((data) => { + console.log('DATA:', data.value) + }) + .catch((error) => { + console.log('ERROR:', error) + }) +``` ## Redis **模組**:[redis](https://github.com/mranney/node_redis) **安裝** -
    -
    +### Installation
    +
    +```bash
     $ npm install redis
    -
    -
    +``` + +### 範例 + +```js +const redis = require('redis') +const client = redis.createClient() -**範例** +client.on('error', (err) => { + console.log(`Error ${err}`) +}) -
    -
    -var client = require('redis').createClient();
    +client.set('string key', 'string val', redis.print)
    +client.hset('hash key', 'hashtest 1', 'some value', redis.print)
    +client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
     
    -client.on('error', function (err) {
    -  console.log('Error ' + err);
    -});
    +client.hkeys('hash key', (err, replies) => {
    +  console.log(`${replies.length} replies:`)
     
    -client.set('string key', 'string val', redis.print);
    -client.hset('hash key', 'hashtest 1', 'some value', redis.print);
    -client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
    +  replies.forEach((reply, i) => {
    +    console.log(`    ${i}: ${reply}`)
    +  })
     
    -client.hkeys('hash key', function (err, replies) {
    +  client.quit()
    +})
    +```
     
    -  console.log(replies.length + ' replies:');
    -  replies.forEach(function (reply, i) {
    -    console.log('    ' + i + ': ' + reply);
    -  });
    +## SQL Server
     
    -  client.quit();
    +**Module**: [tedious](https://github.com/tediousjs/tedious)
     
    -});
    -
    -
    +### Installation - +```bash +$ npm install tedious +``` + +### 範例 + +```js +const Connection = require('tedious').Connection +const Request = require('tedious').Request + +const config = { + server: 'localhost', + authentication: { + type: 'default', + options: { + userName: 'your_username', // update me + password: 'your_password' // update me + } + } +} + +const connection = new Connection(config) + +connection.on('connect', (err) => { + if (err) { + console.log(err) + } else { + executeStatement() + } +}) + +function executeStatement () { + request = new Request("select 123, 'hello world'", (err, rowCount) => { + if (err) { + console.log(err) + } else { + console.log(`${rowCount} rows`) + } + connection.close() + }) + + request.on('row', (columns) => { + columns.forEach((column) => { + if (column.value === null) { + console.log('NULL') + } else { + console.log(column.value) + } + }) + }) + + connection.execSql(request) +} +``` ## SQLite **模組**:[sqlite3](https://github.com/mapbox/node-sqlite3) **安裝** -
    -
    -$ npm install sqlite3
    -
    -
    +### Installation -**範例** +```bash +$ npm install sqlite3 +``` -
    -
    -var sqlite3 = require('sqlite3').verbose();
    -var db = new sqlite3.Database(':memory:');
    +### 範例
     
    -db.serialize(function() {
    +```js
    +const sqlite3 = require('sqlite3').verbose()
    +const db = new sqlite3.Database(':memory:')
     
    -  db.run('CREATE TABLE lorem (info TEXT)');
    -  var stmt = db.prepare('INSERT INTO lorem VALUES (?)');
    +db.serialize(() => {
    +  db.run('CREATE TABLE lorem (info TEXT)')
    +  const stmt = db.prepare('INSERT INTO lorem VALUES (?)')
     
    -  for (var i = 0; i < 10; i++) {
    -    stmt.run('Ipsum ' + i);
    +  for (let i = 0; i < 10; i++) {
    +    stmt.run(`Ipsum ${i}`)
       }
     
    -  stmt.finalize();
    +  stmt.finalize()
     
    -  db.each('SELECT rowid AS id, info FROM lorem', function(err, row) {
    -    console.log(row.id + ': ' + row.info);
    -  });
    -});
    +  db.each('SELECT rowid AS id, info FROM lorem', (err, row) => {
    +    console.log(`${row.id}: ${row.info}`)
    +  })
    +})
     
    -db.close();
    -
    -
    - - +db.close() +``` ## ElasticSearch **模組**:[elasticsearch](https://github.com/elastic/elasticsearch-js) **安裝** -
    -
    +### Installation
    +
    +```bash
     $ npm install elasticsearch
    -
    -
    +``` -**範例** +### 範例 -
    -
    -var elasticsearch = require('elasticsearch');
    -var client = elasticsearch.Client({
    +```js
    +const elasticsearch = require('elasticsearch')
    +const client = elasticsearch.Client({
       host: 'localhost:9200'
    -});
    +})
     
     client.search({
       index: 'books',
    @@ -361,10 +497,9 @@ client.search({
           }
         }
       }
    -}).then(function(response) {
    -  var hits = response.hits.hits;
    -}, function(error) {
    -  console.trace(error.message);
    -});
    -
    -
    +}).then((response) => { + const hits = response.hits.hits +}, (error) => { + console.trace(error.message) +}) +``` diff --git a/zh-tw/guide/debugging.md b/zh-tw/guide/debugging.md old mode 100755 new mode 100644 index 9649c0264c..1e4c397853 --- a/zh-tw/guide/debugging.md +++ b/zh-tw/guide/debugging.md @@ -1,38 +1,28 @@ --- layout: page title: 對 Express 除錯 +description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide -lang: zh-tw +redirect_from: " " --- # 對 Express 除錯 -Express 在內部使用 [debug](https://www.npmjs.com/package/debug) 模組,來記載路由相符項、使用中的中介軟體函數、應用程式模式,以及要求/回應循環流程等相關資訊。 - -
    -`debug` 像是 `console.log` 的擴增版本,但與 `console.log` 不同的是,您不必在正式作業程式碼中註銷 `debug` 日誌。依預設,會關閉記載,並且可以使用 `DEBUG` 環境變數有條件地開啟。 -
    - 如果要查看 Express 中使用的所有內部日誌,在您啟動應用程式時,請將 `DEBUG` 環境變數設為 `express:*`。 -
    -
    +```bash
     $ DEBUG=express:* node index.js
    -
    -
    +``` 在 Windows 中,使用對應指令。 -
    -
    -> set DEBUG=express:* & node index.js
    -
    -
    +```bash +> $env:DEBUG = "express:*"; node index.js +``` 對 [express generator](/{{ page.lang }}/starter/generator.html) 產生的預設應用程式執行這個指令,會列印下列輸出: -
    -
    +```bash
     $ DEBUG=express:* node ./bin/www
       express:router:route new / +0ms
       express:router:layer new / +1ms
    @@ -68,19 +58,17 @@ $ DEBUG=express:* node ./bin/www
       express:router:layer new / +1ms
       express:router use /users router +0ms
       express:router:layer new /users +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -  express:router use / <anonymous> +0ms
    +  express:router use / &lt;anonymous&gt; +0ms
       express:router:layer new / +0ms
    -
    -
    +``` 當對應用程式發出要求時,您會看到 Express 程式碼中指定的日誌: -
    -
    +```bash
       express:router dispatching GET / +4h
       express:router query  : / +2ms
       express:router expressInit  : / +0ms
    @@ -96,10 +84,9 @@ $ DEBUG=express:* node ./bin/www
       express:view lookup "index.pug" +338ms
       express:view stat "/projects/example/views/index.pug" +0ms
       express:view render "/projects/example/views/index.pug" +1ms
    -
    -
    +``` -如果只想查看來自路由器實作的日誌,請將 `DEBUG` 的值設為 `express:router`。同樣地,如果只想查看來自應用程式實作的日誌,請將 `DEBUG` 的值設為 `express:application`,以此類推。 +如果只想查看來自路由器實作的日誌,請將 `DEBUG` 的值設為 `express:router`。同樣地,如果只想查看來自應用程式實作的日誌,請將 `DEBUG` 的值設為 `express:application`,以此類推。 Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. ## `express` 產生的應用程式 @@ -107,18 +94,36 @@ $ DEBUG=express:* node ./bin/www 舉例來說,如果您使用 `$ express sample-app` 來產生應用程式,您可以利用下列指令來啟用除錯陳述式: -
    -
    +```bash
     $ DEBUG=sample-app:* node ./bin/www
    -
    -
    +``` 您可以指派以逗點區隔的名稱清單,來指定多個除錯名稱空間: -
    -
    +```bash
     $ DEBUG=http,mail,express:* node index.js
    -
    -
    +``` + +## Advanced options + +When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: + +| Name | Purpose | +| ------------------- | ----------------------------------------------------------------- | +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_COLORS` | Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_FD` | File descriptor to write debug output to. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + +{% capture debug-text %} + +The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +{% endcapture %} -如需 `debug` 的相關資訊,請參閱 [debug](https://www.npmjs.com/package/debug)。 +{% include admonitions/note.html content=debug-text %} diff --git a/zh-tw/guide/error-handling.md b/zh-tw/guide/error-handling.md old mode 100755 new mode 100644 index bfe7def2f8..f2e14724fe --- a/zh-tw/guide/error-handling.md +++ b/zh-tw/guide/error-handling.md @@ -1,142 +1,292 @@ --- layout: page title: Express 錯誤處理 +description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide -lang: zh-tw +redirect_from: " " --- # 錯誤處理 -錯誤處理中介軟體函數的定義方式,與其他中介軟體函數相同,差別在於錯誤處理函數的引數是四個而非三個:`(err, req, res, next)`。例如: +_Error Handling_ refers to how Express catches and processes errors that +occur both synchronously and asynchronously. Express comes with a default error +handler so you don't need to write your own to get started. +## Catching Errors -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +It's important to ensure that Express catches all errors that occur while +running route handlers and middleware. -您是在定義其他 `app.use()` 和路由呼叫之後,最後才定義錯誤處理中介軟體;例如: - -
    -
    -var bodyParser = require('body-parser');
    -var methodOverride = require('method-override');
    +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:
     
    -app.use(bodyParser());
    -app.use(methodOverride());
    -app.use(function(err, req, res, next) {
    -  // logic
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + throw new Error('BROKEN') // Express will catch this on its own. +}) +``` -中介軟體函數內的回應可以是任何您喜好的格式,如:HTML 錯誤頁面、簡式訊息或 JSON 字串。 +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: -為了方便組織(和更高層次的架構),您可以定義數個錯誤處理中介軟體函數,就像您處理一般中介軟體函數一樣。舉例來說,如果您想為使用及沒有使用 `XHR` 所建立的要求,各定義一個錯誤處理程式,您可以使用下列指令: +```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) + } + }) +}) +``` -
    -
    -var bodyParser = require('body-parser');
    -var methodOverride = require('method-override');
    +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:
     
    -app.use(bodyParser());
    -app.use(methodOverride());
    -app.use(logErrors);
    -app.use(clientErrorHandler);
    -app.use(errorHandler);
    -
    -
    +```js +app.get('/user/:id', async (req, res, next) => { + const user = await getUserById(req.params.id) + res.send(user) +}) +``` -在本例中,通用的 `logErrors` 可能將要求和錯誤資訊寫入至 `stderr`,例如: +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. -
    -
    -function logErrors(err, req, res, next) {
    -  console.error(err.stack);
    -  next(err);
    -}
    -
    -
    +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. -此外在本例中,`clientErrorHandler` 定義成如下;在此情況下,會將錯誤明確傳遞給下一個: +If the callback in a sequence provides no data, only errors, you can simplify +this code as follows: -
    -
    -function clientErrorHandler(err, req, res, next) {
    -  if (req.xhr) {
    -    res.status(500).send({ error: 'Something failed!' });
    -  } else {
    -    next(err);
    +```js
    +app.get('/', [
    +  function (req, res, next) {
    +    fs.writeFile('/inaccessible-path', 'data', next)
    +  },
    +  function (req, res) {
    +    res.send('OK')
       }
    -}
    -
    -
    +]) +``` -"catch-all" `errorHandler` 函數的實作方式如下: +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. -
    -
    -function errorHandler(err, req, res, next) {
    -  res.status(500);
    -  res.render('error', { error: err });
    -}
    -
    -
    +You must catch errors that occur in asynchronous code invoked by route handlers or +middleware and pass them to Express for processing. For example: -不論您傳遞何者給 `next()` 函數(`'route'` 字串除外),Express 都會將現行要求視為發生錯誤,且會跳過其餘任何的非錯誤處理路由和中介軟體函數。如果您想以某種方式來處理該錯誤,您必須按照下一節的說明來建立錯誤處理路由。 +```js +app.get('/', (req, res, next) => { + setTimeout(() => { + try { + throw new Error('BROKEN') + } catch (err) { + next(err) + } + }, 100) +}) +``` -如果您的路由處理程式有多個回呼函數,可以使用 `route` 參數來跳到下一個路由處理程式。例如: +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. +Use promises to avoid the overhead of the `try...catch` block or when using functions +that return promises. For example: -
    -
    -app.get('/a_route_behind_paywall',
    -  function checkIfPaidSubscriber(req, res, next) {
    -    if(!req.user.hasPaid) {
    +```js
    +app.get('/', (req, res, next) => {
    +  Promise.resolve().then(() => {
    +    throw new Error('BROKEN')
    +  }).catch(next) // Errors will be passed to Express.
    +})
    +```
     
    -      // continue handling this request
    -      next('route');
    -    }
    -  }, function getPaidContent(req, res, next) {
    -    PaidContent.find(function(err, doc) {
    -      if(err) return next(err);
    -      res.json(doc);
    -    });
    -  });
    -
    -
    +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. -在本例中,會跳過 `getPaidContent` 處理程式,但是會繼續執行 `app` 中 `/a_route_behind_paywall` 的其餘處理程式。 +You could also use a chain of handlers to rely on synchronous error +catching, by reducing the asynchronous code to something trivial. For example: -
    -呼叫 `next()` 和 `next(err)`,指出現行處理程式已完成以及處於何種狀態。除了依上述說明設定成用來處理錯誤的那些處理程式,`next(err)` 會跳過處理程式鏈中其餘所有的處理程式。
    +```js +app.get('/', [ + function (req, res, next) { + fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { + res.locals.data = data + next(err) + }) + }, + function (req, res) { + res.locals.data = res.locals.data.split(',')[1] + res.send(res.locals.data) + } +]) +``` + +The above example has a couple of trivial statements from 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 +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. -## 預設錯誤處理程式 +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. -Express 隨附一個內建錯誤處理常式,它會處理應用程式中可能遇到的任何錯誤。這個預設錯誤處理中介軟體函數新增於中介軟體函數堆疊尾端。 +## The default error handler -如果您傳遞錯誤至 `next()`,且您沒有在錯誤處理常式中處理它,將會交由內建錯誤處理常式處理;該錯誤會連同堆疊追蹤寫入至用戶端。在正式作業環境中,則不包含堆疊追蹤。 +Express comes with a built-in error handler that takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack. + +如果您傳遞錯誤至 `next()`,且您沒有在錯誤處理常式中處理它,將會交由內建錯誤處理常式處理;該錯誤會連同堆疊追蹤寫入至用戶端。在正式作業環境中,則不包含堆疊追蹤。 The stack trace is not included +in the production environment.
    將 `NODE_ENV` 環境變數設為 `production`,以便在正式作業模式下執行應用程式。
    +When an error is written, the following information is added to the +response: + +- The `res.statusCode` is set from `err.status` (or `err.statusCode`). If + this value is outside the 4xx or 5xx range, it will be set to 500. +- The `res.statusMessage` is set according to the status code. +- The body will be the HTML of the status code message when in production + environment, otherwise will be `err.stack`. +- Any headers specified in an `err.headers` object. + 在您開始撰寫回應之後,一旦在呼叫 `next()` 時才發生錯誤(例如,當您將回應串流輸出至用戶端時遇到錯誤),Express 的預設錯誤處理程式會關閉連線,並使要求失敗。 -因此,在您新增自訂錯誤處理常式時,如果標頭已傳送給用戶端,您會希望委派給 Express 中的預設錯誤處理機制處理: +So when you add a custom error handler, you must delegate to +the default Express error handler, when the headers +have already been sent to the client: -
    -
    -function errorHandler(err, req, res, next) {
    +```js
    +function errorHandler (err, req, res, next) {
       if (res.headersSent) {
    -    return next(err);
    +    return next(err)
       }
    -  res.status(500);
    -  res.render('error', { error: err });
    +  res.status(500)
    +  res.render('error', { error: err })
     }
    -
    -
    +``` + +Note that the default error handler can get triggered if you call `next()` with an error +in your code more than once, even if custom error handling middleware is in place. + +Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html). + +## Writing error handlers + +錯誤處理中介軟體函數的定義方式,與其他中介軟體函數相同,差別在於錯誤處理函數的引數是四個而非三個:`(err, req, res, next)`。例如: For example: + +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` + +您是在定義其他 `app.use()` 和路由呼叫之後,最後才定義錯誤處理中介軟體;例如: + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use((err, req, res, next) => { + // logic +}) +``` + +Responses from within a middleware function can be in any format, such as an HTML error page, a simple message, or a JSON string. + +For organizational (and higher-level framework) purposes, you can define +several error-handling middleware functions, much as you would with +regular middleware functions. For example, to define an error-handler +for requests made by using `XHR` and those without: + +```js +const bodyParser = require('body-parser') +const methodOverride = require('method-override') + +app.use(bodyParser.urlencoded({ + extended: true +})) +app.use(bodyParser.json()) +app.use(methodOverride()) +app.use(logErrors) +app.use(clientErrorHandler) +app.use(errorHandler) +``` + +在本例中,通用的 `logErrors` 可能將要求和錯誤資訊寫入至 `stderr`,例如: + +```js +function logErrors (err, req, res, next) { + console.error(err.stack) + next(err) +} +``` + +此外在本例中,`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. + +```js +function clientErrorHandler (err, req, res, next) { + if (req.xhr) { + res.status(500).send({ error: 'Something failed!' }) + } else { + next(err) + } +} +``` + +"catch-all" `errorHandler` 函數的實作方式如下: + +```js +function errorHandler (err, req, res, next) { + res.status(500) + res.render('error', { error: err }) +} +``` + +If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. For example: + +```js +app.get('/a_route_behind_paywall', + (req, res, next) => { + if (!req.user.hasPaid) { + // continue handling this request + next('route') + } else { + next() + } + }, (req, res, next) => { + PaidContent.find((err, doc) => { + if (err) return next(err) + res.json(doc) + }) + }) +``` + +在本例中,會跳過 `getPaidContent` 處理程式,但是會繼續執行 `app` 中 `/a_route_behind_paywall` 的其餘處理程式。 + +
    +Calls to `next()` and `next(err)` indicate that the current handler is complete and in what state. `next(err)` will skip all remaining handlers in the chain except for those that are set up to handle errors as described above. +
    diff --git a/zh-tw/guide/migrating-4.md b/zh-tw/guide/migrating-4.md old mode 100755 new mode 100644 index e9eb78fbca..dec2130d55 --- a/zh-tw/guide/migrating-4.md +++ b/zh-tw/guide/migrating-4.md @@ -1,15 +1,16 @@ --- layout: page title: 移轉至 Express 4 +description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide -lang: zh-tw +redirect_from: " " --- # 移至 Express 4

    概觀

    -Express 4 是對 Express 3 的突破性變更。也就是說,如果您在其相依關係中更新 Express 版本,現有的 Express 3 應用程式將無法運作。 +Express 4 是對 Express 3 的突破性變更。也就是說,如果您在其相依關係中更新 Express 版本,現有的 Express 3 應用程式將無法運作。 That means an existing Express 3 app will _not_ work if you update the Express version in its dependencies. 本文涵蓋: @@ -24,7 +25,7 @@ Express 4 是對 Express 3 的突破性變更。也就是說,如果您在其 Express 4 有數項明顯的變更:
      -
    • Express 核心和中介軟體系統的變更。Connect 和內建中介軟體的相依關係已移除,因此您必須自行新增中介軟體。 +
    • Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
    • 路由系統的變更。
    • 其他各項變更。
    • @@ -32,16 +33,18 @@ Express 4 有數項明顯的變更: 另請參閱: -* [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x) -* [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) +- [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x) +- [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

      Express 核心和中介軟體系統的變更

      -Express 4 不再相依於 Connect,除了 `express.static` 函數,其他所有的內建中介軟體皆已從其核心移除。也就是說,Express 現在是一個獨立的路由與中介軟體 Web 架構,Express 的版本化與版次不受中介軟體更新的影響。 +Express 4 不再相依於 Connect,除了 `express.static` 函數,其他所有的內建中介軟體皆已從其核心移除。也就是說,Express 現在是一個獨立的路由與中介軟體 Web 架構,Express 的版本化與版次不受中介軟體更新的影響。 This means that +Express is now an independent routing and middleware web framework, and +Express versioning and releases are not affected by middleware updates. -由於沒有內建中介軟體,您必須明確新增執行您應用程式所需的所有中介軟體。只需遵循下列步驟: +由於沒有內建中介軟體,您必須明確新增執行您應用程式所需的所有中介軟體。只需遵循下列步驟: Simply follow these steps: 1. 安裝模組:`npm install --save ` 2. 在您的應用程式中,需要模組:`require('module-name')` @@ -50,7 +53,7 @@ Express 4 不再相依於 Connect,除了 `express.static` 函數,其他所 下表列出 Express 3 中介軟體和其在 Express 4 中的對應項目。 - + @@ -82,25 +85,26 @@ Express 4 不再相依於 Connect,除了 `express.static` 函數,其他所 -
      Express 3Express 4
      Express 3Express 4
      express.bodyParser body-parser + multer
      serve-index
      express.static serve-static
      +
    以下是 Express 4 中介軟體的[完整清單](https://github.com/senchalabs/connect#middleware)。 -在大部分情況下,只需將舊有第 3 版中介軟體取代為其 Express 4 對應項目。如需詳細資料,請參閱 GitHub 中的模組說明文件。 +In most cases, you can simply replace the old version 3 middleware with +its Express 4 counterpart. For details, see the module documentation in +GitHub.

    app.use 接受參數

    -在第 4 版中,您可以使用變數參數,來定義中介軟體函數的載入路徑,然後從路由處理程式讀取參數值。例如: +In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler. +For example: +```js +app.use('/book/:id', (req, res, next) => { + console.log('ID:', req.params.id) + next() +}) +``` -
    -
    -app.use('/book/:id', function(req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -});
    -
    -

    路由系統

    @@ -110,72 +114,72 @@ Apps 現在隱含地載入了路由中介軟體,因此您不用再擔心該中 路由的定義方式不變,但是路由系統多了兩個新特性,可協助您組織路由: {: .doclist } -* 新方法 `app.route()`,用來為路由路徑建立可鏈接的路由處理程式。 -* 新類別 `express.Router`,用來建立可裝載的模組路由處理程式。 + +- 新方法 `app.route()`,用來為路由路徑建立可鏈接的路由處理程式。 +- 新類別 `express.Router`,用來建立可裝載的模組路由處理程式。

    app.route() 方法

    -新的 `app.route()` 方法可讓您為路由路徑建立可鏈接的路由處理程式。由於是在單一位置指定路徑,建立模組路由很有用,因為它可減少冗餘和打錯字的情況。如需路由的相關資訊,請參閱 [`Router()` 說明文件](/{{ page.lang }}/4x/api.html#router)。 +新的 `app.route()` 方法可讓您為路由路徑建立可鏈接的路由處理程式。由於是在單一位置指定路徑,建立模組路由很有用,因為它可減少冗餘和打錯字的情況。如需路由的相關資訊,請參閱 [`Router()` 說明文件](/{{ page.lang }}/4x/api.html#router)。 Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more +information about routes, see [`Router()` documentation](/{{ page.lang }}/4x/api.html#router). 下列範例顯示利用 `app.route()` 函數所定義的路由處理程式鏈。 -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
    +  })
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .put((req, res) => {
    +    res.send('Update the book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    +```

    express.Router 類別

    -有助於組織路由的另一項特性是一個新類別 `express.Router`,可用來建立可裝載的模組路由處理程式。`Router` 實例是一個完整的中介軟體與路由系統; -因此,常被稱為「迷你應用程式」。 +The other feature that helps to organize routes is a new class, +`express.Router`, that you can use 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". 下列範例是將路由器建立成模組、 在其中載入中介軟體、定義一些路由,並將它裝載在主要應用程式中的路徑。 例如,在應用程式目錄中建立一個名為 `birds.js` 的路由器檔案,內含下列內容: -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +var express = require('express')
    +var router = express.Router()
     
     // middleware specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +})
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` 然後將路由器模組載入應用程式中: -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +var birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` 現在,應用程式就能夠處理發給 `/birds` 和 `/birds/about` 路徑的要求,並且會呼叫該路由特定的 `timeLog` 中介軟體。 @@ -186,9 +190,9 @@ app.use('/birds', birds); 下表列出 Express 4 其他小幅卻很重要的變更: - - - + + + @@ -199,7 +203,10 @@ app.use('/birds', birds); `http.createServer()` @@ -207,7 +214,9 @@ app.use('/birds', birds); `app.configure()` @@ -238,7 +247,7 @@ Express 4 中依預設會停用 `json spaces` 應用程式內容。 `req.params` @@ -246,7 +255,7 @@ Express 4 中依預設會停用 `json spaces` 應用程式內容。 `res.locals` @@ -286,15 +295,18 @@ Express 4 中依預設會停用 `json spaces` 應用程式內容。 `res.setHeader('Set-Cookie', val)` -
    物件說明
    ObjectDescription
    Node.js + 不再需要 `http` 模組,除非您需要直接使用它 (socket.io/SPDY/HTTPS)。應用程式可藉由使用 `app.listen()` 函數來啟動。 + The app can be started by using the +`app.listen()` function.
    +The `app.configure()` function has been removed. `app.configure()` 函數已移除。請使用 `process.env.NODE_ENV` 或 `app.get('env')` 函數來偵測環境,並據以配置應用程式。 +
    -之前是陣列;現在是物件。 +Was an array; now an object.
    -之前是函數;現在是物件。 +Was a function; now an object.
    +Functionality is now limited to setting the basic cookie value. 現在功能僅限於設定基本 Cookie 值。請使用 `res.cookie()` 來取得新增的功能。 +
    +

    應用程式移轉範例

    下列範例顯示如何將 Express 3 應用程式移轉至 Express 4。值得一提的檔案是 `app.js` 和 `package.json`。 +The files of interest are `app.js` and `package.json`.

    第 3 版應用程式 @@ -304,48 +316,45 @@ Express 4 中依預設會停用 `json spaces` 應用程式內容。 假設 Express 第 3 版應用程式具有下列的 `app.js` 檔: -
    -
    -var express = require('express');
    -var routes = require('./routes');
    -var user = require('./routes/user');
    -var http = require('http');
    -var path = require('path');
    +```js
    +var express = require('express')
    +var routes = require('./routes')
    +var user = require('./routes/user')
    +var http = require('http')
    +var path = require('path')
     
    -var app = express();
    +var app = express()
     
     // all environments
    -app.set('port', process.env.PORT || 3000);
    -app.set('views', path.join(__dirname, 'views'));
    -app.set('view engine', 'pug');
    -app.use(express.favicon());
    -app.use(express.logger('dev'));
    -app.use(express.methodOverride());
    -app.use(express.session({ secret: 'your secret here' }));
    -app.use(express.bodyParser());
    -app.use(app.router);
    -app.use(express.static(path.join(__dirname, 'public')));
    +app.set('port', process.env.PORT || 3000)
    +app.set('views', path.join(__dirname, 'views'))
    +app.set('view engine', 'pug')
    +app.use(express.favicon())
    +app.use(express.logger('dev'))
    +app.use(express.methodOverride())
    +app.use(express.session({ secret: 'your secret here' }))
    +app.use(express.bodyParser())
    +app.use(app.router)
    +app.use(express.static(path.join(__dirname, 'public')))
     
     // development only
    -if ('development' == app.get('env')) {
    -  app.use(express.errorHandler());
    +if (app.get('env') === 'development') {
    +  app.use(express.errorHandler())
     }
     
    -app.get('/', routes.index);
    -app.get('/users', user.list);
    +app.get('/', routes.index)
    +app.get('/users', user.list)
     
    -http.createServer(app).listen(app.get('port'), function(){
    -  console.log('Express server listening on port ' + app.get('port'));
    -});
    -
    -
    +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```

    package.json

    附帶的第 3 版 `package.json` 檔可能類似如下: -
    -
    +```json
     {
       "name": "application-name",
       "version": "0.0.1",
    @@ -358,8 +367,7 @@ http.createServer(app).listen(app.get('port'), function(){
         "pug": "*"
       }
     }
    -
    -
    +```

    程序 @@ -367,20 +375,20 @@ http.createServer(app).listen(app.get('port'), function(){ 開始移轉程序,作法是使用下列指令,為 Express 4 應用程式安裝必要的中介軟體,並將 Express 和 Pug 更新為其個別的最新版本: -
    -
    +```bash
     $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
    -
    -
    +``` 對 `app.js` 進行下列變更: 1. `express` 物件中不再提供內建 Express 中介軟體函數 -`express.favicon`、`express.logger`, `express.methodOverride`、`express.session`、`express.bodyParser` 和 `express.errorHandler`。您必須手動安裝其替代項目,並將它們載入到應用程式。 + `express.favicon`、`express.logger`, `express.methodOverride`、`express.session`、`express.bodyParser` 和 `express.errorHandler`。您必須手動安裝其替代項目,並將它們載入到應用程式。 You must install their alternatives + manually and load them in the app. -2. 不再需要載入 `app.router` 函數。它不是有效的 Express 4 應用程式物件,因此請移除 `app.use(app.router);` 程式碼。 +2. You no longer need to load the `app.router` function. + 不再需要載入 `app.router` 函數。它不是有效的 Express 4 應用程式物件,因此請移除 `app.use(app.router);` 程式碼。 -3. 請確定中介軟體函數的載入順序正確 - 載入應用程式路由之後,再載入 `errorHandler`。 +3. Make sure that the middleware functions are loaded in the correct order - load `errorHandler` after loading the app routes.

    第 4 版應用程式

    @@ -388,8 +396,7 @@ $ npm install serve-favicon morgan method-override express-session body-parser m 執行上述 `npm` 指令,將會更新 `package.json`,如下所示: -
    -
    +```json
     {
       "name": "application-name",
       "version": "0.0.1",
    @@ -402,86 +409,87 @@ $ npm install serve-favicon morgan method-override express-session body-parser m
         "errorhandler": "^1.1.1",
         "express": "^4.8.0",
         "express-session": "^1.7.2",
    -    "pug": "^2.0.0-beta6",
    +    "pug": "^2.0.0",
         "method-override": "^2.1.2",
         "morgan": "^1.2.2",
         "multer": "^0.1.3",
         "serve-favicon": "^2.0.1"
       }
     }
    -
    -
    +```

    app.js

    -然後移除無效的程式碼、載入必要的中介軟體,並視需要進行其他的變更。`app.js` 檔看似如下: +Then, remove invalid code, load the required middleware, and make other +changes as necessary. The `app.js` file will look like this: -
    -
    -var http = require('http');
    -var express = require('express');
    -var routes = require('./routes');
    -var user = require('./routes/user');
    -var path = require('path');
    +```js
    +var http = require('http')
    +var express = require('express')
    +var routes = require('./routes')
    +var user = require('./routes/user')
    +var path = require('path')
     
    -var favicon = require('serve-favicon');
    -var logger = require('morgan');
    -var methodOverride = require('method-override');
    -var session = require('express-session');
    -var bodyParser = require('body-parser');
    -var multer = require('multer');
    -var errorHandler = require('errorhandler');
    +var favicon = require('serve-favicon')
    +var logger = require('morgan')
    +var methodOverride = require('method-override')
    +var session = require('express-session')
    +var bodyParser = require('body-parser')
    +var multer = require('multer')
    +var errorHandler = require('errorhandler')
     
    -var app = express();
    +var app = express()
     
     // all environments
    -app.set('port', process.env.PORT || 3000);
    -app.set('views', path.join(__dirname, 'views'));
    -app.set('view engine', 'pug');
    -app.use(favicon(__dirname + '/public/favicon.ico'));
    -app.use(logger('dev'));
    -app.use(methodOverride());
    -app.use(session({ resave: true,
    -                  saveUninitialized: true,
    -                  secret: 'uwotm8' }));
    -app.use(bodyParser.json());
    -app.use(bodyParser.urlencoded({ extended: true }));
    -app.use(multer());
    -app.use(express.static(path.join(__dirname, 'public')));
    -
    -app.get('/', routes.index);
    -app.get('/users', user.list);
    +app.set('port', process.env.PORT || 3000)
    +app.set('views', path.join(__dirname, 'views'))
    +app.set('view engine', 'pug')
    +app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
    +app.use(logger('dev'))
    +app.use(methodOverride())
    +app.use(session({
    +  resave: true,
    +  saveUninitialized: true,
    +  secret: 'uwotm8'
    +}))
    +app.use(bodyParser.json())
    +app.use(bodyParser.urlencoded({ extended: true }))
    +app.use(multer())
    +app.use(express.static(path.join(__dirname, 'public')))
    +
    +app.get('/', routes.index)
    +app.get('/users', user.list)
     
     // error handling middleware should be loaded after the loading the routes
    -if ('development' == app.get('env')) {
    -  app.use(errorHandler());
    +if (app.get('env') === 'development') {
    +  app.use(errorHandler())
     }
     
    -var server = http.createServer(app);
    -server.listen(app.get('port'), function(){
    -  console.log('Express server listening on port ' + app.get('port'));
    -});
    -
    -
    +var server = http.createServer(app) +server.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +```
    除非您需要直接使用 `http` 模組 (socket.io/SPDY/HTTPS),並不需要載入它,只需採下列方式就能啟動應用程式: -
    -app.listen(app.get('port'), function(){
    -  console.log('Express server listening on port ' + app.get('port'));
    -});
    -
    + +```js +app.listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')) +}) +``` +
    -

    執行應用程式

    +

    Run the app

    -移轉程序已完成,現在應用程式是一個 Express 4 應用程式。若要確認,請使用下列指令來啟動應用程式: +The migration process is complete, and the app is now an +Express 4 app. To confirm, start the app by using the following command: -
    -
    +```bash
     $ node .
    -
    -
    +``` 載入 [http://localhost:3000](http://localhost:3000),並查看 Express 4 所呈現的首頁。 @@ -493,43 +501,39 @@ $ node . 如果您的系統已安裝 Express 3 應用程式產生器,必須解除安裝它: -
    -
    +```bash
     $ npm uninstall -g express
    -
    -
    +``` + 視您如何配置檔案與目錄專用權而定,您可能需要使用 `sudo` 來執行這個指令。 現在安裝新的產生器: -
    -
    +```bash
     $ npm install -g express-generator
    -
    -
    +``` 視您如何配置檔案與目錄專用權而定,您可能需要使用 `sudo` 來執行這個指令。 現在,您系統上的 `express` 指令已更新為 Express 4 產生器。 -

    應用程式產生器的變更

    +

    Changes to the app generator

    除了以下,指令的選項與用法大致不變: {: .doclist } -* 已移除 `--sessions` 選項。 -* 已移除 `--jshtml` 選項。 -* 新增了 `--hogan` 選項,以支援 [Hogan.js](http://twitter.github.io/hogan.js/)。 + +- 已移除 `--sessions` 選項。 +- 已移除 `--jshtml` 選項。 +- 新增了 `--hogan` 選項,以支援 [Hogan.js](http://twitter.github.io/hogan.js/)。

    範例

    執行下列指令,以建立 Express 4 應用程式: -
    -
    +```bash
     $ express app4
    -
    -
    +``` 如果您查看 `app4/app.js` 檔的內容,您會發現應用程式所需要的所有中介軟體函數(但不包括 `express.static`)都載入成獨立模組,且 `router` 中介軟體不再明確載入到應用程式中。 @@ -537,39 +541,39 @@ $ express app4 安裝相依關係之後,請使用下列指令來啟動應用程式: -
    -
    +```bash
     $ npm start
    -
    -
    +``` 如果您查看 `package.json` 檔中的 npm 啟動 Script,您會發現,啟動應用程式的實際指令是 `node ./bin/www`,這在 Express 3 中是 `node app.js`。 -由於 Express 4 產生器產生的 `app.js` 檔現在是一個 Node.js 模組,因此無法再以應用程式形式單獨啟動它(除非您修改程式碼)。模組必須載入到 Node.js 檔,並透過 Node.js 檔啟動。在本例中,Node.js 檔是 `./bin/www`。 +由於 Express 4 產生器產生的 `app.js` 檔現在是一個 Node.js 模組,因此無法再以應用程式形式單獨啟動它(除非您修改程式碼)。模組必須載入到 Node.js 檔,並透過 Node.js 檔啟動。在本例中,Node.js 檔是 `./bin/www`。 The module must be loaded in a Node.js file +and started via the Node.js file. The Node.js file is `./bin/www` +in this case. -在建立 Express 應用程式或啟動應用程式時,`bin` 目錄和沒有副檔名 -`www` 的檔案都不是必要的。它們只是產生器所建議的,您大可根據自己的需求來修改它們。 +Neither the `bin` directory nor the extensionless `www` +file is mandatory for creating an Express app or starting the app. They are +just suggestions made by the generator, so feel free to modify them to suit your +needs. 若要除去 `www` 目錄,並採用「Express 3 形式」,請刪除 `app.js` 檔尾端的 `module.exports = app;` 字行,然後在該處貼上下列程式碼: -
    -
    -app.set('port', process.env.PORT || 3000);
    +```js
    +app.set('port', process.env.PORT || 3000)
     
    -var server = app.listen(app.get('port'), function() {
    -  debug('Express server listening on port ' + server.address().port);
    -});
    -
    -
    +var server = app.listen(app.get('port'), () => { + debug('Express server listening on port ' + server.address().port) +}) +``` 請使用下列程式碼,確定 `debug` 模組是載入於 `app.js` 檔頂端: -
    -
    -var debug = require('debug')('app4');
    -
    -
    +```js +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` 檔不再自行啟動的原因。 This change is not recommended, but the exercise helps you +to understand how the `./bin/www` file works, and why the `app.js` file +no longer starts on its own. diff --git a/zh-tw/guide/migrating-5.md b/zh-tw/guide/migrating-5.md old mode 100755 new mode 100644 index 1a5b9cbbd0..2623985e81 --- a/zh-tw/guide/migrating-5.md +++ b/zh-tw/guide/migrating-5.md @@ -1,31 +1,44 @@ --- layout: page title: 移轉至 Express 5 +description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide -lang: zh-tw +redirect_from: " " --- # 移至 Express 5

    概觀

    -Express 5.0 尚在 Alpha 版階段,這裡讓您預覽版本中的變更以及如何將 Express 4 應用程式移轉至 Express 5。 +Express 5 與 Express 4 之間差異不大:API 的變更不會像從 3.0 至 4.0 那樣顯著。雖然基本 API 維持相同,仍有一些突破性變更;換句話說,如果您更新成使用 Express 5,現有 Express 4 程式可能無法運作。 Therefore, an application built with Express 4 might not work if you update it to use Express 5. -Express 5 與 Express 4 之間差異不大:API 的變更不會像從 3.0 至 4.0 那樣顯著。雖然基本 API 維持相同,仍有一些突破性變更;換句話說,如果您更新成使用 Express 5,現有 Express 4 程式可能無法運作。 +To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory: -如果要安裝最新的 Alpha 版並預覽 Express 5,請在您應用程式根目錄中輸入下列指令: +```sh +npm install "express@5" +``` -
    -
    -$ npm install express@5.0.0-alpha.2 --save
    -
    -
    +然後您可以執行自動化測試,查看失敗之處,並根據下方列出的更新項目來修正問題。解決測試失敗之後,請執行您的應用程式,查看發生哪些錯誤。只要應用程式使用任何不支援的方法或內容,您會馬上發現。 After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported. -然後您可以執行自動化測試,查看失敗之處,並根據下方列出的更新項目來修正問題。解決測試失敗之後,請執行您的應用程式,查看發生哪些錯誤。只要應用程式使用任何不支援的方法或內容,您會馬上發現。 +## Express 5 Codemods -

    Express 5 中的變更

    +To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. + +Run the following command for run all the codemods available: + +```sh +npx @expressjs/codemod upgrade +``` + +If you want to run a specific codemod, you can run the following command: -這裡列出將會影響您(作為 Express 使用者)的變更(起自 Alpha 2 版)。如需所有規劃的特性清單,請參閱 [pull request](https://github.com/expressjs/express/pull/2237)。 +```sh +npx @expressjs/codemod name-of-the-codemod +``` + +You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods). + +

    Express 5 中的變更

    **已移除的方法和內容** @@ -33,101 +46,503 @@ $ npm install express@5.0.0-alpha.2 --save
  • app.del()
  • app.param(fn)
  • 複數化的方法名稱
  • -
  • app.param(name, fn) 名稱引數中的前導冒號
  • +
  • Leading colon in name argument to app.param(name, fn)
  • req.param(name)
  • res.json(obj, status)
  • res.jsonp(obj, status)
  • +
  • res.redirect('back') and res.location('back')
  • +
  • res.redirect(url, status)
  • res.send(body, status)
  • res.send(status)
  • res.sendfile()
  • +
  • router.param(fn)
  • +
  • express.static.mime
  • +
  • express:router debug logs
  • -**已變更** +**改良** -**改良** +**已變更** -

    已移除的方法和內容

    +## 已移除的方法和內容 + +If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5. + +

    app.del()

    + +Express 5 no longer supports the `app.del()` function. If you use this function, an error is thrown. For registering HTTP DELETE routes, use the `app.delete()` function instead. -如果您在應用程式中使用上述任何方法或內容,應用程式將會當機。因此,更新至第 5 版之後,您需要變更應用程式。 +最初是使用 `del` 而非 `delete`,因為 `delete` 是 JavaScript 中的保留關鍵字。不過,從 ECMAScript 6 起,`delete` 和其他保留關鍵字可以合法作為內容名稱。您可以在這裡閱讀導致淘汰 `app.del` 函數的相關討論。 However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. -

    app.del()

    +{% capture codemod-deprecated-signatures %} +You can replace the deprecated signatures with the following command: -Express 5 不再支援 `app.del()` 函數。如果您使用此函數,會擲出錯誤。若要登錄 HTTP DELETE 路由,請改用 `app.delete()` 函數。 +```plain-text +npx @expressjs/codemod v4-deprecated-signatures +``` -最初是使用 `del` 而非 `delete`,因為 `delete` 是 JavaScript 中的保留關鍵字。不過,從 ECMAScript 6 起,`delete` 和其他保留關鍵字可以合法作為內容名稱。您可以在這裡閱讀導致淘汰 `app.del` 函數的相關討論。 +{% endcapture %} -

    app.param(fn)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} -`app.param(fn)` 簽章用來修改 `app.param(name, fn)` 函數的行為。從 4.11.0 版起就已淘汰,Express 5 已全然不再支援。 +```js +// v4 +app.del('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) -

    複數化的方法名稱

    +// v5 +app.delete('/user/:id', (req, res) => { + res.send(`DELETE /user/${req.params.id}`) +}) +``` -下列方法名稱已複數化。在 Express 4 中,使用舊方法會引發淘汰警告。Express 5 已全然不再支援: +

    app.param(fn)

    + +The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. + +

    Pluralized method names

    + +The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all: + +`req.acceptsLanguage()` 以 `req.acceptsLanguages()` 取代。 `req.acceptsCharset()` 以 `req.acceptsCharsets()` 取代。 `req.acceptsEncoding()` 以 `req.acceptsEncodings()` 取代。 -`req.acceptsLanguage()` 以 `req.acceptsLanguages()` 取代。 +{% capture codemod-pluralized-methods %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod pluralized-methods +``` + +{% endcapture %} -

    app.param(name, fn) 名稱中的前導冒號 (:)

    +{% include admonitions/note.html content=codemod-pluralized-methods %} -`app.param(name, fn)` 函數名稱中的前導冒號字元 (:) 遺留自 Express 3,基於舊版相容性,Express 4 仍支援它,只是會發出淘汰警示。Express 5 會無聲自動忽略它,並使用少了冒號字首的名稱參數。 +```js +// v4 +app.all('/', (req, res) => { + req.acceptsCharset('utf-8') + req.acceptsEncoding('br') + req.acceptsLanguage('en') + + // ... +}) + +// v5 +app.all('/', (req, res) => { + req.acceptsCharsets('utf-8') + req.acceptsEncodings('br') + req.acceptsLanguages('en') + + // ... +}) +``` + +

    app.param(name, fn) 名稱中的前導冒號 (:)

    + +`app.param(name, fn)` 函數名稱中的前導冒號字元 (:) 遺留自 Express 3,基於舊版相容性,Express 4 仍支援它,只是會發出淘汰警示。Express 5 會無聲自動忽略它,並使用少了冒號字首的名稱參數。 Express 5 will silently ignore it and use the name parameter without prefixing it with a colon. 如果您遵循 Express 4 [app.param](/{{ page.lang }}/4x/api.html#app.param) 說明文件,應該不會影響您的程式碼,因為該說明文件不會提及前導冒號。 -

    req.param(name)

    +

    req.param(name)

    + +This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object. + +{% capture codemod-req-param %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod req-param +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-req-param %} + +```js +// v4 +app.post('/user', (req, res) => { + const id = req.param('id') + const body = req.param('body') + const query = req.param('query') + + // ... +}) + +// v5 +app.post('/user', (req, res) => { + const id = req.params.id + const body = req.body + const query = req.query + + // ... +}) +``` + +

    res.json(obj, status)

    + +Express 5 不再支援 `res.json(obj, status)` 簽章。請改以設定狀態,然後與 `res.json()` 方法鏈接,如下所示:`res.status(status).json(obj)`。 Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.json({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).json({ name: 'Ruben' }) +}) +``` + +

    res.jsonp(obj, status)

    + +Express 5 不再支援 `res.jsonp(obj, status)` 簽章。請改以設定狀態,然後與 `res.jsonp()` 方法鏈接,如下所示:`res.status(status).jsonp(obj)`。 Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.post('/user', (req, res) => { + res.jsonp({ name: 'Ruben' }, 201) +}) + +// v5 +app.post('/user', (req, res) => { + res.status(201).jsonp({ name: 'Ruben' }) +}) +``` + +

    res.redirect(url, status)

    + +Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`. + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('/users', 301) +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(301, '/users') +}) +``` + +

    res.redirect('back') and res.location('back')

    + +Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated. + +{% capture codemod-magic-redirect %} +You can replace the deprecated signatures with the following command: + +```plain-text +npx @expressjs/codemod magic-redirect +``` + +{% endcapture %} + +{% include admonitions/note.html content=codemod-magic-redirect %} + +```js +// v4 +app.get('/user', (req, res) => { + res.redirect('back') +}) + +// v5 +app.get('/user', (req, res) => { + res.redirect(req.get('Referrer') || '/') +}) +``` -這個用來擷取表單資料的方法因可能造成混淆且招致危險,而已經移除。現在您需要明確尋找 `req.params`、`req.body` 或 `req.query` 物件中所提交的參數名稱。 +

    res.send(body, status)

    -

    res.json(obj, status)

    +Express 5 不再支援 `res.send(obj, status)` 簽章。請改以設定狀態,然後與 `res.send()` 方法鏈接,如下所示:`res.status(status).send(obj)`。 Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`. -Express 5 不再支援 `res.json(obj, status)` 簽章。請改以設定狀態,然後與 `res.json()` 方法鏈接,如下所示:`res.status(status).json(obj)`。 +{% include admonitions/note.html content=codemod-deprecated-signatures %} -

    res.jsonp(obj, status)

    +```js +// v4 +app.get('/user', (req, res) => { + res.send({ name: 'Ruben' }, 200) +}) -Express 5 不再支援 `res.jsonp(obj, status)` 簽章。請改以設定狀態,然後與 `res.jsonp()` 方法鏈接,如下所示:`res.status(status).jsonp(obj)`。 +// v5 +app.get('/user', (req, res) => { + res.status(200).send({ name: 'Ruben' }) +}) +``` -

    res.send(body, status)

    +

    res.send(status)

    -Express 5 不再支援 `res.send(obj, status)` 簽章。請改以設定狀態,然後與 `res.send()` 方法鏈接,如下所示:`res.status(status).send(obj)`。 +Express 5 不再支援 res.send(status) 簽章,其中 _`status`_ 是數字。請改用 `res.sendStatus(statusCode)` 函數,此函數是設定 HTTP 回應標頭狀態碼,並傳送文字版的程式碼:「找不到」、「內部伺服器錯誤」等。 +如果您需要使用 `res.send()` 函數來傳送數字,請將數字括上引號來轉換成字串,這樣 Express 就不會解譯它以試圖使用不支援的舊簽章。 Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on. +If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature. -

    res.send(status)

    +{% include admonitions/note.html content=codemod-deprecated-signatures %} -Express 5 不再支援 res.send(status) 簽章,其中 *`status`* 是數字。請改用 `res.sendStatus(statusCode)` 函數,此函數是設定 HTTP 回應標頭狀態碼,並傳送文字版的程式碼:「找不到」、「內部伺服器錯誤」等。 -如果您需要使用 `res.send()` 函數來傳送數字,請將數字括上引號來轉換成字串,這樣 Express 就不會解譯它以試圖使用不支援的舊簽章。 +```js +// v4 +app.get('/user', (req, res) => { + res.send(200) +}) -

    res.sendfile()

    +// v5 +app.get('/user', (req, res) => { + res.sendStatus(200) +}) +``` + +

    res.sendfile()

    `res.sendfile()` 函數已被 Express 5 中的駝峰式大小寫版本 `res.sendFile()` 取代。 -

    已變更

    +**Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: + +- JavaScript files (.js): now "text/javascript" instead of "application/javascript" +- JSON files (.json): now "application/json" instead of "text/json" +- CSS files (.css): now "text/css" instead of "text/plain" +- XML files (.xml): now "application/xml" instead of "text/xml" +- Font files (.woff): now "font/woff" instead of "application/font-woff" +- SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" + +{% include admonitions/note.html content=codemod-deprecated-signatures %} + +```js +// v4 +app.get('/user', (req, res) => { + res.sendfile('/path/to/file') +}) + +// v5 +app.get('/user', (req, res) => { + res.sendFile('/path/to/file') +}) +``` + +

    router.param(fn)

    + +The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all. + +

    express.static.mime

    + +In Express 5, `mime` is no longer an exported property of the `static` field. +Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. + +**Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: + +- JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" +- JSON files (.json): now served as "application/json" instead of "text/json" +- CSS files (.css): now served as "text/css" instead of "text/plain" +- HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" +- XML files (.xml): now served as "application/xml" instead of "text/xml" +- Font files (.woff): now served as "font/woff" instead of "application/font-woff" + +```js +// v4 +express.static.mime.lookup('json') + +// v5 +const mime = require('mime-types') +mime.lookup('json') +``` + +

    express:router debug logs

    + +In Express 5, router handling logic is performed by a dependency. Therefore, the +debug logs for the router are no longer available under the `express:` namespace. +In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, +and `express:router:route`. All of these were included under the namespace `express:*`. +In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. +The logs from `router:layer` and `router:route` are included in the namespace `router:*`. +To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of +`express:*`, `router`, and `router:*`. + +```sh +# v4 +DEBUG=express:* node index.js + +# v5 +DEBUG=express:*,router,router:* node index.js +``` + +## 已變更 + +

    Path route matching syntax

    + +Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request: + +- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` + +```js +// v4 +app.get('/*', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/*splat', async (req, res) => { + res.send('ok') +}) +``` + +{% capture note_wildcard %} +`*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. + +```js +// v5 +app.get('/{*splat}', async (req, res) => { + res.send('ok') +}) +``` + +{% endcapture %} +{% include admonitions/note.html content=note_wildcard %} + +- The optional character `?` is no longer supported, use braces instead. + +```js +// v4 +app.get('/:file.:ext?', async (req, res) => { + res.send('ok') +}) + +// v5 +app.get('/:file{.:ext}', async (req, res) => { + res.send('ok') +}) +``` + +- Regexp characters are not supported. For example: -

    app.router

    +```js +app.get('/[discussion|page]/:slug', async (req, res) => { + res.status(200).send('ok') +}) +``` + +should be changed to: + +```js +app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { + res.status(200).send('ok') +}) +``` + +- Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. +- Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`. + +

    Rejected promises handled from middleware and handlers

    + +Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an `Error` to the error handling middleware. This means that using `async` functions as middleware and handlers are easier than ever. When an error is thrown in an `async` function or a rejected promise is `await`ed inside an async function, those errors will be passed to the error handler as if calling `next(err)`. + +Details of how Express handles errors is covered in the [error handling documentation](/en/guide/error-handling.html). + +

    express.urlencoded

    + +The `express.urlencoded` method makes the `extended` option `false` by default. + +

    express.static dotfiles

    + +In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. + +Example of breaking code: + +```js +// v4 +app.use(express.static('public')) +``` + +After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. + +To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: + +```js +// v5 +app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) +app.use(express.static('public')) +``` + +This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible. + +

    app.listen

    + +In Express 5, the `app.listen` method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument. +For example: + +```js +const server = app.listen(8080, '0.0.0.0', (error) => { + if (error) { + throw error // e.g. EADDRINUSE + } + console.log(`Listening on ${JSON.stringify(server.address())}`) +}) +``` + +

    app.router

    `app.router` 物件已在 Express 4 中移除,在 Express 5 中又重新納入。 -在新版本中,這個物件只用來參照至基本 Express 路由器,不像在 Express 3 中,應用程式還得明確載入它。 +在新版本中,這個物件只用來參照至基本 Express 路由器,不像在 Express 3 中,應用程式還得明確載入它。 In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. + +

    req.body

    + +The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. + +

    req.host

    -

    req.host

    +In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5, the port number is maintained. -在 Express 4 中,`req.host` 函數會不當去除埠號(如果有的話)。在 Express 5 中,會維護埠號。 +

    req.query

    -

    req.query

    +The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". -在 Express 4.7 以及從 Express 5 開始,當您想使用自己的函數作為查詢字串剖析邏輯時,查詢剖析器選項可以接受 `false` 以停用查詢字串剖析。 +

    res.clearCookie

    -

    改良

    +The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user. -

    res.render()

    +

    res.status

    + +The `res.status` method only accepts integers in the range of `100` to `999`, following the behavior defined by Node.js, and it returns an error when the status code is not an integer. + +

    res.vary

    + +The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console + +## 改良 + +

    res.render()

    此方法現在會針對所有視圖引擎施行非同步行為,可避免採行同步實作及違反建議介面的視圖引擎所造成的錯誤。 + +

    Brotli encoding support

    + +Express 5 supports Brotli encoding for requests received from clients that support it. diff --git a/zh-tw/guide/overriding-express-api.md b/zh-tw/guide/overriding-express-api.md new file mode 100644 index 0000000000..032e3dd625 --- /dev/null +++ b/zh-tw/guide/overriding-express-api.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Overriding the Express API +description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. +menu: guide +--- + +# Overriding the Express API + +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: + +1. The global prototypes at `express.request` and `express.response`. +2. App-specific prototypes at `app.request` and `app.response`. + +Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. + +## Methods + +You can override the signature and behavior of existing methods with your own, by assigning a custom function. + +Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). + +```js +app.response.sendStatus = function (statusCode, type, message) { + // code is intentionally kept simple for demonstration purpose + return this.contentType(type) + .status(statusCode) + .send(message) +} +``` + +The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. + +The overridden method may now be used this way: + +```js +res.sendStatus(404, 'application/json', '{"error":"resource not found"}') +``` + +## Properties + +Properties in the Express API are either: + +1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) +2. Defined as getters (ex: `req.secure`, `req.ip`) + +Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. + +Properties under category 2 can be overwritten using the Express API extensions API. + +The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. + +```js +Object.defineProperty(app.request, 'ip', { + configurable: true, + enumerable: true, + get () { return this.get('Client-IP') } +}) +``` + +## Prototype + +In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. + +Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. + +```js +// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse +// for the given app reference +Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) +Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) +``` diff --git a/zh-tw/guide/routing.md b/zh-tw/guide/routing.md old mode 100755 new mode 100644 index 9269889bc5..ffcdb69d55 --- a/zh-tw/guide/routing.md +++ b/zh-tw/guide/routing.md @@ -1,27 +1,38 @@ --- layout: page title: Express 路由 +description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide -lang: zh-tw +redirect_from: " " --- # 路由 -*路由*是指應用程式端點 (URI) 的定義,以及應用程式如何回應用戶端要求。如需路由簡介,請參閱[基本路由](/{{ page.lang }}/starter/basic-routing.html)。 +_Routing_ refers to how an application's endpoints (URIs) respond to client requests. +For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/basic-routing.html). -下列程式碼範例說明相當基本的路由。 +You define routing using methods of the Express `app` object that correspond to HTTP methods; +for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, +see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to +specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). -
    -
    -var express = require('express');
    -var app = express();
    +These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to 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 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
    +to the next callback.
    +
    +以下是以字串為基礎的部分路由路徑範例。
    +
    +```js
    +const express = require('express')
    +const app = express()
     
     // respond with "hello world" when a GET request is made to the homepage
    -app.get('/', function(req, res) {
    -  res.send('hello world');
    -});
    -
    -
    +app.get('/', (req, res) => { + res.send('hello world') +}) +```

    路由方法

    @@ -29,311 +40,354 @@ app.get('/', function(req, res) { 下列程式碼範例說明對應用程式根目錄提出 GET 和 POST 方法時所定義的路由。 -
    -
    +```js
     // GET method route
    -app.get('/', function (req, res) {
    -  res.send('GET request to the homepage');
    -});
    +app.get('/', (req, res) => {
    +  res.send('GET request to the homepage')
    +})
     
     // POST method route
    -app.post('/', function (req, res) {
    -  res.send('POST request to the homepage');
    -});
    -
    -
    - -Express 支援下列的路由方法,這些方法對應至 HTTP 方法:`get`、 -`post`、`put`、`head`、`delete`、`options`、 -`trace`、`copy`、`lock`、`mkcol`、`move`、`purge`、`propfind`、`proppatch`、`unlock`、`report`、`mkactivity`、`checkout`、`merge`、`m-search`、`notify`、`subscribe`、`unsubscribe`、`patch`、`search`,以及 `connect`。 - -
    -如果要遞送的方法會轉換成無效的 JavaScript 變數名稱,請使用括弧表示法。例如,`app['m-search']('/', function ...` -
    +app.post('/', (req, res) => { + res.send('POST request to the homepage') +}) +``` -`app.all()` 是一個特殊的路由方法,它不是衍生自任何 HTTP 方法。此方法用來在所有要求方法的路徑中載入中介軟體函數。 +Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. +For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). -在下列範例中,不論您使用的是 GET、POST、PUT、DELETE 或 [http 模組](https://nodejs.org/api/http.html#http_http_methods)中支援的其他任何 HTTP 要求方法,都會針對傳給 "/secret" 的要求執行處理程式。 +`app.all()` 是一個特殊的路由方法,它不是衍生自任何 HTTP 方法。此方法用來在所有要求方法的路徑中載入中介軟體函數。 在下列範例中,不論您使用的是 GET、POST、PUT、DELETE 或 [http 模組](https://nodejs.org/api/http.html#http_http_methods)中支援的其他任何 HTTP 要求方法,都會針對傳給 "/secret" 的要求執行處理程式。 -
    -
    -app.all('/secret', function (req, res, next) {
    -  console.log('Accessing the secret section ...');
    -  next(); // pass control to the next handler
    -});
    -
    -
    +```js +app.all('/secret', (req, res, next) => { + console.log('Accessing the secret section ...') + next() // pass control to the next handler +}) +```

    路由路徑

    -當路由路徑配上要求方法時,即定義了發出要求時的目標端點。路由路徑可以是字串、字串型樣或正規表示式。 +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. -
    - Express 使用 [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) 來找出相符的路由路徑;請參閱 path-to-regexp 說明文件,取得可用來定義路由路徑的所有可行方法。[Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) 是一個用來測試 Express 基本路由的方便工具,只不過它不支援型樣相符。 -
    +{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} -
    -查詢字串不是路由路徑的一部分。 -
    +{% include admonitions/caution.html content=caution-character %} -以下是以字串為基礎的部分路由路徑範例。 +{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. +{% endcapture %} + +{% include admonitions/caution.html content=note-dollar-character %} + +{% capture note-path-to-regexp %} + +Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [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. + +{% endcapture %} -此路由路徑將符合傳送給根路由 `/` 的要求。 +{% include admonitions/note.html content=note-path-to-regexp %} -
    -
    -app.get('/', function (req, res) {
    -  res.send('root');
    -});
    -
    -
    +{% capture query-string-note %} -此路由路徑將符合傳送給 `/about` 的要求。 +Query strings are not part of the route path. -
    -
    -app.get('/about', function (req, res) {
    -  res.send('about');
    -});
    -
    -
    +{% endcapture %} + +{% include admonitions/warning.html content=query-string-note %} + +### Route paths based on strings + +This route path will match requests to the root route, `/`. + +```js +app.get('/', (req, res) => { + res.send('root') +}) +``` + +This route path will match requests to `/about`. + +```js +app.get('/about', (req, res) => { + res.send('about') +}) +``` 此路由路徑將符合傳送給 `/random.text` 的要求。 -
    -
    -app.get('/random.text', function (req, res) {
    -  res.send('random.text');
    -});
    -
    -
    +```js +app.get('/random.text', (req, res) => { + res.send('random.text') +}) +``` -以下是以字串型樣為基礎的部分路由路徑範例。 +### Route paths based on string patterns + +{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} + +{% include admonitions/caution.html content=caution-string-patterns %} 此路由路徑將符合 `acd` 和 `abcd`。 -
    -
    -app.get('/ab?cd', function(req, res) {
    -  res.send('ab?cd');
    -});
    -
    -
    +```js +app.get('/ab?cd', (req, res) => { + res.send('ab?cd') +}) +``` 此路由路徑將符合 `abcd`、`abbcd`、`abbbcd` 等。 -
    -
    -app.get('/ab+cd', function(req, res) {
    -  res.send('ab+cd');
    -});
    -
    -
    +```js +app.get('/ab+cd', (req, res) => { + res.send('ab+cd') +}) +``` 此路由路徑將符合 `abcd`、`abxcd`、`abRABDOMcd`、`ab123cd` 等。 -
    -
    -app.get('/ab*cd', function(req, res) {
    -  res.send('ab*cd');
    -});
    -
    -
    +```js +app.get('/ab*cd', (req, res) => { + res.send('ab*cd') +}) +``` 此路由路徑將符合 `/abe` 和 `/abcde`。 -
    -
    -app.get('/ab(cd)?e', function(req, res) {
    - res.send('ab(cd)?e');
    -});
    -
    -
    +```js +app.get('/ab(cd)?e', (req, res) => { + res.send('ab(cd)?e') +}) +``` + +### 以正規表示式為基礎的路由路徑範例: -
    - ?、+、* 和 () 字元是其正規表示式對應項目的一部分。以字串為基礎的路徑會照字面來解譯連字符號 (-) 和句點 (.)。 +This route path will match anything with an "a" in it. + +```js +app.get(/a/, (req, res) => { + res.send('/a/') +}) +``` + +此路由路徑將符合 `butterfly` 和 `dragonfly`,但不符合 `butterflyman`、`dragonfly man` 等。 + +```js +app.get(/.*fly$/, (req, res) => { + res.send('/.*fly$/') +}) +``` + +

    當路由路徑配上要求方法時,即定義了發出要求時的目標端點。路由路徑可以是字串、字串型樣或正規表示式。

    + +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 path: /users/:userId/books/:bookId +Request URL: http://localhost:3000/users/34/books/8989 +req.params: { "userId": "34", "bookId": "8989" } +``` + +To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. + +```js +app.get('/users/:userId/books/:bookId', (req, res) => { + res.send(req.params) +}) +``` + +
    +The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
    -以正規表示式為基礎的路由路徑範例: +Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. -只要路由名稱中有 "a",都與這個路由路徑相符。 +``` +Route path: /flights/:from-:to +Request URL: http://localhost:3000/flights/LAX-SFO +req.params: { "from": "LAX", "to": "SFO" } +``` -
    -
    -app.get(/a/, function(req, res) {
    -  res.send('/a/');
    -});
    -
    -
    +``` +Route path: /plantae/:genus.:species +Request URL: http://localhost:3000/plantae/Prunus.persica +req.params: { "genus": "Prunus", "species": "persica" } +``` -此路由路徑將符合 `butterfly` 和 `dragonfly`,但不符合 `butterflyman`、`dragonfly man` 等。 +{% capture warning-regexp %} +In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} -
    -
    -app.get(/.*fly$/, function(req, res) {
    -  res.send('/.*fly$/');
    -});
    -
    -
    +{% include admonitions/caution.html content=warning-regexp %} -

    路由處理程式

    +To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): -您可以提供其行為類似[中介軟體](/{{ page.lang }}/guide/using-middleware.html)的多個回呼函數,以處理要求。唯一的例外情況是這些回呼可能會呼叫 -`next('route')`,來略過其餘的路由回呼。如果沒有理由繼續處理現行路由,您可以使用這項機制,在路由中強制施行前置條件,然後將控制權傳遞給後續的路由。 +``` +Route path: /user/:userId(\d+) +Request URL: http://localhost:3000/user/42 +req.params: {"userId": "42"} +``` -路由處理程式的形式可以是一個函數、函數陣列,或上述兩種的組合,如下列範例所示。 +{% capture escape-advisory %} -單一回呼函數可以處理路由。例如: +Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. +{% endcapture %} -
    -
    -app.get('/example/a', function (req, res) {
    -  res.send('Hello from A!');
    -});
    -
    -
    +{% include admonitions/warning.html content=escape-advisory %} -多個回呼函數可以處理路由(請確定您有指定 `next` 物件)。例如: +{% capture warning-version %} +In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. -
    -
    -app.get('/example/b', function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from B!');
    -});
    -
    -
    +{% endcapture %} -回呼函數陣列可以處理路由。例如: +{% include admonitions/warning.html content=warning-version %} +

    Route handlers

    -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    -}
    +You can provide multiple callback functions that behave like [middleware](/{{ page.lang }}/guide/using-middleware.html) 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.
    +
    +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
    +app.get('/example/a', (req, res) => {
    +  res.send('Hello from A!')
    +})
    +```
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +More than one callback function can handle a route (make sure you specify the `next` object). For example:
    +
    +```js
    +app.get('/example/b', (req, res, next) => {
    +  console.log('the response will be sent by the next function ...')
    +  next()
    +}, (req, res) => {
    +  res.send('Hello from B!')
    +})
    +```
    +
    +An array of callback functions can handle a route. For example:
    +
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb2 = function (req, res) {
    -  res.send('Hello from C!');
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/c', [cb0, cb1, cb2]);
    -
    -
    +const cb2 = function (req, res) { + res.send('Hello from C!') +} -獨立函數與函數陣列的組合可以處理路由。例如: +app.get('/example/c', [cb0, cb1, cb2]) +``` +A combination of independent functions and arrays of functions can handle a route. For example: -
    -
    -var cb0 = function (req, res, next) {
    -  console.log('CB0');
    -  next();
    +```js
    +const cb0 = function (req, res, next) {
    +  console.log('CB0')
    +  next()
     }
     
    -var cb1 = function (req, res, next) {
    -  console.log('CB1');
    -  next();
    +const cb1 = function (req, res, next) {
    +  console.log('CB1')
    +  next()
     }
     
    -app.get('/example/d', [cb0, cb1], function (req, res, next) {
    -  console.log('the response will be sent by the next function ...');
    -  next();
    -}, function (req, res) {
    -  res.send('Hello from D!');
    -});
    -
    -
    +app.get('/example/d', [cb0, cb1], (req, res, next) => { + console.log('the response will be sent by the next function ...') + next() +}, (req, res) => { + res.send('Hello from D!') +}) +```

    回應方法

    -在下表中,回應物件 (`res`) 中的方法可以傳送回應給用戶端,並終止要求/回應循環。如果路由處理程式都沒有呼叫這些方法,用戶端要求將會停擺。 +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. -| 方法 | 說明 -|----------------------|-------------------------------------- -| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | 提示您提供要下載的檔案。 -| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | 結束回應程序。 -| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | 傳送 JSON 回應。 -| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | 傳送 JSON 回應,並支援 JSONP。 -| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | 將要求重新導向。 -| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | 呈現視圖範本。 -| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | 傳送各種類型的回應。 -| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | 以八位元組串流形式傳送檔案。 -| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | 設定回應狀態碼,並以回應內文形式傳送其字串表示法。 +| 方法 | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | 提示您提供要下載的檔案。 | +| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | End the response process. | +| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | 傳送 JSON 回應。 | +| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | 傳送 JSON 回應,並支援 JSONP。 | +| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | 將要求重新導向。 | +| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Render a view template. | +| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | 傳送各種類型的回應。 | +| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | 以八位元組串流形式傳送檔案。 | +| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. |

    app.route()

    您可以使用 `app.route()`,來為路由路徑建立可鏈接的路由處理程式。 由於是在單一位置指定路徑,建立模組路由很有用,因為它可減少冗餘和打錯字的情況。如需路由的相關資訊,請參閱 [Router() 說明文件](/{{ page.lang }}/4x/api.html#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](/{{ page.lang }}/5x/api.html#router). 下列範例顯示利用 `app.route()` 所定義的路由處理程式鏈。 -
    -
    +```js
     app.route('/book')
    -  .get(function(req, res) {
    -    res.send('Get a random book');
    +  .get((req, res) => {
    +    res.send('Get a random book')
    +  })
    +  .post((req, res) => {
    +    res.send('Add a book')
       })
    -  .post(function(req, res) {
    -    res.send('Add a book');
    +  .put((req, res) => {
    +    res.send('Update the book')
       })
    -  .put(function(req, res) {
    -    res.send('Update the book');
    -  });
    -
    -
    +```

    express.Router

    -`express.Router` 類別用來建立可裝載的模組路由處理程式。`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". -下列範例是將路由器建立成模組、 -在其中載入中介軟體函數、定義一些路由,並且將路由器模組裝載在主要應用程式中的路徑。 +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. 在應用程式目錄中建立一個名為 `birds.js` 的路由器檔案,內含下列內容: -
    -
    -var express = require('express');
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const router = express.Router()
     
     // middleware that is specific to this router
    -router.use(function timeLog(req, res, next) {
    -  console.log('Time: ', Date.now());
    -  next();
    -});
    +const timeLog = (req, res, next) => {
    +  console.log('Time: ', Date.now())
    +  next()
    +}
    +router.use(timeLog)
    +
     // define the home page route
    -router.get('/', function(req, res) {
    -  res.send('Birds home page');
    -});
    +router.get('/', (req, res) => {
    +  res.send('Birds home page')
    +})
     // define the about route
    -router.get('/about', function(req, res) {
    -  res.send('About birds');
    -});
    +router.get('/about', (req, res) => {
    +  res.send('About birds')
    +})
     
    -module.exports = router;
    -
    -
    +module.exports = router +``` 然後將路由器模組載入應用程式中: -
    -
    -var birds = require('./birds');
    -...
    -app.use('/birds', birds);
    -
    -
    +```js +const birds = require('./birds') + +// ... + +app.use('/birds', birds) +``` 現在,應用程式就能夠處理發給 `/birds` 和 `/birds/about` 的要求,並且呼叫該路由特定的 `timeLog` 中介軟體函數。 + +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](/{{ page.lang }}/5x/api.html#app.use). + +```js +const router = express.Router({ mergeParams: true }) +``` diff --git a/zh-tw/guide/using-middleware.md b/zh-tw/guide/using-middleware.md old mode 100755 new mode 100644 index 6be532a874..95a92eb0e9 --- a/zh-tw/guide/using-middleware.md +++ b/zh-tw/guide/using-middleware.md @@ -1,283 +1,278 @@ --- layout: page title: 使用 Express 中介軟體 +description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide -lang: zh-tw +redirect_from: " " --- # 使用中介軟體 Express 是一個本身功能極簡的路由與中介軟體 Web 架構:本質上,Express 應用程式是一系列的中介軟體函數呼叫。 -*中介軟體*函數是一些有權存取[要求物件](/{{ page.lang }}/4x/api.html#req) (`req`)、[回應物件](/{{ page.lang }}/4x/api.html#res) (`res`) 和應用程式要求/回應循環中之下一個中介軟體函數的函數。下一個中介軟體函數通常以名為 `next` 的變數表示。 +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#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 can perform the following tasks: -* 執行任何程式碼。 -* 對要求和回應物件進行變更。 -* 結束要求/回應循環。 -* 呼叫堆疊中的下一個中介軟體函數。 +- 執行任何程式碼。 +- Make changes to the request and the response objects. +- End the request-response cycle. +- Call the next middleware function in the stack. -如果現行中介軟體函數不會結束要求/回應循環,它必須呼叫 `next()`,以便將控制權傳遞給下一個中介軟體函數。否則,要求將會停擺。 +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. Express 應用程式可以使用下列類型的中介軟體: - - [應用程式層次的中介軟體](#middleware.application) - - [路由器層次的中介軟體](#middleware.router) - - [錯誤處理中介軟體](#middleware.error-handling) - - [內建中介軟體](#middleware.built-in) - - [協力廠商中介軟體](#middleware.third-party) +- [應用程式層次的中介軟體](#middleware.application) +- [路由器層次的中介軟體](#middleware.router) +- [錯誤處理中介軟體](#middleware.error-handling) +- [內建中介軟體](#middleware.built-in) +- [協力廠商中介軟體](#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.

    應用程式層次的中介軟體

    -使用 `app.use()` 和 `app.METHOD()` 函數,將應用程式層次的中介軟體連結至 [app object](/{{ page.lang }}/4x/api.html#app) 實例,其中 `METHOD` 是中介軟體函數要處理的 HTTP 要求方法(例如 GET、PUT 或 POST),並採小寫。 +Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#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. -本例顯示沒有裝載路徑的中介軟體函數。每當應用程式收到要求時,就會執行此函數。 +This example shows a middleware function with no mount path. The function is executed every time the app receives a request. -
    -
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -app.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    -
    -
    +app.use((req, res, next) => { + console.log('Time:', Date.now()) + next() +}) +``` -本例顯示裝載在 `/user/:id` 路徑的中介軟體函數。會對 `/user/:id` 路徑上任何類型的 HTTP 要求,執行此函數。 +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. + +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` + +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) => { + res.send('USER') +}) +``` -
    -
    -app.use('/user/:id', function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    - -本例顯示路由和其處理程式函數(中介軟體系統)。此函數會處理指向 `/user/:id` 路徑的 GET 要求。 - -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  res.send('USER');
    -});
    -
    -
    - -下列範例顯示使用裝載路徑在裝載點載入一系列中介軟體函數。其中說明中介軟體子堆疊,這個子堆疊會針對指向 `/user/:id` 路徑之任何類型的 HTTP 要求,列印其要求資訊。 - -
    -
    -app.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    -
    -
    - -路由處理程式可讓您為一個路徑定義多個路由。下列範例為指向 `/user/:id` 路徑的 GET 要求,定義兩個路由。第二個路由不會造成任何問題,卻絕不會呼叫,因為第一個路由會結束要求/回應循環。 +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. + +```js +app.use('/user/:id', (req, res, next) => { + console.log('Request URL:', req.originalUrl) + next() +}, (req, res, next) => { + console.log('Request Type:', req.method) + next() +}) +``` + +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. 本例顯示中介軟體子堆疊,它處理了指向 `/user/:id` 路徑的 GET 要求。 -
    -
    -app.get('/user/:id', function (req, res, next) {
    -  console.log('ID:', req.params.id);
    -  next();
    -}, function (req, res, next) {
    -  res.send('User Info');
    -});
    +```js
    +app.get('/user/:id', (req, res, next) => {
    +  console.log('ID:', req.params.id)
    +  next()
    +}, (req, res, next) => {
    +  res.send('User Info')
    +})
     
     // handler for the /user/:id path, which prints the user ID
    -app.get('/user/:id', function (req, res, next) {
    -  res.end(req.params.id);
    -});
    -
    -
    +app.get('/user/:id', (req, res, next) => { + 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. + +{% capture next-function %} -如果要跳過路由器中介軟體堆疊中其餘的中介軟體函數,請呼叫 `next('route')`,將控制權傳遞給下一個路由。**附註**: -`next('route')` 只適用於使用 `app.METHOD()` 或 `router.METHOD()` 函數載入的中介軟體函數。 +`next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. + +{% endcapture %} + +{% include admonitions/note.html content=next-function %} 本例顯示中介軟體子堆疊,它處理了指向 `/user/:id` 路徑的 GET 要求。 -
    -
    -app.get('/user/:id', function (req, res, next) {
    +```js
    +app.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next route
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass the control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    -  // render a regular page
    -  res.render('regular');
    -});
    +  else next()
    +}, (req, res, next) => {
    +  // send a regular response
    +  res.send('regular')
    +})
     
    -// handler for the /user/:id path, which renders a special page
    -app.get('/user/:id', function (req, res, next) {
    -  res.render('special');
    -});
    -
    -
    +// handler for the /user/:id path, which sends a special response +app.get('/user/:id', (req, res, next) => { + res.send('special') +}) +``` + +Middleware can also be declared in an array for reusability. + +本例顯示裝載在 `/user/:id` 路徑的中介軟體函數。會對 `/user/:id` 路徑上任何類型的 HTTP 要求,執行此函數。 + +```js +function logOriginalUrl (req, res, next) { + console.log('Request URL:', req.originalUrl) + next() +} + +function logMethod (req, res, next) { + console.log('Request Type:', req.method) + next() +} + +const logStuff = [logOriginalUrl, logMethod] +app.get('/user/:id', logStuff, (req, res, next) => { + res.send('User Info') +}) +```

    路由器層次的中介軟體

    路由器層次的中介軟體的運作方式如同應用程式層次的中介軟體,不同之處在於它會連結至 `express.Router()` 實例。 -
    -
    -var router = express.Router();
    -
    -
    +```js +const router = express.Router() +``` + 請利用 `router.use()` 和 `router.METHOD()` 函數來載入路由器層次的中介軟體。 下列的程式碼範例是使用路由器層次的中介軟體,抄寫上述針對應用程式層次的中介軟體顯示的中介軟體系統: -
    -
    -var app = express();
    -var router = express.Router();
    +```js
    +const express = require('express')
    +const app = express()
    +const router = express.Router()
     
     // a middleware function with no mount path. This code is executed for every request to the router
    -router.use(function (req, res, next) {
    -  console.log('Time:', Date.now());
    -  next();
    -});
    +router.use((req, res, next) => {
    +  console.log('Time:', Date.now())
    +  next()
    +})
     
     // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
    -router.use('/user/:id', function(req, res, next) {
    -  console.log('Request URL:', req.originalUrl);
    -  next();
    -}, function (req, res, next) {
    -  console.log('Request Type:', req.method);
    -  next();
    -});
    +router.use('/user/:id', (req, res, next) => {
    +  console.log('Request URL:', req.originalUrl)
    +  next()
    +}, (req, res, next) => {
    +  console.log('Request Type:', req.method)
    +  next()
    +})
     
     // a middleware sub-stack that handles GET requests to the /user/:id path
    -router.get('/user/:id', function (req, res, next) {
    +router.get('/user/:id', (req, res, next) => {
       // if the user ID is 0, skip to the next router
    -  if (req.params.id == 0) next('route');
    +  if (req.params.id === '0') next('route')
       // otherwise pass control to the next middleware function in this stack
    -  else next(); //
    -}, function (req, res, next) {
    +  else next()
    +}, (req, res, next) => {
       // render a regular page
    -  res.render('regular');
    -});
    +  res.render('regular')
    +})
     
     // handler for the /user/:id path, which renders a special page
    -router.get('/user/:id', function (req, res, next) {
    -  console.log(req.params.id);
    -  res.render('special');
    -});
    +router.get('/user/:id', (req, res, next) => {
    +  console.log(req.params.id)
    +  res.render('special')
    +})
     
     // mount the router on the app
    -app.use('/', router);
    -
    -
    +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. -
    -錯誤處理中介軟體一律會使用*四個*引數。您必須提供這四個引數,將它識別為錯誤處理中介軟體函數。即使您不需要使用 `next` 物件也必須指定,以維護簽章。否則,會將 `next` 物件解譯為一般中介軟體,而無法處理錯誤。 -
    - -錯誤處理中介軟體函數的定義方式,與其他中介軟體函數相同,差別在於引數是四個而非三個,具體來說,就是使用 `(err, req, res, next)`) 簽章: - -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    - -如需錯誤處理中介軟體的詳細資料,請參閱:[錯誤處理](/{{ page.lang }}/guide/error-handling.html)。 +本例顯示中介軟體子堆疊,它處理了指向 `/user/:id` 路徑的 GET 要求。 -

    內建中介軟體

    +```js +const express = require('express') +const app = express() +const router = express.Router() -從 4.x 版起,Express 不再相依於 [Connect](https://github.com/senchalabs/connect)。除了 `express.static`,Express 先前隨附的所有中介軟體函數現在位於個別的模組中。請檢視[中介軟體函數清單](https://github.com/senchalabs/connect#middleware)。 +// predicate the router with a check and bail out when needed +router.use((req, res, next) => { + if (!req.headers['x-auth']) return next('router') + next() +}) -

    express.static(root, [options])

    +router.get('/user/:id', (req, res) => { + res.send('hello, user!') +}) -Express 唯一的內建中介軟體函數是 `express.static`。此函數以 [serve-static](https://github.com/expressjs/serve-static) 為基礎,負責在 Express 應用程式中提供靜態資產。 +// use the router and 401 anything falling through +app.use('/admin', router, (req, res) => { + res.sendStatus(401) +}) +``` -`root` 引數指定提供靜態資產的根目錄。 +

    Error-handling middleware

    -`options` 選用物件可具有下列內容: +
    +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. +
    -| 內容 | 說明 | 類型 | 預設值 | -|---------------|-----------------------------------------------------------------------|-------------|-----------------| -| `dotfiles` | 用來提供點檔案的選項。可能的值是 "allow"、"deny" 和 "ignore" | 字串 | "ignore" | -| `etag` | 啟用或停用 etag 的產生 | 布林 | `true` | -| `extensions` | 設定副檔名遞補。 | 陣列 | `[]` | -| `index` | 傳送目錄索引檔。設定 `false`,會停用目錄檢索。 | 混合 | "index.html" | - `lastModified` | 將 `Last-Modified` 標頭設為作業系統上檔案的前次修改日期。可能的值是 `true` 或 `false`。 | 布林 | `true` | -| `maxAge` | 設定 Cache-Control 標頭的 max-age 內容,以毫秒為單位或 [ms 格式](https://www.npmjs.org/package/ms)的字串 | 數字 | 0 | -| `redirect` | 當路徑名稱是目錄時,重新導向至尾端 "/"。 | 布林 | `true` | -| `setHeaders` | 用來設定 HTTP 標頭以提供檔案的函數。 | 函數 | | +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)`: -下列範例顯示如何使用 `express.static` 中介軟體函數,且其中詳細闡述了 options 物件: +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` -
    -
    -var options = {
    -  dotfiles: 'ignore',
    -  etag: false,
    -  extensions: ['htm', 'html'],
    -  index: false,
    -  maxAge: '1d',
    -  redirect: false,
    -  setHeaders: function (res, path, stat) {
    -    res.set('x-timestamp', Date.now());
    -  }
    -}
    +For details about error-handling middleware, see: [Error handling](/{{ page.lang }}/guide/error-handling.html).
     
    -app.use(express.static('public', options));
    -
    -
    +

    Built-in middleware

    -每一個應用程式可有多個靜態目錄: +從 4.x 版起,Express 不再相依於 [Connect](https://github.com/senchalabs/connect)。除了 `express.static`,Express 先前隨附的所有中介軟體函數現在位於個別的模組中。請檢視[中介軟體函數清單](https://github.com/senchalabs/connect#middleware)。 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). -
    -
    -app.use(express.static('public'));
    -app.use(express.static('uploads'));
    -app.use(express.static('files'));
    -
    -
    +Express has the following built-in middleware functions: -如需 `serve-static` 函數和其選項的詳細資料,請參閱 [serve-static](https://github.com/expressjs/serve-static) 說明文件。 +- [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. +- [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** +- [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+** -

    協力廠商中介軟體

    +

    Third-party middleware

    -使用協力廠商中介軟體,在 Express 應用程式中新增功能。 +Use third-party middleware to add functionality to Express apps. 針對必要的功能安裝 Node.js 模組,然後在應用程式層次或路由器層次將它載入到您的應用程式中。 下列範例說明如何安裝和載入用來剖析 Cookie 的中介軟體函數 `cookie-parser`。 -
    -
    +```bash
     $ npm install cookie-parser
    -
    -
    +``` -
    -
    -var express = require('express');
    -var app = express();
    -var cookieParser = require('cookie-parser');
    +```js
    +const express = require('express')
    +const app = express()
    +const cookieParser = require('cookie-parser')
     
     // load the cookie-parsing middleware
    -app.use(cookieParser());
    -
    -
    +app.use(cookieParser()) +``` -如需 Express 中常用的部分協力廠商中介軟體函數清單,請參閱:[協力廠商中介軟體](../resources/middleware.html)。 +For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](../resources/middleware.html). diff --git a/zh-tw/guide/using-template-engines.md b/zh-tw/guide/using-template-engines.md old mode 100755 new mode 100644 index 1849f66c59..4b9de74607 --- a/zh-tw/guide/using-template-engines.md +++ b/zh-tw/guide/using-template-engines.md @@ -1,61 +1,62 @@ --- layout: page -title: 對 Express 除錯 +title: 在 Express 中使用模板引擎 +description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide -lang: zh-tw +redirect_from: " " --- -# 在 Express 中使用範本引擎 +# 在 Express 中使用模板引擎 -您必須先設定下列應用程式設定,Express 才能呈現範本檔: +A _template engine_ enables you to use static template files in your application. 模板引擎讓您能在應用程式中使用靜態模板檔案。在執行時,模板引擎會將靜態模板檔案中的變數取代為真實的值,並將模板轉換為 HTML 檔案發送至客戶端,這種方法使得設計一個 HTML 頁面變得更加容易。 +This approach makes it easier to design an HTML page. -* `views`:範本檔所在的目錄。例如:`app.set('views', './views')` -* `view engine`:要使用的範本引擎。例如:`app.set('view engine', 'pug')` +部分主流的模板引擎 [Pug](https://pugjs.org/api/getting-started.html)、[Mustache](https://www.npmjs.com/package/mustache) 和 [EJS](https://www.npmjs.com/package/ejs) 均可被使用於 Express 中。[Express 應用程式產生器](http://expressjs.com/en/starter/generator.html)預設採用 [Jade](https://www.npmjs.com/package/jade),但也支援包含上述的多種模板引擎。 -然後安裝對應的範本引擎 npm 套件: +若要渲染模板檔案,您必須在應用程式產生器產生的 `app.js` 設定以下[應用程式屬性](http://expressjs.com/en/4x/api.html#app.set): -
    -
    +- `views`, the directory where the template files are located. `views`:範本檔所在的目錄。例如:`app.set('views', './views')`,其預設為應用程式根目錄的 `views` 資料夾。
    +  This defaults to the `views` directory in the application root directory.
    +- `view engine`, the template engine to use. `view engine`:要使用的範本引擎,例如若要使用 Pug 模板引擎:`app.set('view engine', 'pug')`
    +
    +並安裝對應的模板引擎 npm 套件,例如安裝 Pug:
    +
    +```bash
     $ npm install pug --save
    -
    -
    +```
    與 Express 相容的範本引擎(例如 Pug)會匯出一個名稱是 `__express(filePath, options, callback)` 的函數,以供 `res.render()` 函數呼叫,來呈現範本程式碼。 -有些範本引擎不遵循這項慣例。[Consolidate.js](https://www.npmjs.org/package/consolidate) 程式庫遵循這項慣例,它會對映所有常見的 Node.js 範本引擎,因此能在 Express 內平順無礙地運作。 +Some template engines do not follow this convention. 有些範本引擎不遵循這項慣例。[Consolidate.js](https://www.npmjs.org/package/consolidate) 程式庫遵循這項慣例,它會對映所有常見的 Node.js 範本引擎,因此能在 Express 內平順無礙地運作。 +
    -設定視圖引擎之後,您不必指定引擎或將範本引擎模組載入到應用程式中;Express 會在內部載入模組,如以下所示(針對上述範例)。 +在設定模板引擎之後,您不必指定引擎或將範本引擎模組載入到應用程式中;Express 會在內部載入模組,如以下所示(針對上述範例)。 -
    -
    -app.set('view engine', 'pug');
    -
    -
    +```js +app.set('view engine', 'pug') +``` -在 `views` 目錄中,建立一個名稱是 `index.pug` 的 Pug 範本檔,內含下列內容: +在 `views` 目錄中,建立一個名稱是 `index.pug` 並內含下列內容的 Pug 範本檔: -
    -
    +```pug
     html
       head
         title= title
       body
         h1= message
    -
    -
    +``` -然後建立路由,以呈現 `index.pug` 檔。如果未設定 `view engine` 內容,您必須指定 `view` 檔的副檔名。否則,您可以省略它。 +Create a route to render the `index.pug` file. If the `view engine` property is not set, +you must specify the extension of the `view` file. Otherwise, you can omit it. -
    -
    -app.get('/', function (req, res) {
    -  res.render('index', { title: 'Hey', message: 'Hello there!'});
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.render('index', { title: 'Hey', message: 'Hello there!' }) +}) +``` -當您向首頁提出要求時,`index.pug` 檔會呈現成 HTML。 +當您向首頁發出請求時,`index.pug` 檔會以 HTML 被渲染出來。 -如需進一步瞭解範本引擎在 Express 中的運作方式,請參閱:[開發 Express 範本引擎](/{{ page.lang }}/advanced/developing-template-engines.html)。 +The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. diff --git a/zh-tw/guide/writing-middleware.md b/zh-tw/guide/writing-middleware.md old mode 100755 new mode 100644 index 2da6983aec..ac129ded59 --- a/zh-tw/guide/writing-middleware.md +++ b/zh-tw/guide/writing-middleware.md @@ -1,37 +1,39 @@ --- layout: page title: 撰寫中介軟體以用於 Express 應用程式中 +description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide -lang: zh-tw +redirect_from: " " --- # 撰寫中介軟體以用於 Express 應用程式中

    概觀

    -*中介軟體*函數是一些有權存取[要求物件](/{{ page.lang }}/4x/api.html#req) (`req`)、[回應物件](/{{ page.lang }}/4x/api.html#res) (`res`) 和應用程式要求/回應循環中之下一個中介軟體函數的函數。下一個中介軟體函數通常以名為 `next` 的變數表示。 +_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/4x/api.html#req) (`req`), the [response object](/{{ page.lang }}/4x/api.html#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. -中介軟體函數可以執行下列作業: +Middleware functions can perform the following tasks: -* 執行任何程式碼。 -* 對要求和回應物件進行變更。 -* 結束要求/回應循環。 -* 呼叫堆疊中的下一個中介軟體。 +- 執行任何程式碼。 +- Make changes to the request and the response objects. +- End the request-response cycle. +- Call the next middleware in the stack. -如果現行中介軟體函數不會結束要求/回應循環,它必須呼叫 `next()`,以便將控制權傳遞給下一個中介軟體函數。否則,要求將會停擺。 +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. -下列範例顯示中介軟體函數呼叫中的元素: +The following figure shows the elements of a middleware function call: +
    - -
    要套用中介軟體函數的路徑(路由)。
    +
    Path (route) for which the middleware function applies.
    -
    中介軟體函數。
    +
    The middleware function.
    中介軟體函數的回呼引數,依慣例,稱為 "next"。
    @@ -40,106 +42,180 @@ lang: zh-tw
    中介軟體函數的 HTTP request 引數,依慣例,稱為 "req"。
    - +
    +Elements of a middleware function call -
    要套用中介軟體函數的 HTTP 方法。
    +
    HTTP method for which the middleware function applies.
    +
    -下列範例顯示簡單的 "Hello World" Express 應用程式,您將為這個應用程式定義兩個中介軟體函數: +Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error. -
    -
    -var express = require('express');
    -var app = express();
    +

    範例

    + +下列範例顯示簡單的 "Hello World" Express 應用程式,您將為這個應用程式定義兩個中介軟體函數: +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. -app.get('/', function (req, res) { - res.send('Hello World!'); -}); +```js +const express = require('express') +const app = express() -app.listen(3000); -
    -
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -

    開發

    +app.listen(3000) +``` -以下的簡單範例顯示一個稱為 "myLogger" 的中介軟體函數。當透過這個函數將要求傳遞給應用程式時,此函數只會列印 "LOGGED"。中介軟體函數會指派給名為 `myLogger` 的變數。 +

    Middleware function myLogger

    +Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. The middleware function is assigned to a variable named `myLogger`. -
    -
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    -
    -
    +```js +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} +```
    -請注意上述對 `next()` 的呼叫。呼叫這個函數時,會呼叫應用程式中的下一個中介軟體函數。`next()` 函數並非 Node.js 或 Express API 的一部分,而是傳遞給中介軟體函數的第三個引數。`next()` 函數雖沒有命名限制,但依慣例,都是稱為 "next"。為避免混淆,請一律採用此慣例。 +Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. +The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next". +To avoid confusion, always use this convention.
    -若要載入中介軟體函數,請呼叫 `app.use()`,以指定中介軟體函數。舉例來說,下列程式碼會在根路徑 (/) 路由之前先載入 `myLogger` 中介軟體函數。 +To load the middleware function, call `app.use()`, specifying the middleware function. +For example, the following code loads the `myLogger` middleware function before the route to the root path (/). -
    -
    -var express = require('express');
    -var app = express();
    +```js
    +const express = require('express')
    +const app = express()
     
    -var myLogger = function (req, res, next) {
    -  console.log('LOGGED');
    -  next();
    -};
    +const myLogger = function (req, res, next) {
    +  console.log('LOGGED')
    +  next()
    +}
     
    -app.use(myLogger);
    +app.use(myLogger)
     
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    +app.get('/', (req, res) => {
    +  res.send('Hello World!')
    +})
     
    -app.listen(3000);
    -
    -
    +app.listen(3000) +``` 每當應用程式收到要求時,它會將 "LOGGED" 訊息列印至終端機。 -中介軟體的載入順序很重要:先載入的中介軟體函數也會先執行。 +The order of middleware loading is important: middleware functions that are loaded first are also executed first. 如果 `myLogger` 是在根路徑路由之後才載入,要求永不會抵達該函數,應用程式也不會列印 "LOGGED",因為根路徑的路由處理程式會終止要求/回應循環。 -中介軟體函數 `myLogger` 只會列印訊息,然後呼叫 `next()` 函數,將要求傳遞給堆疊中的下一個中介軟體函數。 +The middleware function `myLogger` simply prints a message, then passes on the request to the next middleware function in the stack by calling the `next()` function. + +

    Middleware function requestTime

    + +Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` +to the request object. + +```js +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} +``` + +The app now uses the `requestTime` middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to `req` (the request object). + +```js +const express = require('express') +const app = express() + +const requestTime = function (req, res, next) { + req.requestTime = Date.now() + next() +} + +app.use(requestTime) + +app.get('/', (req, res) => { + let responseText = 'Hello World!
    ' + responseText += `Requested at: ${req.requestTime}` + res.send(responseText) +}) + +app.listen(3000) +``` + +When you make a request to the root of the app, the app now displays the timestamp of your request in the browser. -下一個範例是在要求物件中新增一個稱為 `requestTime` 的內容。我們將這個中介軟體函數命名為 "requestTime"。 +

    Middleware function validateCookies

    + +Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. + +Here's an example function that validates cookies with an external async service. + +```js +async function cookieValidator (cookies) { + try { + await externallyValidateCookie(cookies.testCookie) + } catch { + throw new Error('Invalid cookies') + } +} +``` + +Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. + +```js +const express = require('express') +const cookieParser = require('cookie-parser') +const cookieValidator = require('./cookieValidator') + +const app = express() + +async function validateCookies (req, res, next) { + await cookieValidator(req.cookies) + next() +} + +app.use(cookieParser()) + +app.use(validateCookies) + +// error handler +app.use((err, req, res, next) => { + res.status(400).send(err.message) +}) + +app.listen(3000) +``` + +
    +Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. +
    -
    -
    -var requestTime = function (req, res, next) {
    -  req.requestTime = Date.now();
    -  next();
    -};
    -
    -
    +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. -現在,應用程式會使用 `requestTime` 中介軟體函數。此外,根路徑路由的回呼函數會使用中介軟體函數新增至 `req`(要求物件)的內容。 +For more information about Express middleware, see: [Using Express middleware](/{{ page.lang }}/guide/using-middleware.html). -
    -
    -var express = require('express');
    -var app = express();
    +

    Configurable middleware

    -var requestTime = function (req, res, next) { - req.requestTime = Date.now(); - next(); -}; +If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. -app.use(requestTime); +File: `my-middleware.js` -app.get('/', function (req, res) { - var responseText = 'Hello World!
    '; - responseText += 'Requested at: ' + req.requestTime + ''; - res.send(responseText); -}); +```js +module.exports = function (options) { + return function (req, res, next) { + // Implement the middleware function based on the options object + next() + } +} +``` -app.listen(3000); -
    -
    +The middleware can now be used as shown below. -當您對應用程式根位置發出要求時,應用程式現在會在瀏覽器中顯示該要求的時間戳記。 +```js +const mw = require('./my-middleware.js') -由於您有權存取要求物件、回應物件、堆疊中的下一個中介軟體函數,以及整個 Node.js API,因此,中介軟體函數的可能性無止盡。 +app.use(mw({ option1: '1', option2: '2' })) +``` -如需 Express 中介軟體的相關資訊,請參閱:[使用 Express 中介軟體](/{{ page.lang }}/guide/using-middleware.html)。 +Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. diff --git a/zh-tw/index.md b/zh-tw/index.md index ecc4f59dce..0c19c9857b 100644 --- a/zh-tw/index.md +++ b/zh-tw/index.md @@ -1,50 +1,61 @@ --- layout: home -title: Express - Node.js Web 應用程式架構 +title: Express - Node.js web application framework +description: "Express is a fast, unopinionated, minimalist web framework for Node.js, providing a robust set of features for web and mobile applications." menu: home -lang: zh-tw +redirect_from: " " --- +
    - {% include header/header-{{ page.lang }}.html %} -
    - - 快速、集思廣益、極簡的 Node.js Web 架構 + +

    Fast, unopinionated, minimalist web framework for Node.js

    -
    $ npm install express --save
    -
    -
    - +
    $ npm install express --save
    -
    -
    - Express 文件提供其他語言版本:[西班牙文](/es)、[日文](/ja)、[俄文](/ru)、 -[中文](/zh)、[韓文](/ko)、[葡萄牙文](/pt-br)。 -
    +
    -
    -
    -
    -

    Web 應用程式

    Express 是最小又靈活的 Node.js Web 應用程式架構,為 Web 與行動式應用程式提供一組健全的特性。
    +```javascript +const express = require('express') +const app = express() +const port = 3000 -
    -

    API

    大量的 HTTP 公用程式方法與中介軟體供您支配,能夠快速又輕鬆的建立完整的 API。
    +app.get('/', (req, res) => { + res.send('Hello World!') +}) -
    -

    效能

    Express 既提供精簡的基礎 Web 應用程式特性,又不使您所認識及喜好的 Node.js 失色。 -
    +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) +``` -
    -
    - diff --git a/zh-tw/resources/community.md b/zh-tw/resources/community.md old mode 100755 new mode 100644 index 5c6c7057d0..5c181366e9 --- a/zh-tw/resources/community.md +++ b/zh-tw/resources/community.md @@ -1,33 +1,88 @@ --- layout: page title: Express 社群 +description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources -lang: zh-tw +redirect_from: " " --- # 社群 -## 郵寄清單 +## Technical committee -加入擁有 2000 位以上 Express 使用者的 [Google 群組](https://groups.google.com/group/express-js),或瀏覽其中超過 5000 筆的討論。 +The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, +and other issues relevant to the Express project. Each meeting is typically announced in an +[expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is +open to all observers. -## Gitter +The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). -對於有興趣參與每天的 Express 相關討論的開發人員,[expressjs/express 聊天室](https://gitter.im/expressjs/express)是一個絕佳去處。 +Members of the Express technical committee are: -## IRC 頻道 +**Active:** -數以百計的開發人員每天都在 freenode 上的 #express 閒逛。如果您對架構有疑問,加入此頻道,很快就能獲得回應。 +- [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey +- [@crandmck](https://github.com/crandmck) - Rand McKinney +- [@LinusU](https://github.com/LinusU) - Linus Unnebäck +- [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón +- [@sheplu](https://github.com/sheplu) - Jean Burellier +- [@wesleytodd](https://github.com/wesleytodd) - Wes Todd +- [@jonchurch](https://github.com/jonchurch) - Jon Church +- [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida -## 範例 +**Inactive:** -檢視儲存庫中數十個 Express 應用程式[範例](https://github.com/expressjs/express/tree/master/examples),從 API 設計與鑑別,到範本引擎的整合,樣樣涵蓋在內。 +- [@dougwilson](https://github.com/dougwilson) - Douglas Wilson +- [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa +- [@jonathanong](https://github.com/jonathanong) - jongleberry +- [@niftylettuce](https://github.com/niftylettuce) - niftylettuce +- [@troygoode](https://github.com/troygoode) - Troy Goode + +## Express is made of many modules + +我們的熱情活躍的社群已建立各式各樣的延伸項目、[中介軟體模組](/{{ page.lang }}/resources/middleware.html),以及更高層次的架構。相關資訊請參閱 [Wiki](https://github.com/expressjs/express/wiki)。 + +Additionally, the Express community maintains modules in these two GitHub orgs: + +- [jshttp](https://jshttp.github.io/) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). +- [pillarjs](https://pillarjs.github.io/): low-level modules that Express uses internally. + +To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). ## 議題 如果您恰巧碰到您認為是錯誤之處,或者只是想提出一項特性要求,請在[議題列表](https://github.com/expressjs/express/issues)中開立問題單。 -## 協力廠商 +## 範例 -我們的熱情活躍的社群已建立各式各樣的延伸項目、[中介軟體模組](/{{ page.lang }}/resources/middleware.html),以及更高層次的架構。相關資訊請參閱 [Wiki](https://github.com/expressjs/express/wiki)。 +檢視儲存庫中數十個 Express 應用程式[範例](https://github.com/expressjs/express/tree/master/examples),從 API 設計與鑑別,到範本引擎的整合,樣樣涵蓋在內。 + +## Github Discussions + +The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. + +# Branding of Express.js + +## Express.js Logo + +Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks. +
    +
    +

    Logotype

    + Express.js logo + + + Express.js logo + +
    +
    +

    Logomark

    + Express.js mark + + + Express.js mark + +
    +
    +
    \ No newline at end of file diff --git a/zh-tw/resources/contributing.md b/zh-tw/resources/contributing.md new file mode 100644 index 0000000000..e37cee3122 --- /dev/null +++ b/zh-tw/resources/contributing.md @@ -0,0 +1,466 @@ +--- +layout: page +title: Contributing to Express +description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. +menu: resources +redirect_from: " " +--- + +# Contributing to Express + +### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). + +Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). +These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. + +- [Technical committee](#technical-committee) +- [Community contributing guide](#community-contributing-guide) +- [Collaborator's guide](#collaborators-guide) +- [Security policies and procedures](#security-policies-and-procedures) + +## Technical committee + +The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). + +## Community contributing guide + + + +The goal of this document is to create a contribution process that: + +- Encourages new contributions. +- Encourages contributors to remain involved. +- Avoids unnecessary processes and bureaucracy whenever possible. +- Creates a transparent decision making process that makes it clear how + contributors can be involved in decision making. + +### Vocabulary + +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Committer** is a subset of contributors who have been given write access to the repository. +- A **Project Captain** is the lead maintainer of a repository. +- A **TC (Technical Committee)** is a group of committers representing the required technical + expertise to resolve rare disputes. +- A **Triager** is a subset of contributors who have been given triage access to the repository. + +### Logging Issues + +Log an issue for any question or problem you might have. When in doubt, log an issue, and +any additional policies about what to include will be provided in the responses. The only +exception is security disclosures which should be sent privately. + +Committers may direct you to another repository, ask for additional clarifications, and +add appropriate metadata before the issue is addressed. + +Please be courteous and respectful. Every participant is expected to follow the +project's Code of Conduct. + +### Contributions + +Any change to resources in this repository must be through pull requests. This applies to all changes +to documentation, code, binary files, etc. Even long term committers and TC members must use +pull requests. + +No pull request can be merged without being reviewed. + +For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that +contributors in other timezones have time to review. Consideration should also be given to +weekends and other holiday periods to ensure active committers all have reasonable time to +become involved in the discussion and review process if they wish. + +The default for each contribution is that it is accepted once no committer has an objection. +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. There is no additional "sign off" +process for contributions to land. Once all issues brought by committers are addressed it can +be landed by any committer. + +In the case of an objection being raised in a pull request by another committer, all involved +committers should seek to arrive at a consensus by way of addressing concerns being expressed +by discussion, compromise on the proposed change, or withdrawal of the proposed change. + +If a contribution is controversial and committers cannot agree about how to get it to land +or if it should land then it should be escalated to the TC. TC members should regularly +discuss pending contributions in order to find a resolution. It is expected that only a +small minority of issues be brought to the TC for resolution and that discussion and +compromise among committers be the default resolution mechanism. + +### Becoming a Triager + +Anyone can become a triager! Read more about the process of being a triager in +[the triage process document](https://github.com/expressjs/discussions/blob/master/docs/contributing/triager-guide.md). + +Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate +a new triager. If you are interested in becoming a triager, our best advice is to actively participate +in the community by helping triaging issues and pull requests. As well we recommend +to engage in other community activities like attending the TC meetings, and participating in the Slack +discussions. 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. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. + +You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) +if you have questions or need guidance. + +### Becoming a Committer + +All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, +and added as a committer, and be given write access to the repository. + +Committers are expected to follow this policy and continue to send pull requests, go through +proper review, and have other committers merge their pull requests. + +### TC Process + +The TC uses a "consensus seeking" process for issues that are escalated to the TC. +The group tries to find a resolution that has no open objections among TC members. +If a consensus cannot be reached that has no objections then a majority wins vote +is called. It is also expected that the majority of decisions made by the TC are via +a consensus seeking process and that voting is only used as a last-resort. + +Resolution may involve returning the issue to project captains with suggestions on +how to move forward towards a consensus. It is not expected that a meeting of the TC +will resolve all issues on its agenda during that meeting and may prefer to continue +the discussion happening among the project captains. + +Members can be added to the TC at any time. 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. The TC will consist of a minimum of 3 active members and a +maximum of 10. If the TC should drop below 5 members the active TC members should nominate +someone new. If a TC member is stepping down, they are encouraged (but not required) to +nominate someone to take their place. + +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. + +To remain "active" a TC member should have participation within the last 12 months and miss +no more than six consecutive TC meetings. 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). Members who do not meet this +are expected to step down. If A TC member does not step down, an issue can be opened in the +discussions repo to move them to inactive status. TC members who step down or are removed due +to inactivity will be moved into inactive status. + +Inactive status members can become active members by self nomination if the TC is not already +larger than the maximum of 10. They will also be given preference if, while at max size, an +active member steps down. + +### Project Captains + +The Express TC can designate captains for individual projects/repos in the +organizations. These captains are responsible for being the primary +day-to-day maintainers of the repo on a technical and community front. +Repo captains are empowered with repo ownership and package publication rights. +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 +community members follow the community guidelines, maintaining the repo +and the published package, as well as in providing user support. + +Like TC members, Repo captains are a subset of committers. + +To become a captain for a project the candidate is expected to participate in that +project for at least 6 months as a committer prior to the request. They should have +helped with code contributions as well as triaging issues. They are also required to +have 2FA enabled on both their GitHub and npm accounts. + +Any TC member or an existing captain on the **same** repo can nominate another committer +to the captain role. To do so, they should submit a PR to this document, updating the +**Active Project Captains** section (while maintaining the sort order) with the project +name, the nominee's GitHub handle, and their npm username (if different). + +- Repos can have as many captains as make sense for the scope of work. +- A TC member or an existing repo captain **on the same project** can nominate a new captain. + Repo captains from other projects should not nominate captains for a different project. + +The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow +for comment and/or dissent. When the PR is merged, a TC member will add them to the +proper GitHub/npm groups. + +#### Active Projects and Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) + +#### Current Initiative Captains + +The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) + +### Developer's Certificate of Origin 1.1 + +```text +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Collaborator's guide + + + +### Website Issues + +Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. + +For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. + +### PRs and Code contributions + +- Tests must pass. +- Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. +- If you fix a bug, add a test. + +### Branches + +Use the `master` branch for bug fixes or minor work that is intended for the +current release stream. + +Use the correspondingly named branch, e.g. `6.x`, for anything intended for +a future release of Express. + +### Steps for contributing + +1. Create an issue for the + bug you want to fix or the feature that you want to add. +2. Create your own fork on GitHub, then + checkout your fork. +3. Write your code in your local copy. It's good practice to create a branch for + each new issue you work on, although not compulsory. +4. To run the test suite, first install the dependencies by running `npm install`, + then run `npm test`. +5. Ensure your code is linted by running `npm run lint` -- fix any issue you + see listed. +6. If the tests pass, you can commit your changes to your fork and then create + a pull request from there. Make sure to reference your issue from the pull + request comments by including the issue number e.g. `#123`. + +### Issues which are questions + +We will typically close any vague issues or questions that are specific to some +app you are writing. Please double check the docs and other references before +being trigger happy with posting a question issue. + +Things that will help get your question issue looked at: + +- Full and runnable JS code. +- Clear description of the problem or unexpected behavior. +- Clear description of the expected result. +- Steps you have taken to debug it yourself. + +If you post a question and do not outline the above items or make it easy for +us to understand and reproduce your issue, it will be closed. + +If your question meets all of the above requirements but you do not believe it needs to be looked at +by the maintainers +(for example, if you are just looking for community input) please open it as a discussion topic instead +of an issue. If you +are unsure and open an issue, we may move it to discussions if we triage them and decide they do +not need high +visibility or maintainer input. + +## Security Policies and Procedures + + + +This document outlines security procedures and general policies for the Express +project. + +- [Reporting a Bug](#reporting-a-bug) +- [Disclosure Policy](#disclosure-policy) +- [Comments on this Policy](#comments-on-this-policy) + +### Reporting a Bug + +The Express team and community take all security bugs in Express seriously. +Thank you for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing `express-security@lists.openjsf.org`. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +The lead maintainer will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the security team will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining +the module. + +### Pre-release Versions + +Alpha and Beta releases are unstable and **not suitable for production use**. +Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. +Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. + +### Disclosure Policy + +When the security team receives a security bug report, they will assign it to a +primary handler. This person will coordinate the fix and release process, +involving the following steps: + +- Confirm the problem and determine the affected versions. +- Audit code to find any potential similar problems. +- Prepare fixes for all releases still under maintenance. These fixes will be + released as fast as possible to npm. + +### The Express Threat Model + +We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) + +### Comments on this Policy + +If you have suggestions on how this process could be improved please submit a +pull request. + +---- + +# Contributing to Expressjs.com {#expressjs-website-contributing} + + + +### The Official Documentation of the Express JS Framework + +This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. + +#### Need some ideas? These are some typical issues. + +1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. + - Display or screen sizing problems + - Mobile responsiveness issues + - Missing or broken accessibility features + - Website outages + - Broken links + - Page structure or user interface enhancements + +2. **Content Issues**: Fix anything related to site content or typos. + - Spelling errors + - Incorrect/outdated Express JS documentation + - Missing content + +3. **Translation Issues**: Fix any translation errors or contribute new content. + - Fix spelling errors + - Fix incorrect/poorly translated words + - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. + +#### Want to work on a backlog issue? + +We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. + +#### Have an idea? Found a bug? + +If you've found a bug or a typo, or if you have an idea for an enhancement, you can: + +- Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. + +- Make a [Github pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work and it's ready to go, feel free to send it our way. + +## Getting Started + +The steps below will guide you through the Expressjs.com contribution process. + +#### Step 1: (OPTIONAL) Open a New Issue + +So you've found a problem that you want to fix, or have a site enhancement you want to make. + +1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. + - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. + - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. + - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. + +2. After receiving your issue the Express JS documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. + - For submissions proposing significant change, we encourage you to follow the review process before starting work. + +#### Step 2: Get the Application Code Base + +Clone the repo and get the code: + +```sh +git clone https://github.com/expressjs/expressjs.com.git +``` + +After you've got the code you're ready to start making your changes! + +But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. + +**Markdown Page Files**: + +- These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. +- Change these to make changes to individual pages' content/text or markup. +- Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. + +**Includes Partials and Layout Templates** + +- `_includes` are partials that are imported and reused across multiple pages. + - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. + - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. +- `_layouts` are the templates used to wrap the site's individual pages. + - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. + +**Blog Markdown Files** + +- These files make up the individual blog posts. If you want to contribute a blog post please + follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) +- Located under the `_posts` directory. + +**CSS or Javascript** + +- All css and js files are kept in `css` and `js` folders on the project root. + +The Express JS website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [Github Pages](https://pages.github.com/). + +#### Step 3: Running the Application + +Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. + +1. **Run Locally**: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. + - This is the recommended option for moderate to complex work. + +2. **Run using Deploy Preview**: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/site-deploys/deploy-previews/). + 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a _draft_ pull request. + 2. After the build steps are complete, you'll have access to a **Deploy Preview** tab that will run your changes on the web, rebuilding after each commit is pushed. + 3. After you are completely done your work and it's ready for review, remove the draft status on your pull request and submit your work. + +## Contributing translations + +We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. + +The documentation is translated into these languages: + +- Chinese Simplified (`zh-cn`) +- Chinese Traditional (`zh-tw`) +- English (`en`) +- French (`fr`) +- German (`de`) +- Italian (`it`) +- Japanese (`ja`) +- Korean (`ko`) +- Brazilian Portuguese (`pt-br`) +- Spanish (`es`) + +### How to translate + +1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) +2. [Select the language you want to translate](https://support.crowdin.com/joining-translation-project/#starting-translation) +3. [Start translating](https://support.crowdin.com/online-editor/) + diff --git a/zh-tw/resources/glossary.md b/zh-tw/resources/glossary.md old mode 100755 new mode 100644 index fcf035117d..235534eaba --- a/zh-tw/resources/glossary.md +++ b/zh-tw/resources/glossary.md @@ -1,56 +1,65 @@ --- layout: page title: Express 名詞解釋 +description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources -lang: zh-tw +redirect_from: " " --- # 名詞解釋 +### 應用程式 (application) + +In general, one or more programs that are designed to carry out operations for a specific purpose. 通常是指設計成實行作業以達特定目的的一或多個程式。就 Express 環境定義來說,是指使用 Express API(在 Node.js 平台上執行)的程式。亦可稱為[應用程式物件 (app object)](/{{ page.lang }}/api.html#express)。 Might also refer to an [app object](/{{ page.lang }}/api.html#express). + ### API -應用程式設計介面。在第一次使用時,會拼寫出縮寫。 +Application programming interface. Spell out the abbreviation when it is first used. ### Express -快速、集思廣益、極簡的 Node.js 應用程式 Web 架構。一般而言,"Express" 比 "Express.js" 合適,不過,也能接受後者。 +A fast, un-opinionated, minimalist web framework for Node.js applications. 快速、集思廣益、極簡的 Node.js 應用程式 Web 架構。一般而言,"Express" 比 "Express.js" 合適,不過,也能接受後者。 ### libuv 多平台支援的程式庫,著重在非同步 I/O,主要開發供 Node.js 使用。 +### middleware + +A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: + +- `var foo = require('middleware')` 可稱為_需要_或_使用_ Node.js 模組。接著,`var mw = foo()` 陳述式通常會傳回中介軟體。 Then the statement `var mw = foo()` typically returns the middleware. +- `app.use(mw)` 可稱為_將中介軟體新增至廣域處理程序堆疊_。 +- `app.get('/foo', mw, function (req, res) { ... })` 可稱為_將中介軟體新增至 "GET /foo" 處理程序堆疊_。 + ### Node.js -一種軟體平台,用來建置可調式網路應用程式。Node.js 使用 JavaScript 作為其 Scripting 語言,並透過非封鎖 I/O 和單一執行緒事件迴圈,來達到高傳輸量。請參閱 [nodejs.org](http://nodejs.org/)。**使用注意事項**:一開始稱為 "Node.js",之後稱為 "Node"。 +A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". + +### 開放程式碼 (open-source, open source) -### 中介軟體 (middleware) +當作為形容詞時,會加連號;例如:"This is open-source software." 請參閱[維基百科上的開放程式碼軟體](http://en.wikipedia.org/wiki/Open-source_software)。附註:雖然此術語通常不會加連號,我們仍採用標準的英文規則,加上連號來代表複合形容詞。 -Express 路由層在最終要求處理程式之前所呼叫的函數,因此它位於原始要求與最終預期的路由中間。中介軟體周圍會有少許合宜的專有名詞點: +{% capture english-rules %} - * `var foo = require('middleware')` 可稱為*需要*或*使用* Node.js 模組。接著,`var mw = foo()` 陳述式通常會傳回中介軟體。 - * `app.use(mw)` 可稱為*將中介軟體新增至廣域處理程序堆疊*。 - * `app.get('/foo', mw, function (req, res) { ... })` 可稱為*將中介軟體新增至 "GET /foo" 處理程序堆疊*。 +Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. -### 回應 (response) +{% endcapture %} -一種 HTTP 回應。伺服器傳回 HTTP 回應訊息給用戶端。回應包含要求的相關完成狀態資訊,也可能將要求內容包含在其訊息內文中。 +{% include admonitions/note.html content=english-rules %} ### 要求 (request) -一種 HTTP 要求。用戶端提交 HTTP 要求訊息給伺服器,再由伺服器傳回回應。要求必須使用其中一種[要求方法](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods),例如 GET、POST 等。 +An HTTP request. A client submits an HTTP request message to a server, which returns a response. 一種 HTTP 要求。用戶端提交 HTTP 要求訊息給伺服器,再由伺服器傳回回應。要求必須使用其中一種[要求方法](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods),例如 GET、POST 等。 -### 開放程式碼 (open-source, open source) +### 回應 (response) -當作為形容詞時,會加連號;例如:"This is open-source software." 請參閱[維基百科上的開放程式碼軟體](http://en.wikipedia.org/wiki/Open-source_software)。附註:雖然此術語通常不會加連號,我們仍採用標準的英文規則,加上連號來代表複合形容詞。 +一種 HTTP 回應。伺服器傳回 HTTP 回應訊息給用戶端。回應包含要求的相關完成狀態資訊,也可能將要求內容包含在其訊息內文中。 A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body. ### 路由 (route) -URL 的一部分,用來識別資源。例如,在 `http://foo.com/products/id` 中,"/products/id" 就是路由。 +Part of a URL that identifies a resource. URL 的一部分,用來識別資源。例如,在 `http://foo.com/products/id` 中,"/products/id" 就是路由。 ### 路由器 (router) 請參閱 API 參照中的[路由器](/{{ page.lang }}/4x/api.html#router)。 - -### 應用程式 (application) - -通常是指設計成實行作業以達特定目的的一或多個程式。就 Express 環境定義來說,是指使用 Express API(在 Node.js 平台上執行)的程式。亦可稱為[應用程式物件 (app object)](/{{ page.lang }}/api.html#express)。 diff --git a/zh-tw/resources/learning.md b/zh-tw/resources/learning.md deleted file mode 100755 index 6b29a3b599..0000000000 --- a/zh-tw/resources/learning.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: 額外學習 -menu: resources -lang: zh-tw ---- - -# 額外學習 - -
    Disclaimer: Unendorsed community content.
    - -## Books - -Here are a few of the many books on Express: - - - **[Getting MEAN with Mongo, Express, Angular, and Node](http://www.manning.com/sholmes/)**, -Manning Publications, early 2015. - - **[Express.js in Action](http://www.manning.com/hahn/)**, -Manning Publications, early 2015. - - **[Mastering Web Application Development with Express](https://www.packtpub.com/web-development/mastering-web-application-development-express-raw)**, -Packt Publishing, September 2014. - - **[Web Development with Node and Express](http://shop.oreilly.com/product/0636920032977.do)**, -O'Reilly Media, July 2014. - - **[Node.js in Action](http://www.manning.com/cantelon/)**, -Manning Publications, October 2013. - - **[Express Web Application Development](https://www.packtpub.com/web-development/express-web-application-development)**, -Packt Publishing, June 2013. -- **[express - Middleware für node.js](http://www.amazon.de/express-Middleware-node-js-J%C3%B6rg-Krause/dp/1517281342/ref=sr_1_1?ie=UTF8&qid=1442001556&sr=8-1&keywords=1517281342)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[JADE - die Template Engine für node.js](http://www.amazon.de/JADE-Die-Template-Engine-node-js/dp/1517282098/ref=sr_1_1?ie=UTF8&qid=1442001592&sr=8-1&keywords=1517282098)**, -texxtoor, September 2015. In deutscher Sprache / in German language -- **[Node Web Development, 2nd edition](https://www.packtpub.com/web-development/node-web-development-second-edition)**, Packt Publishing, August 2013 - -### Add your book here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your book, then submit a pull request (GitHub login required). Follow the format of the above listings. - -## Blogs - -- [StrongLoop Blog: Express category](http://strongloop.com/strongblog/category/express/) -- [Hage Yaapa's Blog: Express category](http://www.hacksparrow.com/category/express-js) -- [Codeforgeek Blog: Express category](http://codeforgeek.com/code/nodejs/express/) - -### Add your blog here! - -[Edit the Markdown file](https://github.com/expressjs/expressjs.com/blob/gh-pages/{{ page.lang }}/resources/learning.md) and add a link to your blog, then submit a pull request (GitHub login required). Follow the format of the above listings. diff --git a/zh-tw/resources/middleware.md b/zh-tw/resources/middleware.md old mode 100755 new mode 100644 index 40577513b8..45bb4ab5a2 --- a/zh-tw/resources/middleware.md +++ b/zh-tw/resources/middleware.md @@ -1,63 +1,44 @@ --- -layout: page +layout: middleware title: Express 中介軟體 +description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources -lang: zh-tw +redirect_from: " " +module: mw-home --- -# 協力廠商中介軟體 +## Express 中介軟體 -以下是部分的 Express 中介軟體模組: +The Express middleware modules listed here are maintained by the +[Expressjs team](https://github.com/orgs/expressjs/people). - - [body-parser](https://github.com/expressjs/body-parser):即先前的 `express.bodyParser`、`json` 和 `urlencoded`。另請參閱: - - [body](https://github.com/raynos/body) - - [co-body](https://github.com/visionmedia/co-body) - - [raw-body](https://github.com/stream-utils/raw-body) - - [compression](https://github.com/expressjs/compression):即先前的 `express.compress` - - [connect-image-optimus](https://github.com/msemenistyi/connect-image-optimus):可提供最佳影像的 Connect/Express 中介軟體模組。如果可能的話,請將影像切換成 `.webp` 或 `.jxr`。 - - [connect-timeout](https://github.com/expressjs/timeout):即先前的 `express.timeout` - - [cookie-parser](https://github.com/expressjs/cookie-parser):即先前的 `express.cookieParser` - - [cookie-session](https://github.com/expressjs/cookie-session):即先前的 `express.cookieSession` - - [csurf](https://github.com/expressjs/csurf):即先前的 `express.csrf` - - [errorhandler](https://github.com/expressjs/errorhandler):即先前的 `express.errorHandler` - - [express-debug](https://github.com/devoidfury/express-debug):低調的開發工具,可在您的應用程式中新增標籤,內含範本變數 (locals)、現行階段作業、有用的要求資料等相關資訊。 - - [express-partial-response](https://github.com/nemtsov/express-partial-response):Express 中介軟體模組,會根據 `fields` 查詢字串,使用 Google API 的 Partial Response 來濾除 JSON 回應部分。 - - [express-session](https://github.com/expressjs/session):即先前的 `express.session` - - [express-simple-cdn](https://github.com/jamiesteven/express-simple-cdn):Express 中介軟體模組,會將 CDN 用於靜態資產,並支援多部主機(例如:cdn1.host.com、cdn2.host.com)。 - - [express-slash](https://github.com/ericf/express-slash):Express 中介軟體模組,供嚴格看待尾端斜線的人員使用。 - - [express-stormpath](https://github.com/stormpath/stormpath-express):Express 中介軟體模組,供使用者執行儲存、鑑別、授權、SSO 和資料安全。 - - [express-uncapitalize](https://github.com/jamiesteven/express-uncapitalize):中介軟體模組,可將含有大寫的 HTTP 要求重新導向至標準小寫形式。 - - [helmet](https://github.com/helmetjs/helmet):此模組會設定各種 HTTP 標頭,有助於保護您應用程式的安全。 - - [join-io](https://github.com/coderaiser/join-io "join-io"):此模組會即時結合檔案,來減少要求計數。 - - [method-override](https://github.com/expressjs/method-override):即先前的 `express.methodOverride` - - [morgan](https://github.com/expressjs/morgan):即先前的 `logger` - - [passport](https://github.com/jaredhanson/passport):鑑別用的 Express 中介軟體模組。 - - [response-time](https://github.com/expressjs/response-time):即先前的 `express.responseTime` - - [serve-favicon](https://github.com/expressjs/serve-favicon):即先前的 `express.favicon` - - [serve-index](https://github.com/expressjs/serve-index):即先前的 `express.directory` - - [serve-static](https://github.com/expressjs/serve-static):此模組可提供靜態內容。 - - [static-expiry](https://github.com/paulwalker/connect-static-expiry):靜態資產的加指紋 URL 或「快取標頭」,還支援一或多個外部網域。 - - [vhost](https://github.com/expressjs/vhost):即先前的 `express.vhost` - - [view-helpers](https://github.com/madhums/node-view-helpers):Express 中介軟體模組,可提供一般 helper 方法給視圖。 - - [sriracha-admin](https://github.com/hdngr/siracha):Express 中介軟體模組,可為 Mongoose 動態產生管理網站。 +| Middleware module | Description | +| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | +| [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | +| [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | +| [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | +| [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | +| [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | +| [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | +| [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | +| [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | +| [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | +| [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | +| [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | +| [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | +| [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | +| [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | +| [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | +| [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | -Connect/Express 團隊不再支援 Connect 先前隨附的一些中介軟體模組。這些模組會以替代模組取代,或者應以更好的模組取代。請使用下列其中一個替代項目: +## Additional middleware modules - - express.cookieParser - - [cookies](https://github.com/jed/cookies) 和 [keygrip](https://github.com/jed/keygrip) - - express.limit - - [raw-body](https://github.com/stream-utils/raw-body) - - express.multipart - - [connect-busboy](https://github.com/mscdex/connect-busboy) - - [multer](https://github.com/expressjs/multer) - - [connect-multiparty](https://github.com/superjoe30/connect-multiparty) - - express.query - - [qs](https://github.com/visionmedia/node-querystring) - - express.staticCache - - [st](https://github.com/isaacs/st) - - [connect-static](https://github.com/andrewrk/connect-static) +These are some additional popular middleware modules. -如需其他的中介軟體模組,請參閱: +{% include community-caveat.html %} - - [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) - - [expressjs](https://github.com/expressjs) +| Middleware module | Description | +| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [helmet](https://github.com/helmetjs/helmet):此模組會設定各種 HTTP 標頭,有助於保護您應用程式的安全。 | Helps secure your apps by setting various HTTP headers. | +| [passport](https://github.com/jaredhanson/passport):鑑別用的 Express 中介軟體模組。 | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | diff --git a/zh-tw/resources/middleware/body-parser.md b/zh-tw/resources/middleware/body-parser.md new file mode 100644 index 0000000000..9c3e7e0276 --- /dev/null +++ b/zh-tw/resources/middleware/body-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express body-parser middleware +menu: resources +redirect_from: ' ' +module: body-parser +--- diff --git a/zh-tw/resources/middleware/compression.md b/zh-tw/resources/middleware/compression.md new file mode 100644 index 0000000000..d288542a65 --- /dev/null +++ b/zh-tw/resources/middleware/compression.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express compression middleware +menu: resources +redirect_from: ' ' +module: compression +--- diff --git a/zh-tw/resources/middleware/connect-rid.md b/zh-tw/resources/middleware/connect-rid.md new file mode 100644 index 0000000000..95b2689265 --- /dev/null +++ b/zh-tw/resources/middleware/connect-rid.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express connect-rid middleware +menu: resources +redirect_from: ' ' +module: connect-rid +--- diff --git a/zh-tw/resources/middleware/cookie-parser.md b/zh-tw/resources/middleware/cookie-parser.md new file mode 100644 index 0000000000..55100372e3 --- /dev/null +++ b/zh-tw/resources/middleware/cookie-parser.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-parser middleware +menu: resources +redirect_from: ' ' +module: cookie-parser +--- diff --git a/zh-tw/resources/middleware/cookie-session.md b/zh-tw/resources/middleware/cookie-session.md new file mode 100644 index 0000000000..c6308fa81c --- /dev/null +++ b/zh-tw/resources/middleware/cookie-session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cookie-session middleware +menu: resources +redirect_from: ' ' +module: cookie-session +--- diff --git a/zh-tw/resources/middleware/cors.md b/zh-tw/resources/middleware/cors.md new file mode 100644 index 0000000000..4692141929 --- /dev/null +++ b/zh-tw/resources/middleware/cors.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express cors middleware +menu: resources +redirect_from: ' ' +module: cors +--- diff --git a/zh-tw/resources/middleware/errorhandler.md b/zh-tw/resources/middleware/errorhandler.md new file mode 100644 index 0000000000..3b11a1208e --- /dev/null +++ b/zh-tw/resources/middleware/errorhandler.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express errorhandler middleware +menu: resources +redirect_from: ' ' +module: errorhandler +--- diff --git a/zh-tw/resources/middleware/method-override.md b/zh-tw/resources/middleware/method-override.md new file mode 100644 index 0000000000..8dff029cd4 --- /dev/null +++ b/zh-tw/resources/middleware/method-override.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express method-override middleware +menu: resources +redirect_from: ' ' +module: method-override +--- diff --git a/zh-tw/resources/middleware/morgan.md b/zh-tw/resources/middleware/morgan.md new file mode 100644 index 0000000000..99c4c80fa9 --- /dev/null +++ b/zh-tw/resources/middleware/morgan.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express morgan middleware +menu: resources +redirect_from: ' ' +module: morgan +--- diff --git a/zh-tw/resources/middleware/multer.md b/zh-tw/resources/middleware/multer.md new file mode 100644 index 0000000000..2fffab3b73 --- /dev/null +++ b/zh-tw/resources/middleware/multer.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express multer middleware +menu: resources +redirect_from: ' ' +module: multer +--- diff --git a/zh-tw/resources/middleware/response-time.md b/zh-tw/resources/middleware/response-time.md new file mode 100644 index 0000000000..78ee67cd32 --- /dev/null +++ b/zh-tw/resources/middleware/response-time.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express response-time middleware +menu: resources +redirect_from: ' ' +module: response-time +--- diff --git a/zh-tw/resources/middleware/serve-favicon.md b/zh-tw/resources/middleware/serve-favicon.md new file mode 100644 index 0000000000..7a1c8e6f5c --- /dev/null +++ b/zh-tw/resources/middleware/serve-favicon.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-favicon middleware +menu: resources +redirect_from: ' ' +module: serve-favicon +--- diff --git a/zh-tw/resources/middleware/serve-index.md b/zh-tw/resources/middleware/serve-index.md new file mode 100644 index 0000000000..deeb963c8f --- /dev/null +++ b/zh-tw/resources/middleware/serve-index.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-index middleware +menu: resources +redirect_from: ' ' +module: serve-index +--- diff --git a/zh-tw/resources/middleware/serve-static.md b/zh-tw/resources/middleware/serve-static.md new file mode 100644 index 0000000000..ff9bcc313e --- /dev/null +++ b/zh-tw/resources/middleware/serve-static.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express serve-static middleware +menu: resources +redirect_from: ' ' +module: serve-static +--- diff --git a/zh-tw/resources/middleware/session.md b/zh-tw/resources/middleware/session.md new file mode 100644 index 0000000000..22cf354ae7 --- /dev/null +++ b/zh-tw/resources/middleware/session.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express session middleware +menu: resources +redirect_from: ' ' +module: session +--- diff --git a/zh-tw/resources/middleware/timeout.md b/zh-tw/resources/middleware/timeout.md new file mode 100644 index 0000000000..1afa2c5dd3 --- /dev/null +++ b/zh-tw/resources/middleware/timeout.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express timeout middleware +menu: resources +redirect_from: ' ' +module: timeout +--- diff --git a/zh-tw/resources/middleware/vhost.md b/zh-tw/resources/middleware/vhost.md new file mode 100644 index 0000000000..2bad4c964f --- /dev/null +++ b/zh-tw/resources/middleware/vhost.md @@ -0,0 +1,7 @@ +--- +layout: middleware +title: Express vhost middleware +menu: resources +redirect_from: ' ' +module: vhost +--- diff --git a/zh-tw/resources/utils.md b/zh-tw/resources/utils.md new file mode 100644 index 0000000000..f58beb26e1 --- /dev/null +++ b/zh-tw/resources/utils.md @@ -0,0 +1,25 @@ +--- +layout: page +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. +menu: resources +redirect_from: " " +--- + +## 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](http://jshttp.github.io/). diff --git a/zh-tw/starter/basic-routing.md b/zh-tw/starter/basic-routing.md old mode 100755 new mode 100644 index 43ba06e680..6329957ed7 --- a/zh-tw/starter/basic-routing.md +++ b/zh-tw/starter/basic-routing.md @@ -1,24 +1,24 @@ --- layout: page title: Express 基本路由 +description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter -lang: zh-tw +redirect_from: " " --- # 基本路由 -*路由*是指判斷應用程式如何回應用戶端對特定端點的要求,而這個特定端點是一個 URI(或路徑)與一個特定的 HTTP 要求方法(GET、POST 等)。 +_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). -每一個路由可以有一或多個處理程式函數,當路由相符時,就會執行這些函數。 +Each route can have one or more handler functions, which are executed when the route is matched. 路由定義的結構如下: -
    -
    +
    +```js
     app.METHOD(PATH, HANDLER)
    -
    -
    +``` -其中: +Where: - `app` 是 `express` 的實例。 - `METHOD` 是 [HTTP 要求方法](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol)。 @@ -26,49 +26,45 @@ app.METHOD(PATH, HANDLER) - `HANDLER` 是當路由相符時要執行的函數。
    +This tutorial assumes that an instance of `express` named `app` is created and the server is running. 這項指導教學假設已建立名稱為 `app` 的 `express` 實例,且伺服器正在執行。如果您不熟悉如何建立和啟動應用程式,請參閱 [Hello world 範例](/{{ page.lang }}/starter/hello-world.html)。 +
    下列範例說明如何定義簡單的路由。 首頁中以 `Hello World!` 回應。 -
    -
    -app.get('/', function (req, res) {
    -  res.send('Hello World!');
    -});
    -
    -
    +```js +app.get('/', (req, res) => { + res.send('Hello World!') +}) +``` -對根路由 (`/`)(應用程式的首頁)發出 POST 要求時的回應: +Respond to a POST request on the root route (`/`), the application's home page: -
    -
    -app.post('/', function (req, res) {
    -  res.send('Got a POST request');
    -});
    -
    -
    +```js +app.post('/', (req, res) => { + res.send('Got a POST request') +}) +``` 對 `/user` 路由發出 PUT 要求時的回應: -
    -
    -app.put('/user', function (req, res) {
    -  res.send('Got a PUT request at /user');
    -});
    -
    -
    +```js +app.put('/user', (req, res) => { + res.send('Got a PUT request at /user') +}) +``` 對 `/user` 路由發出 DELETE 要求時的回應: -
    -
    -app.delete('/user', function (req, res) {
    -  res.send('Got a DELETE request at /user');
    -});
    -
    -
    +```js +app.delete('/user', (req, res) => { + res.send('Got a DELETE request at /user') +}) +``` 如需路由的詳細資料,請參閱[路由手冊](/{{ page.lang }}/guide/routing.html)。 + +### [Previous: Express application generator ](/{{ page.lang }}/starter/generator.html)    [Next: Serving static files in Express ](/{{ page.lang }}/starter/static-files.html) diff --git a/zh-tw/starter/examples.md b/zh-tw/starter/examples.md new file mode 100644 index 0000000000..a03e016318 --- /dev/null +++ b/zh-tw/starter/examples.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Express examples +description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. +menu: starter +redirect_from: " " +--- + +{% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} +{{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} + +## Additional examples + +These are some additional examples with more extensive integrations. + +{% include community-caveat.html %} + +- [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM +- [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM + +### [Previous: Static Files ](/{{ page.lang }}/starter/static-files.html)    [Next: FAQ ](/{{ page.lang }}/starter/faq.html) diff --git a/zh-tw/starter/faq.md b/zh-tw/starter/faq.md old mode 100755 new mode 100644 index 12f73c7e7d..c345d6240a --- a/zh-tw/starter/faq.md +++ b/zh-tw/starter/faq.md @@ -1,68 +1,96 @@ --- layout: page title: Express 常見問題 (FAQ) +description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter -lang: zh-tw +redirect_from: " " --- # 常見問題 (FAQ) ## 我該如何建立我的應用程式結構? -這個問題沒有明確答案。此答案取決於您應用程式的規模和涉及的團隊。為了盡可能靈活,Express 對於結構沒有任何的假設。 +There is no definitive answer to this question. The answer depends +on the scale of your application and the team that is involved. To be as +flexible as possible, Express makes no assumptions in terms of structure. -您可以根據自己的喜好,將路由和應用程式特定的其他邏輯放在任意數目的檔案和任何的目錄結構中。請檢視下列範例,以獲得一些啟發: +Routes and other application-specific logic can live in as many files +as you wish, in any directory structure you prefer. View the following +examples for inspiration: -* [路由清單](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) -* [路由對映](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) -* [MVC 樣式控制器](https://github.com/expressjs/express/tree/master/examples/mvc) +- [路由清單](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-47) +- [路由對映](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) +- [MVC 樣式控制器](https://github.com/expressjs/express/tree/master/examples/mvc) 此外,Express 有一些協力廠商延伸,可簡化部分這些型樣: -* [express-resource 路由](https://github.com/expressjs/express-resource) +- [express-resource 路由](https://github.com/expressjs/express-resource) ## 如何定義模型? -Express 不會注意到資料庫的存在。此概念留給協力廠商 Node 模組處理,如此可讓您與幾近全部的資料庫溝通。 +Express has no notion of a database. This concept is +left up to third-party Node modules, allowing you to +interface with nearly any database. 請參閱 [LoopBack](http://loopback.io),取得以模組為中心的 Express 型架構。 ## 如何鑑別使用者? -鑑別是 Express 另一個不涉及的自用領域。您可以使用任何您想要的鑑別方法。如需簡易使用者名稱 / 密碼方法,請參閱[這個範例](https://github.com/expressjs/express/tree/master/examples/auth)。 - +Authentication is another opinionated area that Express does not +venture into. You may use any authentication scheme you wish. +For a simple username / password scheme, see [this example](https://github.com/expressjs/express/tree/master/examples/auth). ## Express 支援哪些範本引擎? Express 支援符合 `(path, locals, callback)` 簽章的任何範本引擎。若要使範本引擎介面和快取正規化,請參閱 [consolidate.js](https://github.com/visionmedia/consolidate.js) 專案,以取得支援。未列出的範本引擎可能仍支援 Express 簽章。 +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](/{{page.lang}}/guide/using-template-engines.html). ## 如何處理 404 回應? -在 Express 中,404 回應並不是錯誤的結果,因此錯誤處理常式中介軟體不會擷取它們。會有此行為是因為 404 回應僅表示沒有額外的工作來執行;換句話說,Express 已執行所有的中介軟體函數和路由,並發現它們都沒有回應。您唯一要做的是在堆疊的最底端(其他所有函數下方),新增一個中介軟體函數,以處理 404 回應: +In Express, 404 responses are not the result of an error, so +the error-handler middleware will not capture them. This behavior is +because a 404 response simply indicates the absence of additional work to do; +in other words, Express has executed all middleware functions and routes, +and found that none of them responded. All you need to +do is add a middleware function at the very bottom of the stack (below all other functions) +to handle a 404 response: + +```js +app.use((req, res, next) => { + res.status(404).send("Sorry can't find that!") +}) +``` -
    -
    -app.use(function(req, res, next) {
    -  res.status(404).send('Sorry cant find that!');
    -});
    -
    -
    +Add routes dynamically at runtime on an instance of `express.Router()` +so the routes are not superseded by a middleware function. ## 如何設定錯誤處理程式? 錯誤處理中介軟體的定義方式,與其他中介軟體相同,差別在於引數是四個而非三個,具體來說,就是使用 `(err, req, res, next)` 簽章: -
    -
    -app.use(function(err, req, res, next) {
    -  console.error(err.stack);
    -  res.status(500).send('Something broke!');
    -});
    -
    -
    +```js +app.use((err, req, res, next) => { + console.error(err.stack) + res.status(500).send('Something broke!') +}) +``` 如需相關資訊,請參閱[錯誤處理](/{{ page.lang }}/guide/error-handling.html)。 ## 如何呈現一般 HTML? -不需要!不需要用 `res.render()` 函數來「呈現」HTML。如果您有特定的檔案,請使用 `res.sendFile()` 函數。如果您會從目錄提供許多資產,請使用 `express.static()` 中介軟體函數。 +You don't! 不需要!不需要用 `res.render()` 函數來「呈現」HTML。如果您有特定的檔案,請使用 `res.sendFile()` 函數。如果您會從目錄提供許多資產,請使用 `express.static()` 中介軟體函數。 +If you have a specific file, use the `res.sendFile()` function. +If you are serving many assets from a directory, use the `express.static()` +middleware function. + +## What version of Node.js does Express require? + +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. + +### [Previous: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/zh-tw/starter/generator.md b/zh-tw/starter/generator.md old mode 100755 new mode 100644 index 05fda6dc16..685d9b71fd --- a/zh-tw/starter/generator.md +++ b/zh-tw/starter/generator.md @@ -1,29 +1,34 @@ --- layout: page title: Express 應用程式產生器 +description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter -lang: zh-tw +redirect_from: " " --- # Express 應用程式產生器 -使用應用程式產生器工具 `express`,快速建立應用程式架構。 +Use the application generator tool, `express-generator`, to quickly create an application skeleton. -使用下列指令來安裝 `express`: +You can run the application generator with the `npx` command (available in Node.js 8.2.0). -
    -
    -$ npm install express-generator -g
    -
    -
    +```bash +$ npx express-generator +``` + +For earlier Node versions, install the application generator as a global npm package and then launch it: + +```bash +$ npm install -g express-generator +$ express +``` 使用 `-h` 選項來顯示指令選項: -
    -
    +```bash
     $ express -h
     
    -  Usage: express [options][dir]
    +  Usage: express [options] [dir]
     
       Options:
     
    @@ -34,17 +39,15 @@ $ express -h
             --pug           add pug engine support
         -H, --hogan         add hogan.js engine support
             --no-view       generate without view engine
    -    -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    +    -v, --view  add view  support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    +    -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
             --git           add .gitignore
         -f, --force         force on non-empty directory
    -
    -
    +``` -舉例來說,以下是在現行工作目錄中建立一個名為 _myapp_ 的 Express 應用程式: +舉例來說,以下是在現行工作目錄中建立一個名為 _myapp_ 的 Express 應用程式: The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: -
    -
    +```bash
     $ express --view=pug myapp
     
        create : myapp
    @@ -64,40 +67,38 @@ $ express --view=pug myapp
        create : myapp/views/error.pug
        create : myapp/bin
        create : myapp/bin/www
    -
    -
    +``` 然後安裝相依項目: -
    -
    +```bash
     $ cd myapp
     $ npm install
    -
    -
    +``` 在 MacOS 或 Linux 中,使用下列指令來執行應用程式: -
    -
    +```bash
     $ DEBUG=myapp:* npm start
    -
    -
    +``` 在 Windows 中,使用下列指令: -
    -
    +```bash
     > set DEBUG=myapp:* & npm start
    -
    -
    +``` + +On Windows PowerShell, use this command: -然後在瀏覽器中載入 `http://localhost:3000/`,以存取應用程式。 +```bash +PS> $env:DEBUG='myapp:*'; npm start +``` -產生的應用程式具有如下的目錄結構: +Then, load `http://localhost:3000/` in your browser to access the app. -
    -
    +The generated app has the following directory structure:
    +
    +```bash
     .
     ├── app.js
     ├── bin
    @@ -117,9 +118,10 @@ $ DEBUG=myapp:* npm start
         └── layout.pug
     
     7 directories, 9 files
    -
    -
    +```
    -使用產生器來建立應用程式結構,只是多種用來建立 Express 應用程式結構的其中一種方式。您有權使用這種結構,或是加以修改盡量符合您的需求。 +The app structure created by the generator is just one of many ways to structure Express apps. Feel free to use this structure or modify it to best suit your needs.
    + +### [Previous: Hello World ](/{{ page.lang }}/starter/hello-world.html)    [Next: Basic routing](/{{ page.lang }}/starter/basic-routing.html) diff --git a/zh-tw/starter/hello-world.md b/zh-tw/starter/hello-world.md old mode 100755 new mode 100644 index e6748cccfb..ea87c0a304 --- a/zh-tw/starter/hello-world.md +++ b/zh-tw/starter/hello-world.md @@ -1,22 +1,20 @@ --- layout: page title: Express "Hello World" 範例 +description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter -lang: zh-tw +redirect_from: " " --- # Hello world 範例
    +Embedded below is essentially the simplest Express app you can create. 本質上,這是您所能建立的最簡易 Express 應用程式。它是單一檔案應用程式 — 與您使用 [Express 產生器](/{{ page.lang }}/starter/generator.html)所產生的結果*不同*,Express 產生器會建立完整應用程式框架,其中含有眾多 JavaScript 檔案、Jade 範本,以及各種用途的子目錄。 -
    - -首先請建立一個名為 `myapp` 的目錄,切換至該目錄,並執行 `npm init`。然後按照[安裝手冊](/{{ page.lang }}/starter/installing.html),將 `express` 安裝成一個相依關係。 -在 `myapp` 目錄中,建立名為 `app.js` 的檔案,並新增下列程式碼: +
    -
    -
    +```js
     const express = require('express')
     const app = express()
     const port = 3000
    @@ -26,12 +24,17 @@ app.get('/', (req, res) => {
     })
     
     app.listen(port, () => {
    -  console.log(`Example app listening at http://localhost:${port}`)
    +  console.log(`Example app listening on port ${port}`)
     })
    -
    -
    +``` -應用程式會啟動伺服器,並在埠 3000 接聽連線。應用程式對指向根 URL (`/`) 或*路由*的要求,以 "Hello World!" 回應。對於其他每一個路徑,它的回應是 **404 找不到**。 +This app starts a server and listens on port 3000 for connections. 應用程式會啟動伺服器,並在埠 3000 接聽連線。應用程式對指向根 URL (`/`) 或_路由_的要求,以 "Hello World!" 回應。對於其他每一個路徑,它的回應是 **404 找不到**。 + +### Running Locally + +首先請建立一個名為 `myapp` 的目錄,切換至該目錄,並執行 `npm init`。然後按照[安裝手冊](/{{ page.lang }}/starter/installing.html),將 `express` 安裝成一個相依關係。 Then, install `express` as a dependency, as per the [installation guide](/{{ page.lang }}/starter/installing.html). + +在 `myapp` 目錄中,建立名為 `app.js` 的檔案,並新增下列程式碼:
    `req`(要求)和 `res`(回應)與 Node 提供的物件完全相同,因此您可以呼叫 `req.pipe()`、`req.on('data', callback)`,以及任何您要執行的項目,而不需要 Express 涉及。 @@ -39,11 +42,10 @@ app.listen(port, () => { 使用下列指令來執行應用程式: -
    -
    +```bash
     $ node app.js
    -
    -
    +``` 然後在瀏覽器中載入 [http://localhost:3000/](http://localhost:3000/),以查看輸出。 +### [Previous: Installing ](/{{ page.lang }}/starter/installing.html)    [Next: Express Generator ](/{{ page.lang }}/starter/generator.html) diff --git a/zh-tw/starter/installing.md b/zh-tw/starter/installing.md old mode 100755 new mode 100644 index ac2c3fb039..9cf5af24e8 --- a/zh-tw/starter/installing.md +++ b/zh-tw/starter/installing.md @@ -1,56 +1,55 @@ --- layout: page title: 安裝 Express +description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter -lang: zh-tw +redirect_from: " " --- # 安裝 假設您已安裝 [Node.js](https://nodejs.org/),請建立目錄來保留您的應用程式,並使它成為您的工作目錄。 -
    -
    +- [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher.
    +- [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher.
    +
    +```bash
     $ mkdir myapp
     $ cd myapp
    -
    -
    +``` +Use the `npm init` command to create a `package.json` file for your application. 使用 `npm init` 指令,為您的應用程式建立 `package.json` 檔。如需 `package.json` 如何運作的相關資訊,請參閱 [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json)。 -
    -
    +```bash
     $ npm init
    -
    -
    +``` -這個指令會提示您提供一些事項,例如:您應用程式的名稱和版本。現在,您只需按下 RETURN 鍵,接受大部分的預設值,但下列除外: +This command prompts you for a number of things, such as the name and version of your application. +For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception: -
    -
    +```
     entry point: (index.js)
    -
    -
    - -輸入 `app.js`,或您所要的主要檔名稱。如果您希望其名稱是 `index.js`,請按 RETURN 鍵,接受建議的預設檔名。 +``` -現在,將 Express 安裝在 `myapp` 目錄中,並儲存在相依關係清單中。例如: +輸入 `app.js`,或您所要的主要檔名稱。如果您希望其名稱是 `index.js`,請按 RETURN 鍵,接受建議的預設檔名。 If you want it to be `index.js`, hit RETURN to accept the suggested default file name. +現在,將 Express 安裝在 `myapp` 目錄中,並儲存在相依關係清單中。例如: For example: -
    -
    -$ npm install express --save
    -
    -
    +```bash +$ npm install express +``` 如果只想暫時安裝 Express,而不新增至相依關係清單,請省略 `--save` 選項: -
    -
    -$ npm install express
    -
    -
    +```bash +$ npm install express --no-save +```
    + 安裝 Node 模組時,如果指定了 `--save` 選項,則會將這些模組新增至 `package.json` 檔中的 `dependencies` 清單。之後,當您在 `app` 目錄中執行 `npm install` 時,就會自動安裝相依關係清單中的模組。 + Then, afterwards, running `npm install` in the app directory will automatically install modules in the dependencies list.
    + +### [Next: Hello World ](/{{ page.lang }}/starter/hello-world.html) \ No newline at end of file diff --git a/zh-tw/starter/static-files.md b/zh-tw/starter/static-files.md old mode 100755 new mode 100644 index 152f6f6f5f..4e8433ba05 --- a/zh-tw/starter/static-files.md +++ b/zh-tw/starter/static-files.md @@ -1,73 +1,81 @@ --- layout: page title: 在 Express 中提供靜態檔案 +description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter -lang: zh-tw +redirect_from: " " --- # 在 Express 中提供靜態檔案 -如果要提供影像、CSS 檔案和 JavaScript 檔案等之類的靜態檔案,請使用 Express 中的 `express.static` 內建中介軟體函數。 +To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express. -將含有靜態資產的目錄名稱傳遞給 `express.static` 中介軟體函數,就能直接開始提供檔案。舉例來說,使用下列程式碼在名稱是 `public` 的目錄中,提供影像、CSS 檔案和 JavaScript 檔案: +The function signature is: -
    -
    -app.use(express.static('public'));
    -
    -
    +```js +express.static(root, [options]) +``` + +The `root` argument specifies the root directory from which to serve static assets. +For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). + +For example, use the following code to serve images, CSS files, and JavaScript files in a directory named `public`: + +```js +app.use(express.static('public')) +``` 現在,您可以載入位於 `public` 目錄中的檔案: -
    -
    +```text
     http://localhost:3000/images/kitten.jpg
     http://localhost:3000/css/style.css
     http://localhost:3000/js/app.js
     http://localhost:3000/images/bg.png
     http://localhost:3000/hello.html
    -
    -
    +```
    Express 會查閱靜態目錄的相對檔案,因此靜態目錄的名稱不是 URL 的一部分。
    -如果要使用多個靜態資產目錄,請呼叫 `express.static` 中介軟體函數多次: +To use multiple static assets directories, call the `express.static` middleware function multiple times: -
    -
    -app.use(express.static('public'));
    -app.use(express.static('files'));
    -
    -
    +```js +app.use(express.static('public')) +app.use(express.static('files')) +``` -Express 在查閱檔案時,會依照您使用 `express.static` 中介軟體函數來設定靜態目錄的順序。 +Express looks up the files in the order in which you set the static directories with the `express.static` middleware function. -如果要為 `express.static` 函數所提供的檔案,建立虛擬路徑字首(其中的路徑事實上不存在於檔案系統中),請為靜態目錄[指定裝載路徑](/{{ page.lang }}/4x/api.html#app.use),如下所示: +{% capture alert_content %} +For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. +{% endcapture %} +{% include admonitions/note.html content=alert_content %} -
    -
    -app.use('/static', express.static('public'));
    -
    -
    +To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: + +```js +app.use('/static', express.static('public')) +``` 現在,您可以透過 `/static` 路徑字首,來載入 `public` 目錄中的檔案。 -
    -
    +```text
     http://localhost:3000/static/images/kitten.jpg
     http://localhost:3000/static/css/style.css
     http://localhost:3000/static/js/app.js
     http://localhost:3000/static/images/bg.png
     http://localhost:3000/static/hello.html
    -
    -
    +``` + +不過,您提供給 `express.static` 函數的路徑,是相對於您從中啟動 `node` 程序的目錄。如果您是從另一個目錄執行 Express 應用程式,保險作法是使用您想提供之目錄的絕對路徑: If you run the express app from another directory, it's safer to use the absolute path of the directory that you want to serve: + +```js +const path = require('path') +app.use('/static', express.static(path.join(__dirname, 'public'))) +``` -不過,您提供給 `express.static` 函數的路徑,是相對於您從中啟動 `node` 程序的目錄。如果您是從另一個目錄執行 Express 應用程式,保險作法是使用您想提供之目錄的絕對路徑: +For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static.html). -
    -
    -app.use('/static', express.static(__dirname + '/public'));
    -
    -
    +### [Previous: Basic Routing ](/{{ page.lang }}/starter/basic-routing.html)    [Next: More examples ](/{{ page.lang }}/starter/examples.html) diff --git a/zh-tw/support/index.md b/zh-tw/support/index.md new file mode 100644 index 0000000000..2b70a1fb48 --- /dev/null +++ b/zh-tw/support/index.md @@ -0,0 +1,27 @@ +--- +layout: page +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. +menu: support +--- + +# Version Support + +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**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | +| [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | +| [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | +| [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | +| **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | +| **v0.14.x**{: .eol } | 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](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page)