Node.js HTTP सर्वर के साथ एकल कुकी प्राप्त करें और सेट करें


159

मैं एक एकल कुकी सेट करने में सक्षम होना चाहता हूं, और उस एकल कुकी को नोडज सर्वर उदाहरण में किए गए प्रत्येक अनुरोध के साथ पढ़ना चाहता हूं। क्या इसे थर्ड पार्टी लिब में खींचने की आवश्यकता के बिना कोड की कुछ पंक्तियों में किया जा सकता है?

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

बस उपर्युक्त कोड को सीधे नोडज.ओआरजी से लेने की कोशिश कर रहे हैं, और इसमें एक कुकी काम करते हैं।

जवाबों:


190

कुकीज़ प्राप्त करने / स्थापित करने के लिए कोई त्वरित फ़ंक्शन एक्सेस नहीं है, इसलिए मैं निम्नलिखित हैक के साथ आया:

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

यह सभी कुकीज़ को कुकीज़ ऑब्जेक्ट में संग्रहीत करेगा, और सिर लिखने पर आपको कुकीज़ सेट करने की आवश्यकता है।


11
उपरोक्त कोड गलत तरीके से काम करेगा अगर कुकी के मूल्य =में फेसबुक के कुकीज़ में से एक के बराबर ( ) चिन्ह शामिल है fbm_1234123412341234=base_domain=.domain.com
आँख

3
कुकी मानों को URL एन्कोडेड / प्रतिशत एन्कोडेड नहीं होना चाहिए? = डॉकई मूल्य में उस मामले में अमान्य होगा, है ना?
192 बजे

2
उस मामले में ;तब तक का विभाजन हो जाता है =। बायां कुंजी है, सही मूल्य है।
इल

4
मैं @Eye रूप में एक ही मुद्दे में भाग गया, @iLoch मैं के मार्ग पर जाने की बजाय बंद parts[0]करने के लिए parts.shift()और parts[1]करने के लिएparts.join('=')
aron.duby

3
दिए गए कोड में गंभीर कीड़े थे और लोगों ने इसे कॉपी करने के लिए कहा था। मेरा आखिरी अपडेट देखें
दान

124

यदि आप एक्सप्रेस लाइब्रेरी का उपयोग कर रहे हैं, जैसा कि कई नोड। जेएस डेवलपर्स करते हैं, तो एक आसान तरीका है। अधिक जानकारी के लिए Express.js प्रलेखन पृष्ठ देखें।

ऊपर दिए गए उदाहरण काम करता है लेकिन एक्सप्रेस आपको इसकी देखभाल करने के लिए एक अच्छा काम देता है:

app.use(express.cookieParser());

कुकी सेट करने के लिए:

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

कुकी साफ़ करने के लिए:

res.clearCookie('cookiename');

14
कुकी पुस्तकालय वास्तव में अंतर्निहित लाइब्रेरी कनेक्ट से है; कुकी सहायक पाने के लिए आपको सभी एक्सप्रेस लेने की आवश्यकता नहीं है।
अजाक्स

1
वास्तव में कुकी लाइब्रेरी कनेक्ट का हिस्सा नहीं है (जो कुकी को सेट नहीं कर सकती है)
फ्रिज करें

10
cookie-parserअब एक्सप्रेस और / या कनेक्ट का हिस्सा नहीं है, लेकिन मिडलवेयर के रूप में उपलब्ध है: github.com/expressjs/cookie-parser
Koen।

7
इस उदाहरण में एक "कुकी" कैसे मिलती है? पूर्णता के लिए और प्रश्न का उत्तर देने के लिए।
हबेटिश

1
डाउनवोटिंग केवल कुकीज़ का उपयोग करने के लिए एक्सप्रेस स्थापित करने की आवश्यकता के कारण
स्टीवन

34

एक्सप्रेस के कुकी पार्सर के उपयोग के सुझाव के साथ रेवनोह का सबसे अच्छा जवाब था । लेकिन, वह जवाब अब 3 साल का है और पुराना है।

एक्सप्रेस का उपयोग करके , आप निम्नानुसार एक कुकी पढ़ सकते हैं

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"
  },

कुकीज को सेट करने और पार्स करने जैसे और भी ऑपरेशन यहाँ और यहाँ वर्णित हैं


8
प्रश्न पूछता है कि कैसे प्राप्त करें और सेट करें। इसका उपयोग करने के लिए:res.cookie('cookieName', cookieValue, { maxAge: 900000, httpOnly: true });
Augie Gardner

क्या आप प्रति-सत्र के रूप में कुकीज़ सेट और प्राप्त कर सकते हैं (चाबियाँ जानने और संभालने की आवश्यकता को रोक सकते हैं)?
मतज जे

