为什么 express-session 会为 Set-Cookie 创建一个数组?

Why does express-session create an array for Set-Cookie?

express-session 源代码中这是做什么的:

function setcookie(res, name, val, secret, options) {
  var signed = 's:' + signature.sign(val, secret);
  var data = cookie.serialize(name, signed, options);

  var prev = res.getHeader('Set-Cookie') || []
  var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];

  res.setHeader('Set-Cookie', header)
}

具体来说:

  var prev = res.getHeader('Set-Cookie') || []
  var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];

什么时候会出现这样的情况,你已经把 cookie 写入了响应头,然后需要把它变成某种数组?这里发生了什么,为什么?

同一个响应中可以出现多个 Set-Cookie header。并且,res.setHeader(name, data) 接受数据数组,以便为​​相同的 header.

指定多个重复值

因此,为了“添加”另一个 header,此代码获取当前 header 值(如果有)。如果该值已经是一个数组,那么它只是将新值添加到该数组。如果它还不是一个数组(例如只有一个值),那么它会将现有值和新值放入一个数组中并调用 res.setHeader(name, data),其中 data 现在是一个值数组。

这是必需的,因为 res.setHeader() 在调用特定名称时不会为该名称“添加”新值 - 而是用该名称替换任何现有值。因此,要添加新值,它必须获取现有值,确保它们在数组中,将新值添加到数组,然后将新值设置为数组。

所以,这一行:

var prev = res.getHeader('Set-Cookie') || []

使默认值为空数组,以防不存在 'Set-Cookie' header.

然后,这一行:

var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];

检查我们刚刚得到的值是否已经是一个数组。如果是这样,它将新值连接到该数组。如果不是(它一定只是一个单一的值),它就会将之前的单一值与新的值组合成一个数组。因此,所有代码路径都有一个数组,新值位于数组的末尾,任何先前的值位于数组的开头。然后它可以使用该数组调用 res.setHeader() 并将所有先前值替换为先前值和任何新值的组合。

这段代码将与这样的东西一起使用:

res.setHeader('Set-Cookie', 'color=blue');
res.setHeader('Set-Cookie', 'shape=square');

此代码的结果是 Set-Cookie 将有两个值 'color=blue''shape=square'。并且,当实际发送响应时,它将构造两个单独的 Set-Cookie header,每个都具有这些值之一。