Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 91 additions & 12 deletions src/content/api/4x/api/application/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,21 @@ However, the other methods listed above work in exactly the same way.

To route methods that translate to invalid JavaScript variable names, use the bracket notation. For example, `app['m-search']('/', function ...`.

```js ins={10}
app.get('/', function (req, res) {
res.send('GET request to homepage');
});

app.post('/', function (req, res) {
res.send('POST request to homepage');
});

// methods that are invalid JavaScript variable names use bracket notation
app['m-search']('/', function (req, res) {
res.send('M-SEARCH request to homepage');
});
```

<Alert type="info">

The `app.get()` function is automatically called for the HTTP `HEAD` method in addition to the
Expand Down Expand Up @@ -1127,18 +1142,28 @@ app.get('title'); // "My Site"

The following table lists application settings.

Note that sub-apps will:
<Alert type="info">

Sub-apps will:

- Not inherit the value of settings that have a default value. You must set the value in the sub-app.
- Inherit the value of settings with no default value; these are explicitly noted in the table below.

Exceptions: Sub-apps will inherit the value of `trust proxy` even though it has a default value (for backward-compatibility);
Sub-apps will not inherit the value of `view cache` in production (when `NODE_ENV` is "production").

</Alert>

<Signature attributesTitle="Settings">
<Fragment slot="attributes">
<Param name="case sensitive routing" type="Boolean" default="N/A (undefined)">
Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes. When disabled, "/Foo" and "/foo" are treated the same. **NOTE**: Sub-apps will inherit the value of this setting.
Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes. When disabled, "/Foo" and "/foo" are treated the same.

<Alert type="info">

Sub-apps will inherit the value of this setting.