12

@Corey हार्ट के जवाब में वृद्धि के रूप में, मैंने parseCookies()उपयोग को फिर से लिखा है :

  • RegExp.prototyp.exec - "नाम = मान" स्ट्रिंग को पार्स करने के लिए रेगेक्स का उपयोग करें

यहाँ काम कर रहे उदाहरण है:

let http = require('http');

function parseCookies(str) {
  let rx = /([^;=\s]*)=([^;]*)/g;
  let obj = { };
  for ( let m ; m = rx.exec(str) ; )
    obj[ m[1] ] = decodeURIComponent( m[2] );
  return obj;
}

function stringifyCookies(cookies) {
  return Object.entries( cookies )
    .map( ([k,v]) => k + '=' + encodeURIComponent(v) )
    .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);

मैं यह भी ध्यान देता हूं कि ओपी http मॉड्यूल का उपयोग करता है। यदि ओपी पुनर्स्थापना का उपयोग कर रहा था , तो वह पुनर्स्थापना-कुकीज़ का उपयोग कर सकता है :

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

1
कुछ सुझाव अब, 3.5 साल बाद, भविष्य के दर्शकों के लिए। उपयोग let/constऔर stringifyCookiesएक mapतरह से एक सरणी के निर्माण के साथ लाइन में खड़ा किया जा सकता है ।
1947 में एस्केरर

10

आप "कुकीज़" एनपीएम मॉड्यूल का उपयोग कर सकते हैं, जिसमें सुविधाओं का एक व्यापक सेट है।

प्रलेखन और उदाहरण:
https://github.com/jed/cookies


1
ऐसा लगता है कि मॉड्यूल HTTP सर्वर में उपयोग के लिए है। Http क्लाइंट में कुकीज़ को संभालने के लिए कुकीज टूल है? मूल रूप से मैं http क्लाइंट लिब को बताने के लिए इच्छुक हूं: यदि आपको कोई सेट-कुकी हेडर मिलता है, तो उन्हें स्वचालित रूप से याद रखें, और फिर बाद के आउटबाउंड अनुरोधों को उचित (जब डोमेन मिलान) पास करें।
चेसो

यह आपकी पसंद की http क्लाइंट लाइब्रेरी की एक विशेषता होगी। मैं एक अच्छे उदाहरण के रूप में अतिशयोक्ति का सुझाव दे सकता हूं ।
ज़ह सिप

घंटे के बाद एक्सप्रेस में काम करने के लिए इस काम पाने की कोशिश कर दिया ... इसके बजाय कनेक्ट का उपयोग करें।
enko

7

कुकी मानों में कुकी के साथ काम करने के लिए कुकी स्प्लिटर प्राप्त करना:

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

फिर एक व्यक्ति कुकी पाने के लिए:

get_cookies(request)['my_cookie']


2

यहाँ नोड में कुकीज़ के प्रबंधन के लिए एक साफ कॉपी-एन-पेस्ट पैच है। मैं सौंदर्य के लिए, कॉफीस्क्रिप्ट में ऐसा करूँगा।

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

अब आप कुकीज़ को वैसे ही संभाल पाएंगे जैसे आप उम्मीद करेंगे:

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

3
बस उस कोड को TRoff COFFESCRIPT टैब पर coffeescript.org पर कॉपी पेस्ट करें । आपके उत्तर ने मेरी मदद की, और यदि आप जावास्क्रिप्ट को जानते हैं तो कॉफ़ीस्क्रिप्ट को पढ़ना मुश्किल नहीं है।
मैटिज

1

मुझे इस प्रश्न के इस भाग को दोहराना चाहिए जो यहाँ उत्तर दे रहा है:

क्या इसे थर्ड पार्टी लिब में खींचने की आवश्यकता के बिना कोड की कुछ पंक्तियों में किया जा सकता है?


कुकीज़ पढ़ना

