Получить и установить одиночное cookie с Node.js HTTP-сервером

Я хочу иметь возможность установить один файл cookie и прочитать этот единственный файл cookie с каждым запросом, сделанным на экземпляр сервера nodejs. Можно ли это сделать в нескольких строках кода, без необходимости втягивать стороннюю библиотеку?

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/');

Просто пытаясь взять вышеуказанный код непосредственно из nodejs.org и работать с ним в файле cookie.

Ответ 1

Существует не быстрый доступ к функции для получения/настройки файлов 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/');

Это сохранит все файлы cookie в объекте куки, и вам нужно будет установить куки, когда вы напишете голову.

Ответ 2

Если вы используете экспресс-библиотеку, как это делают многие разработчики node.js, есть более простой способ. Подробнее см. Страницу документации Express.js.

Приведенный выше пример синтаксического анализа работает, но экспресс дает вам хорошую функцию, чтобы позаботиться об этом:

app.use(express.cookieParser());

Чтобы установить файл cookie:

res.cookie('cookiename', 'cookievalue', { maxAge: 900000, httpOnly: true });

Чтобы очистить файл cookie:

res.clearCookie('cookiename');

Ответ 3

У RevNoah был лучший ответ с предложением использовать парсер файлов cookie Express. Но этому ответу уже 3 года, и он устарел.

Используя 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']);
})

И обновите свой package.json следующим, заменив соответствующие относительно последние версии.

"dependencies": {
    "express": "4.12.3",
    "cookie-parser": "1.4.0"
  },

Дополнительные операции, такие как установка и анализ файлов cookie, описаны здесь и здесь.

Ответ 4

Вы можете использовать модуль cookie "cookie", который имеет полный набор функций.

Документация и примеры на:
https://github.com/jed/cookies

Ответ 5

В качестве дополнения к ответу @Corey Hart я переписал parseCookies(), используя:

  • RegExp.prototype.exec - используйте регулярное выражение для анализа строк "имя = значение"

Вот рабочий пример:

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);

Я также отмечаю, что OP использует модуль http. Если ОП использовал 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);

Ответ 6

Файлы cookie передаются через HTTP-заголовки
Вам нужно будет только разобрать заголовки запросов и поместить заголовки ответов.

Ответ 7

Чтобы получить сплиттер 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;
};

то для получения отдельного файла cookie:

get_cookies(request)['my_cookie']

Ответ 8

Здесь находится аккуратный патч для копирования файлов cookie в node. Я сделаю это в 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

Теперь вы сможете обрабатывать файлы cookie точно так же, как и следовало ожидать:

server = http.createServer (request, response) ->
  #get individually
  cookieValue = request.getCookie 'testCookie'
  console.log 'testCookie\ 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

Ответ 9

Если вам все равно, что в 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
  });
});

Ответ 10

var cookie = 'your_cookie';
var cookie_value;
var i = request.headers.indexOf(cookie+'=');
if (i != -1) {
  var eq = i+cookie.length+1;
  var end = request.headers.indexOf(';', eq);
  cookie_value = request.headers.substring(eq, end == -1 ? undefined : end);
}

Ответ 11

Сначала нужно создать cookie (в качестве примера я купил токен внутри файла cookie), а затем установить его в ответ. Чтобы использовать файл cookie следующим образом, установите cookieParser

app.use(cookieParser());

Браузер сохранит его на вкладке "Ресурс" и будет использоваться для каждого запроса, после чего начальный URL будет использоваться как базовый

var token = student.generateToken('authentication');
        res.cookie('token', token, {
            expires: new Date(Date.now() + 9999999),
            httpOnly: false
        }).status(200).send();

Получить cookie с запросом на стороне сервера тоже легко. Вы должны извлечь cookie из запроса, вызвав свойство "cookie" объекта запроса.

var token = req.cookies.token; // Retrieving Token stored in cookies