如何使用Express框架在Node JS中设置cookie?


161

在我的应用程序中,我需要使用express框架设置cookie。我已经尝试了以下代码,但未设置cookie。

谁能帮我做到这一点?

var express = require('express'), http = require('http');
var app = express();
app.configure(function(){
      app.use(express.cookieParser());
      app.use(express.static(__dirname + '/public'));

      app.use(function (req, res) {
           var randomNumber=Math.random().toString();
           randomNumber=randomNumber.substring(2,randomNumber.length);
           res.cookie('cokkieName',randomNumber, { maxAge: 900000, httpOnly: true })

           console.log('cookie have created successfully');
      });

});

var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(5555);

您如何验证未设置Cookie?您是否检查了浏览器得到的响应头?
NilsH 2013年

@NilsH我已经加入日志statement.if它设置装置将显示为“饼干已susccessfully创建” ..
SACHIN

1
好的,那么要么您的中间件没有被调用,要么某些先前的语句给出了异常。
NilsH 2013年

如果我删除了'app.use(express.static(__ dirname +'/ public'));' 这行意味着它设置了cookie
sachin

Answers:


216

在Express中使用中间件的顺序很重要:先前声明的中间件将首先被调用,并且如果它可以处理请求,则稍后声明的任何中间件都不会被调用。

如果express.static正在处理请求,则需要向上移动中间件:

// need cookieParser middleware before we can do anything with cookies
app.use(express.cookieParser());

// set a cookie
app.use(function (req, res, next) {
  // check if client sent cookie
  var cookie = req.cookies.cookieName;
  if (cookie === undefined) {
    // no: set a new cookie
    var randomNumber=Math.random().toString();
    randomNumber=randomNumber.substring(2,randomNumber.length);
    res.cookie('cookieName',randomNumber, { maxAge: 900000, httpOnly: true });
    console.log('cookie created successfully');
  } else {
    // yes, cookie was already present 
    console.log('cookie exists', cookie);
  } 
  next(); // <-- important!
});

// let static middleware do its job
app.use(express.static(__dirname + '/public'));

此外,中间件需求要么端的请求(通过发回的响应),或请求传递到下一个中间件。在这种情况下,我通过next()在设置cookie时调用来完成后者。

更新资料

到目前为止,cookie解析器是一个单独的npm包,因此不要使用

app.use(express.cookieParser());

您需要使用单独安装它npm i cookie-parser,然后将其用作:

const cookieParser = require('cookie-parser');
app.use(cookieParser());

我还有一个问题,在设置cookie之前,我如何检查cokkie是否存在
sachin 2013年

我编辑了答案,向您展示了如何检查cookie是否已设置。
robertklep

1
您的页面上可能有一些JS和/或CSS文件。这些将由处理express.static您的中间件之后将处理它们。因此,对于每个JS或CSS文件,都会调用代码。
robertklep

1
它没有设置cookie 8次,它说cookie已经存在。这是可以预期的。
robertklep

14
请注意,cookie解析器现在应该单独安装。参见npmjs.com/package/cookie-parser
约书亚

118

设置Cookie?

res.cookie('cookieName', 'cookieValue')

读过Cookie?

req.cookies

演示版

const express('express')
    , cookieParser = require('cookie-parser'); // in order to read cookie sent from client

app.get('/', (req,res)=>{

    // read cookies
    console.log(req.cookies) 

    let options = {
        maxAge: 1000 * 60 * 15, // would expire after 15 minutes
        httpOnly: true, // The cookie only accessible by the web server
        signed: true // Indicates if the cookie should be signed
    }

    // Set cookie
    res.cookie('cookieName', 'cookieValue', options) // options is optional
    res.send('')

})

嗨,你能说什么签名:是吗?
titoih

如果您建议将cookie设置为符号,请务必注意req.cookie将返回空。您只能从req.signedCookies中检索签名的cookie
特殊的人

38

不能完全回答您的问题,但是我在寻找我遇到的问题的答案时遇到了您的问题。也许会帮助别人。

我的问题是在服务器响应中设置了cookie,但浏览器未保存。

服务器响应返回并设置了cookie:

Set-Cookie:my_cookie=HelloWorld; Path=/; Expires=Wed, 15 Mar 2017 15:59:59 GMT 

这就是我解决的方法。

fetch在客户端代码中使用过。如果您未credentials: 'include'fetch选项中,则即使服务器响应设置了cookie,cookie也不会发送到服务器,也不会被浏览器保存。

例:

var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');

return fetch('/your/server_endpoint', {
    method: 'POST',
    mode: 'same-origin',
    redirect: 'follow',
    credentials: 'include', // Don't forget to specify this if you need cookies
    headers: headers,
    body: JSON.stringify({
        first_name: 'John',
        last_name: 'Doe'
    })
})

我希望这对某人有帮助。


我已经在浏览器中检查了我的发帖请求,但是此字段与发帖请求不匹配吗?
Sunil Garg's

如果使用XHR或Jquery的,使用“withCredentials:真正的”,而不是
不插电

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.