Cookieहेडर के साथ अनुरोधों से कुकीज़ पढ़ी जाती हैं । वे केवल एक nameऔर शामिल हैं value। जिस तरह से रास्ते काम करते हैं, उसी नाम के कई कुकीज़ भेजे जा सकते हैं। NodeJS में, Cookieहेडर में भेजे जाने वाले सभी तार एक ही स्ट्रिंग में । आप उनसे बिछड़ गए ;। एक बार जब आप एक कुकी, बराबर के बाईं ओर सब कुछ (यदि वर्तमान) है name, और सब कुछ के बाद है value। कुछ ब्राउज़र कुकी को बिना किसी समान चिह्न के स्वीकार करेंगे और नाम को रिक्त मानेंगे। व्हॉट्सएप कुकी के हिस्से के रूप में नहीं गिना जाता है। मूल्यों को दोहरे उद्धरण चिह्नों ( ") में भी लपेटा जा सकता है । मान भी हो सकते हैं =। उदाहरण के लिए, formula=5+3=8एक वैध कुकी है।

/**
 * @param {string} [cookieString='']
 * @return {[string,string][]} String Tuple
 */
function getEntriesFromCookie(cookieString = '') {
  return cookieString.split(';').map((pair) => {
    const indexOfEquals = pair.indexOf('=');
    let name;
    let value;
    if (indexOfEquals === -1) {
      name = '';
      value = pair.trim();
    } else {
      name = pair.substr(0, indexOfEquals).trim();
      value = pair.substr(indexOfEquals + 1).trim();
    }
    const firstQuote = value.indexOf('"');
    const lastQuote = value.lastIndexOf('"');
    if (firstQuote !== -1 && lastQuote !== -1) {
      value = value.substring(firstQuote + 1, lastQuote);
    }
    return [name, value];
  });
}

const cookieEntries = getEntriesFromCookie(request.headers.Cookie); 
const object = Object.fromEntries(cookieEntries.slice().reverse());

यदि आप डुप्लिकेट किए गए नामों की अपेक्षा नहीं कर रहे हैं, तो आप एक ऑब्जेक्ट में बदल सकते हैं जो चीजों को आसान बनाता है। फिर आप object.myCookieNameमूल्य प्राप्त करने के लिए जैसे पहुंच सकते हैं । यदि आप डुप्लिकेट की अपेक्षा कर रहे हैं, तो आप इसके माध्यम से पुनरावृति करना चाहते हैं cookieEntries। ब्राउज़र कुकीज़ को नीचे उतरने की प्राथमिकता में खिलाते हैं, इसलिए पीछे हटना सुनिश्चित करता है कि सर्वोच्च प्राथमिकता कुकी वस्तु में दिखाई दे। ( .slice()सरणी के उत्परिवर्तन से बचने के लिए है।)


सेटिंग्स कुकीज़

"लेखन" कुकीज़ Set-Cookieआपकी प्रतिक्रिया में हेडर का उपयोग करके किया जाता है । response.headers['Set-Cookie']वस्तु वास्तव में एक सरणी है, तो आप इसे करने के लिए जोर दे रहे होंगे। यह एक स्ट्रिंग को स्वीकार करता है लेकिन इसमें अधिक मूल्य हैं बस nameऔर value। सबसे कठिन हिस्सा स्ट्रिंग लिख रहा है, लेकिन यह एक पंक्ति में किया जा सकता है।

/**
 * @param {Object} options
 * @param {string} [options.name='']
 * @param {string} [options.value='']
 * @param {Date} [options.expires]
 * @param {number} [options.maxAge]
 * @param {string} [options.domain]
 * @param {string} [options.path]
 * @param {boolean} [options.secure]
 * @param {boolean} [options.httpOnly]
 * @param {'Strict'|'Lax'|'None'} [options.sameSite]
 * @return {string}
 */
function createSetCookie(options) {
  return (`${options.name || ''}=${options.value || ''}`)
    + (options.expires != null ? `; Expires=${options.expires.toUTCString()}` : '')
    + (options.maxAge != null ? `; Max-Age=${options.maxAge}` : '')
    + (options.domain != null ? `; Domain=${options.domain}` : '')
    + (options.path != null ? `; Path=${options.path}` : '')
    + (options.secure ? '; Secure' : '')
    + (options.httpOnly ? '; HttpOnly' : '')
    + (options.sameSite != null ? `; SameSite=${options.sameSite}` : '');
}

const newCookie = createSetCookie({
  name: 'cookieName',
  value: 'cookieValue',
  path:'/',
});
response.headers['Set-Cookie'].push(newCookie);

याद रखें कि आप कई कुकीज़ सेट कर सकते हैं, क्योंकि आप वास्तव Set-Cookieमें अपने अनुरोध में कई हेडर सेट कर सकते हैं। इसलिए यह एक सरणी है।


बाहरी पुस्तकालयों पर ध्यान दें:

आप उपयोग करना चाहते हैं express, cookie-parserया cookie, ध्यान दें कि वे चूक कि अमानक हैं। कुकीज हमेशा यूआरआई डिकोडेड (प्रतिशत-डिकोडेड) होती हैं। इसका मतलब है कि यदि आप एक नाम या मान का उपयोग करते हैं, जिसमें निम्न में से कोई भी वर्ण है: तो !#$%&'()*+/:<=>?@[]^`{|}उन्हें उन पुस्तकालयों के साथ अलग तरीके से संभाला जाएगा। यदि आप कुकीज़ सेट कर रहे हैं, तो वे इनकोडेड हैं %{HEX}। और अगर आप एक कुकी पढ़ रहे हैं तो आपको उन्हें डिकोड करना होगा।

उदाहरण के लिए, जबकि email=name@domain.comएक वैध कुकी है, इन पुस्तकालयों के रूप में इसे सांकेतिक शब्दों में बदलना होगा email=name%40domain.com। यदि आप %अपनी कुकी में उपयोग कर रहे हैं तो डिकोडिंग मुद्दों को प्रदर्शित कर सकता है । यह आम हो जाएगा। उदाहरण के लिए, आपका कुकी जो था: secretagentlevel=50%007and50%006बन जाता है secretagentlevel=507and506। यह एक किनारे का मामला है, लेकिन पुस्तकालयों को स्विच करने पर ध्यान देने योग्य कुछ है।

इसके अलावा, इन पुस्तकालयों पर, कुकीज़ को डिफ़ॉल्ट रूप से सेट किया जाता है, path=/जिसका अर्थ है कि वे होस्ट के लिए हर यूआरएल अनुरोध पर भेजे जाते हैं।

यदि आप इन मानों को अपने आप एनकोड या डीकोड करना चाहते हैं, तो आप क्रमशः, encodeURIComponentया उपयोग कर सकते decodeURIComponentहैं।


संदर्भ:


अतिरिक्त जानकारी:


0

पहले कुकी बनाने की जरूरत है (मैंने एक उदाहरण के रूप में कुकी के अंदर टोकन लपेटा है) और फिर इसे प्रतिक्रिया में सेट करें। कुकी को निम्न तरीके से स्थापित करने के लिए कुकी का उपयोग करें।

app.use(cookieParser());

ब्राउज़र ने इसे अपने 'संसाधन' टैब में सहेजा होगा और इसके बाद प्रारंभिक URL को आधार के रूप में लेते हुए हर अनुरोध के लिए उपयोग किया जाएगा

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

सर्वर साइड पर एक अनुरोध से कुकी प्राप्त करना आसान है। आपको अनुरोध ऑब्जेक्ट की 'कुकी' संपत्ति को कॉल करके अनुरोध से कुकी को निकालना होगा।

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

0

अगर आपको इस बात की परवाह नहीं है कि आप क्या 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
  });
});

