阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 请求头信息的读取与设置

请求头信息的读取与设置

作者:陈川 阅读数:44657人阅读 分类: Node.js

请求头信息的读取与设置

Koa2框架中处理HTTP请求时,请求头信息是客户端与服务器交互的重要组成部分。通过ctx.request对象可以方便地获取和操作这些头信息,同时也能通过ctx.response对象设置响应头。

请求头信息的读取

在Koa2中,可以通过ctx.request.header或ctx.headers访问完整的请求头对象。这些头信息以键值对的形式存在,键名会被统一转换为小写形式。

app.use(async (ctx) => {
  // 获取所有请求头
  const headers = ctx.headers;
  console.log(headers);
  
  // 获取特定请求头
  const userAgent = ctx.get('User-Agent');
  const contentType = ctx.request.get('Content-Type');
  
  ctx.body = {
    userAgent,
    contentType
  };
});

常用的请求头读取方法包括:

  • ctx.get(field): 获取指定请求头字段
  • ctx.request.get(field): 同上,两种写法等效
  • ctx.header: 获取全部请求头对象
  • ctx.headers: header的别名

请求头信息的设置

响应头的设置主要通过ctx.set()或ctx.response.set()方法实现。Koa2会自动设置一些默认响应头,如Content-Type默认为text/plain。

app.use(async (ctx) => {
  // 设置单个响应头
  ctx.set('X-Powered-By', 'Koa2');
  
  // 设置多个响应头
  ctx.set({
    'Cache-Control': 'no-cache',
    'Last-Modified': new Date()
  });
  
  // 等效写法
  ctx.response.set('Content-Type', 'application/json');
  
  ctx.body = { message: 'Headers set successfully' };
});

特殊头信息处理

某些头信息需要特别注意处理方式:

  1. Content-Type处理:
app.use(async (ctx) => {
  // 获取Content-Type
  const type = ctx.type;
  
  // 设置Content-Type
  ctx.type = 'application/json';
  
  // 等效于
  ctx.set('Content-Type', 'application/json');
});
  1. ETag和Last-Modified处理:
const fs = require('fs');
const crypto = require('crypto');

app.use(async (ctx) => {
  const filePath = './static/image.jpg';
  const fileBuffer = fs.readFileSync(filePath);
  const hash = crypto.createHash('md5').update(fileBuffer).digest('hex');
  
  ctx.set('ETag', hash);
  ctx.set('Last-Modified', new Date(fs.statSync(filePath).mtime).toUTCString());
  
  // 检查客户端缓存
  if (ctx.fresh) {
    ctx.status = 304;
    return;
  }
  
  ctx.body = fileBuffer;
});

自定义中间件处理头信息

可以创建中间件统一处理特定头信息:

// 添加X-Response-Time头
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
});

// CORS中间件
app.use(async (ctx, next) => {
  ctx.set('Access-Control-Allow-Origin', '*');
  ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  
  if (ctx.method === 'OPTIONS') {
    ctx.status = 204;
    return;
  }
  
  await next();
});

安全相关的头信息设置

安全头信息对于Web应用至关重要:

app.use(async (ctx, next) => {
  ctx.set('X-Frame-Options', 'DENY');
  ctx.set('X-Content-Type-Options', 'nosniff');
  ctx.set('X-XSS-Protection', '1; mode=block');
  ctx.set('Content-Security-Policy', "default-src 'self'");
  
  await next();
});

请求头与响应头的实际应用

  1. 内容协商:
app.use(async (ctx) => {
  // 根据Accept头返回不同格式响应
  const accept = ctx.accepts('json', 'html', 'text');
  
  switch(accept) {
    case 'json':
      ctx.type = 'application/json';
      ctx.body = { data: 'JSON response' };
      break;
    case 'html':
      ctx.type = 'text/html';
      ctx.body = '<p>HTML response</p>';
      break;
    default:
      ctx.type = 'text/plain';
      ctx.body = 'Plain text response';
  }
});
  1. 认证处理:
app.use(async (ctx, next) => {
  const authHeader = ctx.get('Authorization');
  
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    ctx.status = 401;
    ctx.set('WWW-Authenticate', 'Bearer');
    ctx.body = 'Authentication required';
    return;
  }
  
  const token = authHeader.split(' ')[1];
  // 验证token逻辑...
  
  await next();
});

性能优化相关的头设置

app.use(async (ctx, next) => {
  await next();
  
  if (ctx.response.is('json')) {
    ctx.set('Vary', 'Accept-Encoding');
    ctx.set('Cache-Control', 'public, max-age=3600');
  }
  
  // 启用HTTP/2服务器推送
  if (ctx.response.is('html')) {
    ctx.set('Link', '</styles.css>; rel=preload; as=style');
  }
});

调试与问题排查

开发过程中可以添加调试头信息:

app.use(async (ctx, next) => {
  ctx.set('X-Request-ID', Math.random().toString(36).substr(2, 9));
  
  console.log('Incoming headers:', ctx.headers);
  await next();
  console.log('Outgoing headers:', ctx.response.headers);
});

头信息处理的注意事项

  1. 头字段名称大小写不敏感,但建议统一使用小写
  2. 设置重复头字段时,后者会覆盖前者
  3. 某些头字段有特殊格式要求,如Set-Cookie
  4. 头字段值只能是字符串或可以转换为字符串的类型
  5. 修改头信息应在发送响应体之前完成

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