</Alert>
</Param>
<Param name="env" type="String" default='process.env.NODE_ENV (NODE_ENV environment variable) or "development" if NODE_ENV is not set.'>
Environment mode. Be sure to set to "production" in a production environment; see [Production best practices: performance and reliability](/advanced/best-practice-performance#things-to-do-in-your-environment--setup).
Expand All @@ -1150,38 +1175,89 @@ Sub-apps will not inherit the value of `view cache` in production (when `NODE_EN
Specifies the default JSONP callback name.
</Param>
<Param name="json escape" type="Boolean" default="N/A (undefined)">
Enable escaping JSON responses from the `res.json`, `res.jsonp`, and `res.send` APIs. This will escape the characters `<`, `>`, and `&` as Unicode escape sequences in JSON. The purpose of this is to assist with [mitigating certain types of persistent XSS attacks](https://blog.mozilla.org/security/2017/07/18/web-service-audits-firefox-accounts/) when clients sniff responses for HTML. **NOTE**: Sub-apps will inherit the value of this setting.
Enable escaping JSON responses from the `res.json`, `res.jsonp`, and `res.send` APIs. This will escape the characters `<`, `>`, and `&` as Unicode escape sequences in JSON. The purpose of this is to assist with [mitigating certain types of persistent XSS attacks](https://blog.mozilla.org/security/2017/07/18/web-service-audits-firefox-accounts/) when clients sniff responses for HTML.

<Alert type="info">

Sub-apps will inherit the value of this setting.

</Alert>
</Param>
<Param name="json replacer" type="Function | Array" default="N/A (undefined)">
The ['replacer' argument used by `JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_replacer_parameter). **NOTE**: Sub-apps will inherit the value of this setting.
The ['replacer' argument used by `JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_replacer_parameter).

<Alert type="info">

Sub-apps will inherit the value of this setting.

</Alert>
</Param>
<Param name="json spaces" type="Number | String" default="N/A (undefined)">
The ['space' argument used by `JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_space_parameter). This is typically set to the number of spaces to use to indent prettified JSON. **NOTE**: Sub-apps will inherit the value of this setting.
The ['space' argument used by `JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_space_parameter). This is typically set to the number of spaces to use to indent prettified JSON.

<Alert type="info">

Sub-apps will inherit the value of this setting.

</Alert>
</Param>
<Param name="query parser" type="Boolean | String | Function" default='"extended"'>
Disable query parsing by setting the value to `false`, or set the query parser to use either "simple" or "extended" or a custom query string parsing function. The simple query parser is based on Node's native query parser, [querystring](https://nodejs.org/api/querystring.html). The extended query parser is based on [qs](https://www.npmjs.com/package/qs). A custom query string parsing function will receive the complete query string, and must return an object of query keys and their values.
</Param>
<Param name="strict routing" type="Boolean" default="N/A (undefined)">
Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different. Otherwise, the router treats "/foo" and "/foo/" as the same. **NOTE**: Sub-apps will inherit the value of this setting.
Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different. Otherwise, the router treats "/foo" and "/foo/" as the same.

<Alert type="info">

Sub-apps will inherit the value of this setting.

</Alert>
</Param>
<Param name="subdomain offset" type="Number" default="2">
The number of dot-separated parts of the host to remove to access subdomain.
</Param>
<Param name="trust proxy" type="Boolean | String | Number | Function | Array" default="false (disabled)">
Indicates the app is behind a front-facing proxy, and to use the `X-Forwarded-*` headers to determine the connection and the IP address of the client. NOTE: `X-Forwarded-*` headers are easily spoofed and the detected IP addresses are unreliable. When enabled, Express attempts to determine the IP address of the client connected through the front-facing proxy, or series of proxies. The `req.ips` property, then contains an array of IP addresses the client is connected through. To enable it, use the values described in the trust proxy options table below. The `trust proxy` setting is implemented using the [proxy-addr](https://www.npmjs.com/package/proxy-addr) package. For more information, see its documentation. **NOTE**: Sub-apps _will_ inherit the value of this setting, even though it has a default value.
Indicates the app is behind a front-facing proxy, and to use the `X-Forwarded-*` headers to determine the connection and the IP address of the client.

<Alert type="info">

`X-Forwarded-*` headers are easily spoofed and the detected IP addresses are unreliable.

</Alert>

When enabled, Express attempts to determine the IP address of the client connected through the front-facing proxy, or series of proxies. The `req.ips` property, then contains an array of IP addresses the client is connected through. To enable it, use the values described in the trust proxy options table below. The `trust proxy` setting is implemented using the [proxy-addr](https://www.npmjs.com/package/proxy-addr) package. For more information, see its documentation.

<Alert type="info">

Sub-apps _will_ inherit the value of this setting, even though it has a default value.

</Alert>
</Param>
<Param name="views" type="String or Array" default="process.cwd() + '/views'">
<Param name="views" type="String | Array" default="process.cwd() + '/views'">
A directory or an array of directories for the application's views. If an array, the views are looked up in the order they occur in the array.
</Param>
<Param name="view cache" type="Boolean" default="true in production, otherwise undefined.">
Enables view template compilation caching. **NOTE**: Sub-apps will not inherit the value of this setting in production (when `NODE_ENV` is "production").
Enables view template compilation caching.

<Alert type="info">

Sub-apps will not inherit the value of this setting in production (when `NODE_ENV` is "production").

</Alert>
</Param>
<Param name="view engine" type="String" default="N/A (undefined)">
The default engine extension to use when omitted. **NOTE**: Sub-apps will inherit the value of this setting.
The default engine extension to use when omitted.

<Alert type="info">

Sub-apps will inherit the value of this setting.

</Alert>
</Param>
<Param name="x-powered-by" type="Boolean" default="true">
Enables the "X-Powered-By: Express" HTTP header.
</Param>

</Fragment>
</Signature>

Expand Down Expand Up @@ -1239,7 +1315,11 @@ app.set('trust proxy', function (ip) {

#### Options for `etag` setting

**NOTE**: These settings apply only to dynamic files, not static files. The `express.static` middleware ignores these settings.
<Alert type="info">

These settings apply only to dynamic files, not static files. The `express.static` middleware ignores these settings.

</Alert>

The ETag functionality is implemented using the [etag](https://www.npmjs.com/package/etag) package. For more information, see its documentation.

Expand Down Expand Up @@ -1305,7 +1385,6 @@ app.use(function (req, res, next) {
```

<Alert type="info">
**NOTE**

Sub-apps will:

Expand Down
141 changes: 139 additions & 2 deletions src/content/api/4x/api/express/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,33 @@ may not be a function and instead a string or other user-input.

</Alert>

```cjs title="index.cjs" ins={5}
var express = require('express');
var app = express();

// parse requests with a Content-Type of application/json
app.use(express.json());

app.post('/profile', function (req, res) {
console.dir(req.body);
res.json(req.body);
});
```

```mjs title="index.mjs" ins={6}
import express from 'express';

const app = express();

// parse requests with a Content-Type of application/json
app.use(express.json());

app.post('/profile', (req, res) => {
console.dir(req.body);
res.json(req.body);
});
```

### express.raw()

<Signature returns="Function" since="v4.17.0">
Expand Down Expand Up @@ -148,6 +175,33 @@ Testing that `req.body` is a `Buffer` before calling buffer methods is recommend

</Alert>

```cjs title="index.cjs" ins={5}
var express = require('express');
var app = express();

// parse requests with a Content-Type of application/octet-stream into a Buffer
app.use(express.raw());

app.post('/upload', function (req, res) {
console.dir(Buffer.isBuffer(req.body)); // => true
res.send('received ' + req.body.length + ' bytes');
});
```

```mjs title="index.mjs" ins={6}
import express from 'express';

const app = express();

// parse requests with a Content-Type of application/octet-stream into a Buffer
app.use(express.raw());

app.post('/upload', (req, res) => {
console.dir(Buffer.isBuffer(req.body)); // => true
res.send(`received ${req.body.length} bytes`);
});
```

### express.Router()

<Signature returns="Router">
Expand Down Expand Up @@ -194,7 +248,13 @@ For more information, see [Router](/api/router/).
[dotfiles](#dotfiles) below.
</Param>
<Param name="etag" type="Boolean" default="true">
Enable or disable etag generation. NOTE: `express.static` always sends weak ETags.
Enable or disable etag generation.

<Alert type="info">

`express.static` always sends weak ETags.

</Alert>
</Param>
<Param name="extensions" type="String[] | Boolean" default="false">
Sets file extension fallbacks: If a file is not found, search for files with the specified
Expand Down Expand Up @@ -302,7 +362,10 @@ Arguments:

Here is an example of using the `express.static` middleware function with an elaborate options object:

```js
```cjs title="index.cjs" ins={16}
var express = require('express');
var app = express();

var options = {
dotfiles: 'ignore',
etag: false,
Expand All @@ -318,6 +381,26 @@ var options = {
app.use(express.static('public', options));
```

```mjs title="index.mjs" ins={17}
import express from 'express';

const app = express();

const options = {
dotfiles: 'ignore',
etag: false,
extensions: ['htm', 'html'],
index: false,
maxAge: '1d',
redirect: false,
setHeaders: (res, path, stat) => {
res.set('x-timestamp', Date.now());
},
};

app.use(express.static('public', options));
```

### express.text()

<Signature returns="Function" since="v4.17.0">
Expand Down Expand Up @@ -381,6 +464,33 @@ Testing that `req.body` is a string before calling string methods is recommended

</Alert>

```cjs title="index.cjs" ins={5}
var express = require('express');
var app = express();

// parse requests with a Content-Type of text/plain into a string
app.use(express.text());

app.post('/', function (req, res) {
console.dir(typeof req.body); // => 'string'
res.send(req.body);
});
```

```mjs title="index.mjs" ins={6}
import express from 'express';

const app = express();

// parse requests with a Content-Type of text/plain into a string
app.use(express.text());

app.post('/', (req, res) => {
console.dir(typeof req.body); // => 'string'
res.send(req.body);
});
```

### express.urlencoded()

<Signature returns="Function" since="v4.16.0">
Expand Down Expand Up @@ -457,3 +567,30 @@ fail in multiple ways, for example `foo` may not be there or may not be a string
may not be a function and instead a string or other user-input.

</Alert>

```cjs title="index.cjs" ins={5}
var express = require('express');
var app = express();

// parse requests with a Content-Type of application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));

app.post('/profile', function (req, res) {
console.dir(req.body);
res.json(req.body);
});
```

```mjs title="index.mjs" ins={6}
import express from 'express';

const app = express();

// parse requests with a Content-Type of application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));

app.post('/profile', (req, res) => {
console.dir(req.body);
res.json(req.body);
});
```
Loading
Loading