Im trying to refresh a clients webpage (using a router) and everywhere I look I see something along the lines of using res.redirect(same page link of some sort), however for some reason this isnt working for me, do you know of any alternatives?
my code looks something like this
router.post('/sendSnippet', function (req, res) {
req.on('data', function(data) {
User.findOne({email: req.user.email}).then((userToEdit) =>{
if(userToEdit){
var newSnippet = {
"types":[],
"code": data.toString()
}
userToEdit.snippets.push(newSnippet)
userToEdit.save().then(()=>{
//refresh here
res.redirect('/profile/');
})
}
})
})
});
thanks for any help in advance
Assuming you are trying to force-reload a client's browser tab for your website, I don't think you can do that server-side.
You can use meta http-equiv or the Refresh HTTP header to tell the client's browser to refresh the page after some time or use client javascript to refresh the page:
Router:
router.post("/example", (req, res) => {
res.header("Refresh", "10"); // tells the browser to refresh the page after 10 seconds
res.send("your data");
});
Meta:
<head>
<!-- Refresh after 10 seconds -->
<meta http-equiv="refresh" content="10">
</head>
Javascript + html:
<html>
<body>
<script>
// reloads after 10 seconds
setTimeout(() => {
location.reload();
}, 10000);
// or you could have some kind of API to tell when to refresh the page
function check() {
const x = new XMLHttpRequest();
x.open("GET", "some path");
x.send();
x.onload = function() {
if (x.response === "done") {
location.reload();
} else {
setTimeout(check, 1000);
}
}
}
check();
</script>
</body>
</html>
Related
In the server script I try to deliver different html files. When app.post('/login'...) comes in, res.sendFile() is working and the html gets rendered. On the second call, whenn app.get('/go') comes in, the file gets served, but not displayed. I cannot explain why the second HTML file is not displayed. What am I doing wrong?
the second request comes from a fetch request in a javascript
socket.on('gameStarted', (data) => {
console.log("Game started");
fetch('/go', {method: 'GET'});
})
served but not displayed
app.post('/login', async (req, res, next) => {
var roomNR = req.body.player.gameCode;
var playerName = req.body.player.nickname;
var codeValid = await checkCode(activeRoomsCollection, gameCodes, roomNR);
var playerExists = await playerCollection.findOne({ playerName: playerName })
if (codeValid) {
if ((playerExists === null) || !playerExists) {
playerCollection.insertOne({ room: roomNR, playerName: playerName, state: false });
console.log(`Added player '${playerName}' with roomnumber '${roomNR}'`);
res.sendFile(path.join(__dirname + '/../../public/lobby.html'), function (err) {
if (err) {
console.log(err);
res.status(err.status).end();
}
else {
console.log('Sent Lobby');
}
});
} else {
// updateDomElement(player, elementId, data)
//res.send('Benutzername existiert bereits');
}
} else {
res.send('Code ungültig');
}
});
app.get('/go', (req, res, next ) => {
res.sendFile(path.join(__dirname + '/../../public/raetsel1.html'), function (err) {
if (err) {
console.log(err);
res.status(err.status).end();
}
else {
console.log('Sent Raetsel1');
}
});
});
fetch() never displays anything on its own. It's a way for your Javsascript to issue http requests to remote servers and those servers then return content back to your Javascript. The result from those http requests ONLY goes to your Javascript. Nothing in the view of the page is affected at all by a fetch() call.
If you want the result of a fetch() call to display something in your page, you would need to write Javascript to do that (to insert content into the current page).
If, instead, you just want the browser to go to a new page, then change from this:
fetch('/go', {method: 'GET'});
to this:
window.location = "/go";
This will cause the browser to go to the URL, retrieve the content and display it. This will shut-down the current page and load and display a new page and the URL in the URL-bar in the browser will show the updated location.
Note that if you have socket.io code in both pages, it will disconnect the current socket.io connection and then run the Javascript in the new page - causing it to create a new socket.io connection (if you have code in the new page to do that) as that is what happens to socket.io connections when you load and display a new web page in the browser.
This question already has answers here:
XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header
(11 answers)
Closed 4 years ago.
I am trying to get data from the back end Node server from the front end using a POST request but the HTML doesn't seem to catch and display the data properly. I've tested the backend using Postmaster and the data comes out fine. Can anyone help me out here? As the project complete code is kinda huge, I'll add the relevant snippet for now.
Backend is node.js:
#!/usr/bin/env node
app.post('/data', urlencodedParser, function(req, res) {
//config = DB auth data
var pool = new pg.Pool(config);
pool.query('SELECT url FROM imgs WHERE uid=$1 OR uid=0', [usid], function(err, result) {
if (err) {
console.log(err);
res.status(400).send(err);
}
imgs = JSON.stringify(result.rows);
res.send(imgs);
});
// Rest of the code ...
}
});
<html>
<body>
<button type="button" onclick="server()">submit</button>
<p id="demo"></p>
<script>
function server() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("POST", "http://localhost:8000/data", true);
xhttp.send();
}
</script>
</body>
</html>
UPDATE : Turns out I need CORS to make this work. Thanks everyone for helping me out and #Quentin for finding what I was missing.
Try using Jquery,
In your backend, your xhttp request can be replaced as below :
function server() {
var body = {"name":"Bob"}; //whatever data you want to pass to the post request
$.ajax({
type: "POST",
url: 'http://localhost:8000/data',
data: JSON.stringify(body),
success: function(result) {
console.log(result);
},
contentType: 'application/json'
});
}
I need some help understanding how this redirect works (and why isn't doing what I think it's supposed to do):
Problem:
I have an HTML page with a "logout" button that triggers a jQuery snippet:
$.ajax({
type: "POST",
url: "https://localhost:8000/chat",
data: {logout_msg: "get_out"},
success: (data, textStatus, jqXHR) => {
},
dataType:"json"
});
The button works, I catch the "POST" in my NodeJS server, here:
app.post('/chat', (req, res) => {
req.session.destroy((error) => {
if (!error) {
res.redirect("/login");
} else {
console.log(error);
}
});
The response is received by the browser:
But there is no web-page redirect. The browser won't load the other redirect page. I tried this in Firefox & Chrome. Both behave the same way, so I assume it's something in my code. What am I missing? Thanks.
You only "redirect" the request of jquery. If you want to open an other page in the Browser, then send the logout request with an HTML form or use location.href = '...' in the success handler.
You do not need JQuery to do simple log out.
Just add in HTML
<form action="/logout" method="post">
And in server side
app.post('/logout', (req, res) => {
req.session.destroy((error) => {
if (!error) {
res.redirect("/login");
} else {
console.log(error);
}
});
Hope this helps.
In an Express-based app, I'm running an async function to fetch image source from a database and render them into a Nunjucks view engine
Nunjucks is rendering the following in the DOM
<img src="[object Promise]">
I have already enabled Nunjucks's async rendering with web: { async: true } and enabled the nunjucks async api with a callback like so
// controller.js (KeystoneJS app)
view.render('index', function (err, res) {
console.log('err at index render', err); // undefined
return res;
});
How can i get the resolved value of my async function?
As I understand it, Nunjucks doesn't support asynchronous render directly. You can use asynchronous filters to get it. Maybe I'm wrong.
Imho, use feature with Be Careful! mark is a not good idea.
// template.njk
Hello {{user_id | find | attr('name') }}!
// app.js
var nunjucks = require('nunjucks');
var env = nunjucks.configure();
// Async filter
env.addFilter('find', function(a, cb) {
setTimeout(function () {
cb(null, {
name: 'Smith'
});
}, 10);
}, true)
// Sync filter
env.addFilter('attr', function(obj, attr) {
return obj && attr && obj[attr];
});
env.render('template.njk',
{user_id: 1}, // pass sync vars
function(err, res) {
if (err)
return;
console.log(res);
return res
}
);
I don't know about nunjucks, but you can implement async functionality regardless of the view engine being used. To show the idea, I tried to reproduce your situation. I created an HTML file named index.html with an img tag without any src attribute:
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Reproduce</title>
</head>
<body>
<img id='bg'></img>
<script src='./so.js'></script>
</body>
</html>
I have a <script> tag in my HTML which links to my so.js file shown below by which an image is requested by sending a HTTP request to NodeJS/Express server:
getImage();
function getImage(){
// Get an image by its name as URL parameter
fetch('/bg/background.jpg',{
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}).then(result=>{
return result.blob()
}).then(result=>{
console.log('result -> ', result)
document.querySelector('#bg').src=URL.createObjectURL(result)
document.querySelector('#bg').style.width='200px'
}).catch(err=>{
console.log('err -> ', err)
})
}
Here is my NodeJS/ExpressJS code inside a file name server.js:
express=require('express')
bodyParser=require('body-parser')
path=require('path')
fetch=require('node-fetch')
server=express()
//Body-parser middleware
server.use(bodyParser.json())
server.use(bodyParser.urlencoded({extended:false}))
server.use(bodyParser.raw())
//Set static path
server.use(express.static(path.join(__dirname,'public')))
server.get('/',(req,res)=>{
res.render('index.html')
})
// Pick a file on hard disk
// and send it as "Blob" to the browser
server.get('/bg/:name',(req,res)=>{
var options = {
root: __dirname + '/public/',
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
var fileName = req.params.name;
res.sendFile(fileName, options, function (err) {
if (err) {
next(err);
} else {
console.log('Sent:', fileName);
}
});
})
server.listen('8000',()=>{
console.log('Server listening on port 8000...')
})
As can be seen, I'm doing my async communication between browser and server by implementing fetch API and without even touching the view engine.
I just wanted to provide an alternative idea to use fetch API and do the async HTTP communications with it regardless of any view rendering engine that is being used.
I am trying to scrape the below mentioned URL and trying to extract the link in the tag,using PhantomJS.
The link sends back javascript code which is executed on the browser to form the HTML inside the Body.
The problem is PhantomJS is not executing the Javascript and I am getting the unfinished HTML after executing my code.
Index.js
var page = require('webpage').create();
console.log('The default user agent is ' + page.settings.userAgent);
page.settings.userAgent = 'SpecialAgent';
page.open('http://videohost.site/play/A11QStEaNdVZfvV/', function(status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var html = page.evaluate(function() {
return document.getElementsByTagName('body')[0].innerHTML;
});
console.log(html);
}
phantom.exit();
});
I execute it using phantomjs index.js in the console t check the HTML.
Any help regarding how would the script inside the would be executed would be much appreciated.
Update:
works with NightMareJS as according to Vaviloff's suggestion.
app.get('/scrape', function (req, res) {
//All the web scraping magic will happen here
console.log('Scrape')
url = 'http://videohost.site/play/A11QStEaNdVZfvV/'
nightmare
.goto(url)
.evaluate(function(){
return document.body.innerHTML; //pass all of the html as text
})
.end()
.then(function (document) {
console.log(document)
})
.catch(function (error) {
console.error('Search failed:', error);
})
res.send('Woohoo')
})
app.listen('8081')
console.log('Magic happens on port 8081');
exports = module.exports = app;