- Spec files
npm-express
Describes: pkg:npm/express@4.21.x
- Description
- Fast, unopinionated, minimalist web framework for Node.js
- Author
- tessl
- Last updated
response.md docs/
1# Response Handling23Enhanced response object with Express-specific methods for sending responses, setting headers, handling cookies, and content negotiation.45## Capabilities67### Response Sending89Send various types of responses including text, JSON, files, and status codes.1011```javascript { .api }12/**13* Send response with automatic content type detection14* @param {any} [body] - Response body (string, Buffer, object, etc.)15* @returns {Response} Response instance for chaining16*/17res.send(body?: any): Response;1819/**20* Send JSON response21* @param {any} [obj] - Object to serialize as JSON22* @returns {Response} Response instance for chaining23*/24res.json(obj?: any): Response;2526/**27* Send JSONP response for cross-domain requests28* @param {any} [obj] - Object to serialize as JSONP29* @returns {Response} Response instance for chaining30*/31res.jsonp(obj?: any): Response;3233/**34* Send status code only35* @param {number} statusCode - HTTP status code36* @returns {Response} Response instance for chaining37*/38res.sendStatus(statusCode: number): Response;39```4041**Usage Examples:**4243```javascript44app.get('/text', (req, res) => {45res.send('Hello World!');46});4748app.get('/html', (req, res) => {49res.send('<h1>Hello HTML!</h1>');50});5152app.get('/json', (req, res) => {53res.json({ message: 'Hello JSON!', timestamp: new Date() });54});5556app.get('/jsonp', (req, res) => {57res.jsonp({ data: 'JSONP response' });58// With callback: /jsonp?callback=myCallback59// Returns: myCallback({"data":"JSONP response"});60});6162app.get('/status-only', (req, res) => {63res.sendStatus(204); // No Content64});6566app.post('/created', (req, res) => {67res.sendStatus(201); // Created68});6970app.get('/not-found', (req, res) => {71res.sendStatus(404); // Not Found72});73```7475### File Handling7677Send files and trigger downloads with proper headers and options.7879```javascript { .api }80/**81* Send file from file system82* @param {string} path - Path to file (absolute or relative to cwd)83* @param {SendFileOptions} [options] - File sending options84* @param {Function} [callback] - Callback function for completion/errors85*/86res.sendFile(path: string, options?: SendFileOptions, callback?: (err?: Error) => void): void;8788/**89* Trigger file download with Content-Disposition header90* @param {string} path - Path to file91* @param {string} [filename] - Filename for download (defaults to basename)92* @param {SendFileOptions} [options] - File sending options93* @param {Function} [callback] - Callback function for completion/errors94*/95res.download(path: string, filename?: string, options?: SendFileOptions, callback?: (err?: Error) => void): void;9697/**98* File sending options99*/100interface SendFileOptions {101/** Maximum age for caching (milliseconds) */102maxAge?: number;103/** Root directory for relative paths */104root?: string;105/** Last-Modified header (default: true) */106lastModified?: boolean;107/** Custom headers to set */108headers?: { [key: string]: string };109/** Enable dot files (default: false) */110dotfiles?: 'allow' | 'deny' | 'ignore';111/** Accept ranges (default: true) */112acceptRanges?: boolean;113/** Cache control immutable (default: false) */114immutable?: boolean;115}116```117118**Usage Examples:**119120```javascript121const path = require('path');122123// Send file with absolute path124app.get('/download/report', (req, res) => {125const filePath = path.join(__dirname, 'reports', 'monthly.pdf');126res.sendFile(filePath, (err) => {127if (err) {128res.status(404).send('File not found');129}130});131});132133// Send file with options134app.get('/static/:filename', (req, res) => {135res.sendFile(req.params.filename, {136root: path.join(__dirname, 'public'),137maxAge: 86400000, // 1 day138headers: {139'X-Sent': 'true'140}141}, (err) => {142if (err) {143res.status(err.status || 500).send('Error sending file');144}145});146});147148// Trigger file download149app.get('/download/:filename', (req, res) => {150const filePath = path.join(__dirname, 'downloads', req.params.filename);151res.download(filePath, (err) => {152if (err) {153res.status(404).send('File not found');154}155});156});157158// Download with custom filename159app.get('/export/users', (req, res) => {160const filePath = path.join(__dirname, 'temp', 'users-export.csv');161res.download(filePath, 'my-users.csv');162});163```164165### Status and Headers166167Set response status codes and headers for proper HTTP communication.168169```javascript { .api }170/**171* Set response status code172* @param {number} statusCode - HTTP status code173* @returns {Response} Response instance for chaining174*/175res.status(statusCode: number): Response;176177/**178* Set response header(s)179* @param {string | object} field - Header name or header object180* @param {string} [value] - Header value (when field is string)181* @returns {Response} Response instance for chaining182*/183res.set(field: string | { [key: string]: string }, value?: string): Response;184185/**186* Alias for res.set()187* @param {string | object} field - Header name or header object188* @param {string} [value] - Header value (when field is string)189* @returns {Response} Response instance for chaining190*/191res.header(field: string | { [key: string]: string }, value?: string): Response;192193/**194* Get response header value195* @param {string} field - Header name196* @returns {string | undefined} Header value or undefined197*/198res.get(field: string): string | undefined;199200/**201* Append value to response header202* @param {string} field - Header name203* @param {string | string[]} value - Value(s) to append204* @returns {Response} Response instance for chaining205*/206res.append(field: string, value: string | string[]): Response;207```208209**Usage Examples:**210211```javascript212// Set status and send response213app.get('/api/users/:id', (req, res) => {214const user = findUser(req.params.id);215216if (!user) {217return res.status(404).json({ error: 'User not found' });218}219220res.status(200).json(user);221});222223// Set individual headers224app.get('/api/data', (req, res) => {225res.set('X-API-Version', '1.0');226res.set('X-Rate-Limit', '1000');227res.json({ data: 'example' });228});229230// Set multiple headers at once231app.get('/secure-data', (req, res) => {232res.set({233'X-Content-Type-Options': 'nosniff',234'X-Frame-Options': 'DENY',235'X-XSS-Protection': '1; mode=block'236});237res.json({ sensitive: 'data' });238});239240// Append to headers241app.get('/cors-endpoint', (req, res) => {242res.append('Access-Control-Allow-Methods', 'GET');243res.append('Access-Control-Allow-Methods', 'POST');244res.json({ message: 'CORS enabled' });245});246247// Check existing headers248app.use((req, res, next) => {249res.set('X-Request-ID', generateId());250next();251});252253app.get('/check-headers', (req, res) => {254const requestId = res.get('X-Request-ID');255res.json({ requestId });256});257```258259### Content Type Management260261Set and manage response content types with proper MIME type handling.262263```javascript { .api }264/**265* Set Content-Type header based on file extension or MIME type266* @param {string} type - File extension or MIME type267* @returns {Response} Response instance for chaining268*/269res.type(type: string): Response;270271/**272* Set Vary header for content negotiation273* @param {string} field - Header field to vary on274* @returns {Response} Response instance for chaining275*/276res.vary(field: string): Response;277278/**279* Set response format based on Accept header280* @param {Object} obj - Object with format handlers281* @returns {Response} Response instance for chaining282*/283res.format(obj: { [key: string]: () => void }): Response;284```285286**Usage Examples:**287288```javascript289// Set content type by extension290app.get('/xml-data', (req, res) => {291res.type('xml');292res.send('<data>XML content</data>');293});294295// Set content type by MIME type296app.get('/pdf-report', (req, res) => {297res.type('application/pdf');298// Send PDF data...299});300301// Content negotiation with format302app.get('/api/users', (req, res) => {303const users = getUsers();304305res.format({306'text/plain': () => {307res.send(users.map(u => u.name).join('\n'));308},309'text/html': () => {310res.send('<ul>' + users.map(u => `<li>${u.name}</li>`).join('') + '</ul>');311},312'application/json': () => {313res.json(users);314},315'application/xml': () => {316res.type('xml');317res.send(convertToXML(users));318},319'default': () => {320res.status(406).send('Not Acceptable');321}322});323});324325// Set Vary header for caching326app.get('/api/content', (req, res) => {327res.vary('Accept-Encoding');328res.vary('Accept-Language');329res.json({ content: 'varies by encoding and language' });330});331```332333### Redirects334335Redirect requests to different URLs with proper status codes.336337```javascript { .api }338/**339* Redirect request to specified URL with optional status code340* @param {number} [status] - HTTP status code (default: 302)341* @param {string} url - URL to redirect to342*/343res.redirect(status: number, url: string): void;344res.redirect(url: string): void;345```346347**Usage Examples:**348349```javascript350// Temporary redirect (302)351app.get('/old-page', (req, res) => {352res.redirect('/new-page');353});354355// Permanent redirect (301)356app.get('/legacy-api', (req, res) => {357res.redirect(301, '/api/v2');358});359360// Redirect with query parameters361app.get('/search', (req, res) => {362if (!req.query.q) {363return res.redirect('/search?q=default');364}365res.send(`Searching for: ${req.query.q}`);366});367368// Conditional redirects369app.get('/dashboard', (req, res) => {370if (!req.user) {371return res.redirect('/login');372}373res.send('Dashboard content');374});375376// External redirects377app.get('/external', (req, res) => {378res.redirect('https://external-site.com/page');379});380```381382### Cookie Management383384Set and clear cookies with various options for session management and user preferences.385386```javascript { .api }387/**388* Set cookie with name, value, and options389* @param {string} name - Cookie name390* @param {string} value - Cookie value391* @param {CookieOptions} [options] - Cookie options392* @returns {Response} Response instance for chaining393*/394res.cookie(name: string, value: string, options?: CookieOptions): Response;395396/**397* Clear cookie by name with optional options398* @param {string} name - Cookie name to clear399* @param {CookieOptions} [options] - Cookie options (must match original)400* @returns {Response} Response instance for chaining401*/402res.clearCookie(name: string, options?: CookieOptions): Response;403404/**405* Cookie configuration options406*/407interface CookieOptions {408/** Cookie domain */409domain?: string;410/** Cookie path (default: '/') */411path?: string;412/** Secure cookie (HTTPS only) */413secure?: boolean;414/** HTTP only cookie (not accessible via JavaScript) */415httpOnly?: boolean;416/** Expiration date */417expires?: Date;418/** Max age in milliseconds */419maxAge?: number;420/** SameSite attribute */421sameSite?: boolean | 'lax' | 'strict' | 'none';422/** Signed cookie (requires cookie-parser secret) */423signed?: boolean;424}425```426427**Usage Examples:**428429```javascript430// Basic cookie431app.get('/set-cookie', (req, res) => {432res.cookie('username', 'john_doe');433res.send('Cookie set');434});435436// Cookie with options437app.post('/login', (req, res) => {438res.cookie('session_id', generateSessionId(), {439httpOnly: true,440secure: process.env.NODE_ENV === 'production',441maxAge: 24 * 60 * 60 * 1000, // 24 hours442sameSite: 'strict'443});444res.json({ message: 'Logged in successfully' });445});446447// Persistent cookie448app.get('/remember-me', (req, res) => {449const expires = new Date();450expires.setFullYear(expires.getFullYear() + 1); // 1 year from now451452res.cookie('remember_token', 'abc123', {453expires: expires,454httpOnly: true,455secure: true456});457res.send('Remember me cookie set');458});459460// Clear cookie461app.post('/logout', (req, res) => {462res.clearCookie('session_id');463res.clearCookie('remember_token');464res.json({ message: 'Logged out successfully' });465});466467// Clear cookie with matching options468app.get('/clear-secure-cookie', (req, res) => {469res.clearCookie('secure_data', {470path: '/admin',471secure: true,472httpOnly: true473});474res.send('Secure cookie cleared');475});476```477478### Template Rendering479480Render views using configured template engines with local variables.481482```javascript { .api }483/**484* Render view template with locals and send as response485* @param {string} view - View name/path486* @param {Object} [locals] - Local variables for template487* @param {Function} [callback] - Callback function for completion/errors488*/489res.render(view: string, locals?: any, callback?: (err: Error | null, html?: string) => void): void;490```491492**Usage Examples:**493494```javascript495// Set view engine496app.set('view engine', 'ejs');497app.set('views', './views');498499// Basic view rendering500app.get('/', (req, res) => {501res.render('index');502});503504// Render with local variables505app.get('/user/:id', (req, res) => {506const user = findUser(req.params.id);507res.render('user-profile', {508user: user,509title: `${user.name}'s Profile`,510currentYear: new Date().getFullYear()511});512});513514// Render with callback515app.get('/report', (req, res) => {516const data = generateReportData();517518res.render('report-template', { data }, (err, html) => {519if (err) {520res.status(500).send('Error rendering report');521} else {522// Optionally modify HTML before sending523const modifiedHtml = html.replace('{{timestamp}}', new Date().toISOString());524res.send(modifiedHtml);525}526});527});528529// Dynamic view selection530app.get('/page/:template', (req, res) => {531const allowedTemplates = ['about', 'contact', 'services'];532const template = req.params.template;533534if (!allowedTemplates.includes(template)) {535return res.status(404).render('404');536}537538res.render(`pages/${template}`, {539title: template.charAt(0).toUpperCase() + template.slice(1),540layout: 'main'541});542});543```544545### Additional Response Methods546547Set specialized headers and handle specific response scenarios.548549```javascript { .api }550/**551* Set Link header for resource relationships552* @param {Object} links - Object with link relationships553* @returns {Response} Response instance for chaining554*/555res.links(links: { [rel: string]: string }): Response;556557/**558* Set Location header (typically used with redirects)559* @param {string} path - Location path or URL560* @returns {Response} Response instance for chaining561*/562res.location(path: string): Response;563564/**565* Set Content-Disposition attachment header566* @param {string} [filename] - Optional filename for attachment567* @returns {Response} Response instance for chaining568*/569res.attachment(filename?: string): Response;570```571572**Usage Examples:**573574```javascript575// Set link relationships576app.get('/api/users', (req, res) => {577res.links({578next: '/api/users?page=2',579prev: '/api/users?page=1',580first: '/api/users?page=1',581last: '/api/users?page=10'582});583res.json({ users: [] });584});585586// Set location header587app.post('/api/users', (req, res) => {588const user = createUser(req.body);589res.location(`/api/users/${user.id}`);590res.status(201).json(user);591});592593// Set attachment header594app.get('/export/data', (req, res) => {595res.attachment('data-export.csv');596res.send('id,name,email\n1,John,john@example.com');597});598599app.get('/download/report', (req, res) => {600res.attachment(); // Uses original filename601res.sendFile(path.join(__dirname, 'reports', 'monthly.pdf'));602});603```604605## Response Object Properties606607```javascript { .api }608/**609* Express response object extends Node.js ServerResponse610*/611interface Response {612/** Reference to Express application instance */613app: Application;614/** Response local variables available to views */615locals: { [key: string]: any };616/** Response headers sent status */617headersSent: boolean;618}619```620621**Usage Examples:**622623```javascript624// Use response locals for view data625app.use((req, res, next) => {626res.locals.currentUser = req.user;627res.locals.siteName = 'My App';628next();629});630631// Check if headers were already sent632app.get('/delayed-response', (req, res) => {633setTimeout(() => {634if (!res.headersSent) {635res.json({ message: 'Delayed response' });636}637}, 5000);638});639```