क्षमा करें, लेकिन इस कोड से मुझे कोई मतलब नहीं है। है jar()कुकीज़ की वर्तमान सूची पाने के लिए कुछ cutesy विधि नाम? अनुरोध के 2 आह्वान का क्या मतलब है? यह ज्यादातर एक विज्ञापन है, जवाब नहीं।
user1944491

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

0

कुछ ES5 / 6 टोना और RegEx जादू का उपयोग करना

यहां कुकीज़ को पढ़ने और उन्हें कुंजी की एक वस्तु में बदलने का एक विकल्प है, ग्राहक पक्ष के लिए मूल्य जोड़े, इसे सर्वर साइड भी उपयोग कर सकते हैं।

नोट : यदि =मूल्य में कोई है, तो कोई चिंता नहीं है। यदि =कुंजी में एक है, तो स्वर्ग में परेशानी।

अधिक नोट्स : कुछ पठनीयता का तर्क दे सकते हैं इसलिए इसे नीचे तोड़ दें जैसा आप चाहते हैं।

I लाइक नोट्स : एरर हैंडलर जोड़ना (कैच ट्राई) चोट नहीं पहुंचाएगा।

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}`)
}

यहां छवि विवरण दर्ज करें

क्या हो रहा है?

iLikeCookies()कुकीज़ को विभाजित करेगा ;( अंतरिक्ष के बाद; ):

["name=Cookie Monster", "likesCookies=yes=withARandomEquals"]

फिर हम उस सरणी को मैप करते हैं और रेगेक्स कैप्चरिंग पेरेन्स का =उपयोग करने की पहली घटना से विभाजित होते हैं :

[["name", "Cookie Monster"], ["likesCookies", "yes=withARandomEquals"]]

तो फिर हमारे दोस्त का उपयोग करें। Object.fromEntries यह कुंजी, वैल जोड़े की एक वस्तु बनाने के लिए।

Nooice।


0

मैंने यह सरल कार्य केवल पास req.headers.cookieऔर कुकी नाम लिखा है

const getCookieByName =(cookies,name)=>{
    const arrOfCookies = cookies.split(' ')
    let yourCookie = null

    arrOfCookies.forEach(element => {
        if(element.includes(name)){
            yourCookie = element.replace(name+'=','')
        }
    });
    return yourCookie
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.