Javascript 使用 Node.js HTTP 服务器获取和设置单个 Cookie
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3393854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get and Set a Single Cookie with Node.js HTTP Server
提问by Corey Hart
I want to be able to set a single cookie, and read that single cookie with each request made to the nodejs server instance. Can it be done in a few lines of code, without the need to pull in a third party lib?
我希望能够设置一个 cookie,并在向 nodejs 服务器实例发出的每个请求中读取该单个 cookie。可以用几行代码完成,而不需要拉入第三方库吗?
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
Just trying to take the above code directly from nodejs.org, and work a cookie into it.
只是尝试直接从 nodejs.org 获取上述代码,然后将 cookie 放入其中。
回答by Corey Hart
There is no quick function access to getting/setting cookies, so I came up with the following hack:
没有获取/设置 cookie 的快速功能访问,所以我想出了以下技巧:
var http = require('http');
function parseCookies (request) {
var list = {},
rc = request.headers.cookie;
rc && rc.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
list[parts.shift().trim()] = decodeURI(parts.join('='));
});
return list;
}
http.createServer(function (request, response) {
// To Read a Cookie
var cookies = parseCookies(request);
// To Write a Cookie
response.writeHead(200, {
'Set-Cookie': 'mycookie=test',
'Content-Type': 'text/plain'
});
response.end('Hello World\n');
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
This will store all cookies into the cookies object, and you need to set cookies when you write the head.
这会将所有的cookies存储到cookies对象中,写head时需要设置cookies。
回答by RevNoah
If you're using the express library, as many node.js developers do, there is an easier way. Check the Express.js documentation page for more information.
如果您使用 express 库,就像许多 node.js 开发人员所做的那样,有一种更简单的方法。查看 Express.js 文档页面以获取更多信息。
The parsing example above works but express gives you a nice function to take care of that:
上面的解析示例有效,但 express 为您提供了一个很好的功能来处理这个问题:
app.use(express.cookieParser());
To set a cookie:
要设置 cookie:
res.cookie('cookiename', 'cookievalue', { maxAge: 900000, httpOnly: true });
To clear the cookie:
要清除 cookie:
res.clearCookie('cookiename');
回答by Kirby
RevNoah had the best answer with the suggestion of using Express's cookie parser. But, that answer is now 3 years old and is out of date.
RevNoah 给出了最好的答案,建议使用 Express 的cookie parser。但是,这个答案现在已经 3 年了,而且已经过时了。
Using Express, you can read a cookie as follows
使用Express,您可以按如下方式读取 cookie
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/myapi', function(req, resp) {
console.log(req.cookies['Your-Cookie-Name-Here']);
})
And update your package.jsonwith the following, substituting the appropriate relatively latest versions.
并package.json使用以下内容更新您,替换适当的相对最新版本。
"dependencies": {
"express": "4.12.3",
"cookie-parser": "1.4.0"
},
More operations like setting and parsing cookies are described hereand here
回答by Stephen Quan
As an enhancement to @Corey Hart's answer, I've rewritten the parseCookies()using:
作为对@Corey Hart 回答的增强,我重写了parseCookies()使用:
- RegExp.prototype.exec- use regex to parse "name=value" strings
- RegExp.prototype.exec- 使用正则表达式解析“name=value”字符串
Here's the working example:
这是工作示例:
let http = require('http');
function parseCookies(cookie) {
let rx = /([^;=\s]*)=([^;]*)/g;
let obj = { };
for ( let m ; m = rx.exec(cookie) ; )
obj[ m[1] ] = decodeURIComponent( m[2] );
return obj;
}
function stringifyCookies(cookies) {
let list = [ ];
for ( [ key, value ] of Object.entries( cookies ) )
list.push( key + '=' + encodeURIComponent( value ) );
return list.join( '; ' );
}
http.createServer(function ( request, response ) {
let cookies = parseCookies( request.headers.cookie );
console.log( 'Input cookies: ', cookies );
cookies.search = 'google';
if ( cookies.counter )
cookies.counter++;
else
cookies.counter = 1;
console.log( 'Output cookies: ', cookies );
response.writeHead( 200, {
'Set-Cookie': stringifyCookies(cookies),
'Content-Type': 'text/plain'
} );
response.end('Hello World\n');
} ).listen(1234);
I also note that the OP uses the http module. If the OP was using restify, he can make use of restify-cookies:
我还注意到 OP 使用了 http 模块。如果 OP 使用的是restify,他可以使用restify-cookies:
var CookieParser = require('restify-cookies');
var Restify = require('restify');
var server = Restify.createServer();
server.use(CookieParser.parse);
server.get('/', function(req, res, next){
var cookies = req.cookies; // Gets read-only cookies from the request
res.setCookie('my-new-cookie', 'Hi There'); // Adds a new cookie to the response
res.send(JSON.stringify(cookies));
});
server.listen(8080);
回答by zah
You can use the "cookies" npm module, which has a comprehensive set of features.
您可以使用“cookies”npm 模块,该模块具有一组全面的功能。
Documentation and examples at:
https://github.com/jed/cookies
文档和示例位于:https:
//github.com/jed/cookies
回答by David Beckwith
To get a cookie splitter to work with cookies that have '=' in the cookie values:
要让 cookie 拆分器处理 cookie 值中包含“=”的 cookie:
var get_cookies = function(request) {
var cookies = {};
request.headers && request.headers.cookie.split(';').forEach(function(cookie) {
var parts = cookie.match(/(.*?)=(.*)$/)
cookies[ parts[1].trim() ] = (parts[2] || '').trim();
});
return cookies;
};
then to get an individual cookie:
然后获取一个单独的cookie:
get_cookies(request)['my_cookie']
回答by Tobias P.
Cookies are transfered through HTTP-Headers
You'll only have to parse the request-headers and put response-headers.
Cookie 是通过 HTTP 标头传输的。
您只需解析请求标头并放置响应标头。
回答by Philip Orange
Here's a neat copy-n-paste patch for managing cookies in node. I'll do this in CoffeeScript, for the beauty.
这是一个用于在 node.js 中管理 cookie 的简洁的 copy-n-paste 补丁。为了美观,我将在 CoffeeScript 中执行此操作。
http = require 'http'
http.IncomingMessage::getCookie = (name) ->
cookies = {}
this.headers.cookie && this.headers.cookie.split(';').forEach (cookie) ->
parts = cookie.split '='
cookies[parts[0].trim()] = (parts[1] || '').trim()
return
return cookies[name] || null
http.IncomingMessage::getCookies = ->
cookies = {}
this.headers.cookie && this.headers.cookie.split(';').forEach (cookie) ->
parts = cookie.split '='
cookies[parts[0].trim()] = (parts[1] || '').trim()
return
return cookies
http.OutgoingMessage::setCookie = (name, value, exdays, domain, path) ->
cookies = this.getHeader 'Set-Cookie'
if typeof cookies isnt 'object'
cookies = []
exdate = new Date()
exdate.setDate(exdate.getDate() + exdays);
cookieText = name+'='+value+';expires='+exdate.toUTCString()+';'
if domain
cookieText += 'domain='+domain+';'
if path
cookieText += 'path='+path+';'
cookies.push cookieText
this.setHeader 'Set-Cookie', cookies
return
Now you'll be able to handle cookies just as you'd expect:
现在,您将能够像预期的那样处理 cookie:
server = http.createServer (request, response) ->
#get individually
cookieValue = request.getCookie 'testCookie'
console.log 'testCookie\'s value is '+cookieValue
#get altogether
allCookies = request.getCookies()
console.log allCookies
#set
response.setCookie 'newCookie', 'cookieValue', 30
response.end 'I luvs da cookies';
return
server.listen 8080
回答by BlackBeard
If you don't care what's in the cookieand you just want to use it, try this clean approach using request(a popular node module):
如果您不在乎其中的内容cookie而只想使用它,请尝试使用request(一个流行的节点模块)这种干净的方法:
var request = require('request');
var j = request.jar();
var request = request.defaults({jar:j});
request('http://www.google.com', function () {
request('http://images.google.com', function (error, response, body){
// this request will will have the cookie which first request received
// do stuff
});
});
回答by Steve
Using Some ES5/6 Sorcery & RegEx Magic
使用一些 ES5/6 魔法和正则表达式魔法
Here is an option to read the cookies and turn them into an object of Key, Value pairs for client side, could also use it server side.
这是读取cookie并将它们转换为客户端的键值对对象的选项,也可以在服务器端使用它。
Note: If there is a =in the value, no worries. If there is an =in the key, trouble in paradise.
注意:如果=值中有 a ,不用担心。如果有=钥匙,麻烦在天堂。
More Notes: Some may argue readability so break it down as you like.
更多注释:有些人可能会争辩可读性,因此可以根据需要将其分解。
I Like Notes: Adding an error handler (try catch) wouldn't hurt.
我喜欢注释:添加错误处理程序(try catch)不会有什么坏处。
const iLikeCookies = () => {
return Object.fromEntries(document.cookie.split('; ').map(v => v.split(/=(.+)/)));
}
const main = () => {
// Add Test Cookies
document.cookie = `name=Cookie Monster;expires=false;domain=localhost`
document.cookie = `likesCookies=yes=withARandomEquals;expires=false;domain=localhost`;
// Show the Objects
console.log(document.cookie)
console.log('The Object:', iLikeCookies())
// Get a value from key
console.log(`Username: ${iLikeCookies().name}`)
console.log(`Enjoys Cookies: ${iLikeCookies().likesCookies}`)
}
What is going on?
到底是怎么回事?
iLikeCookies()will split the cookies by ;(space after ;):
iLikeCookies()将通过;(后空格;)分割 cookie :
["name=Cookie Monster", "likesCookies=yes=withARandomEquals"]
Then we map that array and split by first occurrence of =using regex capturing parens:
然后我们映射该数组并通过=使用正则表达式捕获括号的第一次出现进行拆分:
[["name", "Cookie Monster"], ["likesCookies", "yes=withARandomEquals"]]
[["name", "Cookie Monster"], ["likesCookies", "yes=withARandomEquals"]]
Then use our friend `Object.fromEntries to make this an object of key, val pairs.
然后使用我们的朋友`Object.fromEntries 使其成为key, val 对的对象。
Nooice.
诺斯。


