I wanted to remember the last page someone visited (like here)
I tried to do it with cookie-session but It's doesn't work as I a suppose.
I saw this and I tried this example for extending the session without success.
Here the code :
var session = require('cookie-session');
var express = require('express');
var app = express();
app.use( session({ secret: 'secret' }) );
app.get('/a', function (req, res) {
if(req.session.last) {
res.write("the last page was " + req.session.last + ". ");
}
req.session.last = "a";
res.end("Page A");
});
app.get('/b', function (req, res) {
if(req.session.last) {
res.write("the last page was " + req.session.last + ". ");
}
req.session.last = "b";
res.end("Page B");
});
app.get('/c', function (req, res) {
if(req.session.last) {
res.write("the last page was " + req.session.last + ". ");
}
req.session.last = "c";
res.end("Page C");
});
app.listen(8080);
Are you sure you are not getting an error in your logs along the line of "cannot write to headers after they have been sent"? Can you try moving the assigning of the session to before the res.write call? From your first link, in the comments...
"I kept getting an error that the headers couldn't be set after they'd been sent.
I modified the code so that lastPage was set before sending any body eg:
var responseText;
if(req.session.lastPage)
responseText = 'Last page was: ' + req.session.lastPage + '. ';
else
responseText = 'You\'re Awesome';
req.session.lastPage = '/awesome';
res.send(responseText);
Related
This is my app.js:
const express = require("express");
//const https = require("https");
const app = express();
app.get("/", function(req, res) {
const query = niall;
// Follow procedure here to get access_token and refresh_token: https://benwiz.com/blog/create-spotify-refresh-token/
const access_token = {access_token};
const token = "Bearer " + access_token;
var searchUrl = "https://api.spotify.com/v1/search?q=" + query + "&type=track&limit=4";
////////WRITE YOUR CODE HERE//////////
});
// Starting the server. Should this be placed at the top of all other commands?
app.listen(3000, function() {
console.log("Server is running on port 3000.")
})
Expected Behaviour:
We are to get results from the api endpoint using https.get method.
The returned data is to be parsed to JSON.
We need to store the value of track ID, from this JSON output, into a variable and log it in the console.
Helpful Resources:
Follow the steps here to get the access_token: https://benwiz.com/blog/create-spotify-refresh-token/
Understand parameters here: https://developer.spotify.com/documentation/web-api/reference/#category-search
Spotify Web Console to understand the JSON arrangement: https://developer.spotify.com/console/get-search-item/
I'm really in need of help. Any help would be appreciated.
Replace ////////WRITE YOUR CODE HERE////////// with
axios.get(searchUrl, {
headers: {
'Authorization': token,
}
})
.then((resAxios) => {
console.log(resAxios.data)
spotifyResult = resAxios.data;
//Extracting required data from 'result'. The following "items[0].id.videoId" is the address of the data that we need from the JSON 'ytResult'.
let spotifyTrackIdAppJs00 = spotifyResult.tracks.items[0].id;
let spotifyAlbumIdAppJs00 = spotifyResult.tracks.items[0].album.id;
let spotifyArtistIdAppJs00 = spotifyResult.tracks.items[0].artists[0].id;
console.log("Fetched values: " + spotifyTrackIdAppJs00 + ", " + spotifyAlbumIdAppJs00 + ", " + spotifyArtistIdAppJs00);
// The 'results' named EJS file is rendered and fed in response. The 'required' data is passed into it using the following letiable(s).
// A folder named 'views' has to be in the same directory as "app.js". That folder contains 'results.ejs'.
res.render("results", {
spotifyTrackIdEjs00: spotifyTrackIdAppJs00,
spotifyAlbumIdEjs00: spotifyAlbumIdAppJs00,
spotifyArtistIdEjs00: spotifyArtistIdAppJs00
});
console.log("Values to be used in rendered file: " + spotifyTrackIdAppJs00 + ", " + spotifyAlbumIdAppJs00 + ", " + spotifyArtistIdAppJs00);
})
.catch((error) => {
console.error(error)
})
I needed ID value for Album and Artist as well. Please modify accordingly.
I want to implement a system in which if the user types domain/crypt/text (the page where the text gets crypted), the text is available to read in the main page (domain). I've found out the problem is that when I change the URL to check the main page datas gets resetted since I'm loading once again the page, but I can't find any solution to this problem.
const Encryption = require('node_triple_des');
const sha1 = require('sha1');
const express = require('express');
const app = express();
const key = "Chiave_scelta";
var coded_key = 'Coded_Key';
var text_crypted = 'NaN';
var text_decrypted = 'NaN';
async function encryptKey() {
coded_key = sha1(key); //si codifica la chiave scelta in SHA1
}
async function encryptAll(msg) {
await encryptKey();
var result = await Encryption.encrypt(coded_key,msg);
return result;
}
async function decryptAll(msg) {
await encryptKey();
var result = await Encryption.decrypt(coded_key, msg);
return result;
}
app.get('/', function (req, res) {
res.send('Generated key: ' + coded_key + '<br>' +
'Last crypted text: ' + text_crypted + '<br>' +
'Last decrypted text: ' + text_decrypted + '<br>'
)
})
app.get('/crypt/:code', async function (req, res) {
crypted_text = await encryptAll(req.params.code); //cripta il messaggio
res.send('Crypted text: ' + crypted_text )
})
app.get('/decrypt/:code', async function (req, res) {
decrypted_text = await decryptAll(req.params.code); //decripta il messaggio
res.send('Decrypted text: ' + decrypted_text )
})
app.listen(3000)
I fixed by importing the module 'local-storage' (which I previously installed).
const ls = require('local-storage');
To set values I used the following syntax:
ls.set(name,value);
To get values I used the following syntax:
ls.get(name,value);
I am using nodejs express and firebase for my database. So what I am trying to do is upon user's post request, update firebase data and redirect user to another page. But I keep getting Error: Can't set headers after they are sent.
Here is my code in controller.js file:
app.post('/carpark', urlencodedParser, function(req,res){
req.session.carpark = req.body.carpark;
lotsRef.orderByChild('CarparkName').equalTo(req.session.carpark).on('value', function(snapshot){
for (var key in snapshot.val()) {
if (snapshot.val()[key]['Availability'] == true) {
firebase.database().ref('Lots/'+ key).update({'Availability': false });
res.redirect('checkin');
break;
}
}
});
EDITED:
app.post('/carpark', urlencodedParser, function(req,res){
req.session.carpark = req.body.carpark;
lotsRef.orderByChild('CarparkName').equalTo(req.session.carpark).on('value', function(snapshot){
for (var key in snapshot.val()) {
var allocatedtime = new Date().getHours() + ':' + (new Date().getMinutes() <10 ? '0' : '') + new Date().getMinutes() + ':' + (new Date().getSeconds() <10 ?'0' : '') + new Date().getSeconds();
req.session.key = key;
req.session.LotID = snapshot.val()[key]['LotID'];
req.session.AllocatedTime = allocatedtime;
req.session.SerialNum = snapshot.val()[key]['SerialNumber'];
var date = new Date().getFullYear() + "-" + (new Date().getMonth()+1) + "-" + new Date().getDate();
req.session.DateAllocated = date;
console.log(req.session);
firebase.database().ref('Lots/'+ req.session.key).update({'Availability': false });
break;
}
}
res.redirect('checkin');
});
The redirect should be moved outside For loop:
app.post('/carpark', urlencodedParser, function(req,res){
req.session.carpark = req.body.carpark;
lotsRef.orderByChild('CarparkName').equalTo(req.session.carpark).on('value', function(snapshot){
for (var key in snapshot.val()) {
if (snapshot.val()[key]['Availability'] == true) {
firebase.database().ref('Lots/'+ key).update({'Availability': false });
break;
}
}
res.redirect('checkin');
});
But this will redirect to 'checkin' irrespective of your if clause, so that depends on your scenario whether you want to redirect to some other page when the if clause is not true even once.
I am using using EJS templates with Node.js and Express. I am trying to pass a request parameter to my EJS template. It is working, however, for some reason my console log is reporting something strange.
Versions:
Node 0.10.26
Express 4.6.1
EJS 0.8.5
Here is the route that handles the ejs template:
var express = require('express');
var router = express.Router();
var data = require('../data.json');
var pkg = require('../../package.json');
router.get('/', function(req, res) {
res.render('index',
{
'acs' : data.acs,
'products' : data.products,
'pkg' : pkg,
'debug' : req.param('debug')
});
});
module.exports = router;
This is the console log (I replaced anything long with "..." to save space)
var __stack = {
lineno: 1,
input: "<!DOCTYPE html>\n<html lang=\"en\"> ... </html>\n",
filename: "/web/app/views/index.ejs" };
function rethrow(err, str, filename, lineno){
var lines = str.split('\n')
, start = Math.max(lineno - 3, 0)
, end = Math.min(lines.length, lineno + 3);
// Error context
var context = lines.slice(start, end).map(function(line, i){
var curr = i + start + 1;
return (curr == lineno ? ' >> ' : ' ')
+ curr
+ '| '
+ line;
}).join('\n');
// Alter exception message
err.path = filename;
err.message = (filename || 'ejs') + ':'
+ lineno + '\n'
+ context + '\n\n'
+ err.message;
throw err;
}
try {
var buf = [];
with (locals || {}) { (function(){
buf.push('<!DOCTYPE html>\n<html lang="en">...</html>\n'); })();
}
return buf.join('');
} catch (err) {
rethrow(err, __stack.input, __stack.filename, __stack.lineno);
}
Like I said, it is working, however I can't tell why this is being logged in the console. Thanks for the help!
The problem is that the second argument passed to res.render() is passed to both the rendering engine AND your template. Because of this behavior, ejs (at least through 1.0 as of this writing), looks for a debug property in that object to determine if debug information will be printed.
I have a simple node.js server testing the connect-redis module as a session store. It all works but I've noticed that I get a new sess: key in redis on every single request. I expected only one key since there is only one session.
Here's my code :
var connect = require('connect');
var util = require("util");
var RedisStore = require("connect-redis")(connect);
var http = require('http');
var app = connect()
.use(connect.cookieParser('keyboard cat'))
.use(connect.query())
.use(connect.session( {
secret:"elms",
store:new RedisStore({prefix:'sid_'}),
cookie:{maxAge:60000, secure:false}
}))
.use(function(req, res, next) {
var sess = req.session;
if (sess.views) {
res.setHeader('Content-Type', 'text/html');
res.write("<p>" + util.inspect(req.cookies) + "</p>");
sess.basket = sess.basket || {book1:0, book2:0, book3:0};
if(req.query.buyBook1) {sess.basket.book1 ++;}
if(req.query.buyBook2) {sess.basket.book2 ++;}
if(req.query.buyBook3) {sess.basket.book3 ++;}
if(req.query.expiresession) {
sess.cookie.maxAge = 0;
}
res.write('<p>views: ' + sess.views + '</p>');
res.write('<ul>\
<li>book1 ' + sess.basket.book1 + ' - Add</li>\
<li>book2 ' + sess.basket.book2 + ' - Add</li>\
<li>book3 ' + sess.basket.book3 + ' - Add</li>\
</ul>\
Expire session');
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
res.write('<p>httpOnly: ' + sess.cookie.httpOnly + '</p>');
res.write('<p>path: ' + sess.cookie.path + '</p>');
res.write('<p>domain: ' + sess.cookie.domain + '</p>');
res.write('<p>secure: ' + sess.cookie.secure + '</p>');
sess.views ++;
} else {
sess.views = 1;
}
res.write("<p>" + util.inspect(req.cookies) + "</p>");
res.end('welcome to the session demo. refresh!');
});
http.createServer(app).listen(3000);
I've noticed that the req.session.cookie.domain is always null. I'm on windows 8 and using the hosts file to map 127.0.0.1 to www.gaz-node.com, which is what I exepected the cookie domain to be at the server. Could be related.
Any ideas?
Thanks
The answer was very simple. I got up especially early on this sunday morning in order to debug it and the answer became suddenly clear midway through my first mug of coffee, which subsequently tasted better than the first half.
The Revenge of the /favicon.ico Request
I wasn't handling the request from the browser for /favicon.ico which is bit of a gotcha for node newbies like me. Every request is followed by a /favicon.ico request (by Chrome at least) so the browser can display the site's icon. It never gives up until it gets a favicon.ico.
The actual session was working perfectly well, there was only one session id for that but the request for /favicon.ico doesn't send any cookies over and it was this that was triggering a new zombie session every request.
To fix this I added a module to handle the /favicon.ico request and serve a 404 response. I could just as easily have given the relentless browser a favicon and sent that instead using the "fs" module.
It's important that you handle the /favicon.ico and end the response, without calling next(), before you use the session module! Here's the fixed code :
var connect = require('connect');
var util = require("util");
var RedisStore = require("connect-redis")(connect);
var http = require('http');
var app = connect()
.use(function(req, res, next) {
if(req.url == '/favicon.ico') {
serve404(res);
} else {
next();
}
})
.use(connect.cookieParser())//"elms123"))
.use(connect.query())
.use(connect.session( {
secret:"elms123",
store:new RedisStore({prefix:'sid_'}),
cookie:{maxAge:60000, secure:false, domain:"gaz-node.com"}
}))
.use(function(req, res, next) {
var sess = req.session;
res.setHeader('Content-Type', 'text/html');
res.write('welcome to the session demo. refresh!');
if (sess.views) {
res.write("<p>" + util.inspect(req.cookies) + "</p>");
sess.basket = sess.basket || {book1:0, book2:0, book3:0};
if(req.query.buyBook1) {sess.basket.book1 ++;}
if(req.query.buyBook2) {sess.basket.book2 ++;}
if(req.query.buyBook3) {sess.basket.book3 ++;}
if(req.query.expiresession) {sess.cookie.maxAge=0;}
if(req.query.forceerror) {/*idontexist()*/throw new Error('ahhhh!');}
res.write('<p>views: ' + sess.views + '</p>');
res.write('<ul>\
<li>book1 ' + sess.basket.book1 + ' - Add</li>\
<li>book2 ' + sess.basket.book2 + ' - Add</li>\
<li>book3 ' + sess.basket.book3 + ' - Add</li>\
</ul>\
Expire session\
Force error');
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
res.write('<p>httpOnly: ' + sess.cookie.httpOnly + '</p>');
res.write('<p>path: ' + sess.cookie.path + '</p>');
res.write('<p>domain: ' + sess.cookie.domain + '</p>');
res.write('<p>secure: ' + sess.cookie.secure + '</p>');
sess.views ++;
} else {
sess.views = 1;
}
res.end("<p>" + util.inspect(req.cookies) + "</p>");
})
.use(connect.errorHandler());
http.createServer(app).listen(3000);
function serve404(res) {
res.writeHead(404, {"content-type": "text/plain"});
res.end("Error : Resource not found");
}
I also had this issue. Of course, we should use 'favicon' midlleware. And be sure to place 'session' middleware below 'static'. See my answer https://stackoverflow.com/a/21094838/3190612