Im trying to get nodejs http to serve a vuejs application.
Vue is configured as SPA with history mode enabled.
My nodejs server is set up like this:
http.createServer((req, res) => {
fs.readFile('dist/index.html', 'utf-8', (err, content) => {
if (err) {
console.log('We cannot open "index.html" file.')
}
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8'
})
res.end(content)
})
}).listen(port, () => {
console.log('Server listening on: http://localhost:%s', port)
})
Taken from here: https://router.vuejs.org/guide/essentials/history-mode.html#native-node-js
This does indeed start the server and i can navigate to localhost:3000 but see a blank page.
Problem is, that with this configuration the server always returns the index.html file. Which is not wanted for static files like .js files, which results in errors.
How do i have to configure my http server so Vue will work as expected?
You have to serve the whole dist folder, not just the index file so it can get the whole vuejs app.
You can make this easier for you by using modules like https://github.com/cloudhead/node-static
const static = require('node-static');
const http = require('http');
const distFolder = new static.Server('./dist');
http.createServer(function (req, res) {
distFolder.serve(req, res);
}).listen(port, () => {
console.log('Server listening on: http://localhost:%s', port)
})
With expressjs this would become
const express = require('express')
const app = express()
app.use(express.static('dist'))
app.listen(port, () => {
console.log('Server listening on: http://localhost:%s', port)
})
EDIT:
Fallback for history mode:
http.createServer(function (req, res) {
distFolder.serve(req, res, function (err, result) {
// Fallback for history mode
if (err !== null && err.status === 404) {
distFolder.serveFile('/index.html', 200, {}, req, res);
}
});
}).listen(port, () => {
console.log('Server listening on: http://localhost:%s', port)
})
You are right, the example is a bit misleading. They say "If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in." on the page but example completely ignores other static files.
You can use express - see this SO answer
Related
I'm trying to run Next js application on my Digital Ocean Droplet (with OpenLiteSpeed).
I have start.js file with the following content:
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
handle(req, res, parsedUrl)
}).listen(80, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:80')
})
})
When I calling this file from console: node start.js, my site successfully running on port 80.
But when I'm trying to add this file as a start up file in App Server Context Definition, site is not running, and my website just cannot be reached.
But when I'm changing the file to default one (app.js):
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World! From OpenLiteSpeed NodeJS\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://:/`);
});
The website is successfully opening with Hello World.
Listener is successfully setup to port 80:
Grace restart is done. changing ports to 3000 (for example) not helping much: I got same behavior.
What I am doing wrong?
UPDATE:
I found temporary solution:
node start.js & disown
and then close the Terminal.
Please anyone give me drawbacks of this method.
I'm on shared hosting and let's say my domain is example.com and I want to run a socket.io app in one folder called myapp so it can be accessed from here: example.com/myapp. Then I install node.js and put the app.js file right under example.com/myapp so whenever I access it I get the confirmation message: hello world node.js. The file looks like this:
const http = require('http')
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello world node.js \n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
next, I install the modules, inside the same folder: npm install express and npm install socket.io so I get a folder called node_modules directly under /myapp so the path will look like myapp/node_modules, right?
My question is, where do I put the files of my socket.io app (it's a chat)? The index.js file looks like this:
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
socket.on('chat message', msg => {
io.emit('chat message', msg);
});
});
http.listen(port, () => {
console.log(`Socket.IO server running at http://localhost:${port}/`);
});
Should I put it in the same folder as app.js or somewhere else? Because if I put it along with app.js then this happens: if I access example.com/myapp I get the "hello world" page, which I don't want whereas in order to see the front page of my chat app I need to add a / like this: example.com/myapp/ but that is not accepted by cpanel as a valid application on the application manager. What's the right method to do this?
Thank you.
Follow on from this question: Axios can GET but not POST to the same URL
I've been trying to figure this out for too long now.
I want to POST from my React app to a .JSON file. Can anyone tell me what I'm doing wrong?
My AJAX POST function using axios always returns a 404. I'm listening for it on the node server but app.post never fires.
Thanks.
POST request from my React app:
postJson = (postJsonData) => {
axios.post('./postJson/', {
postJsonData
})
.then(function (response) {
console.log("success!");
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
app.js (node server):
/*========== Default Setup for node server copied from node website ==========*/
const http = require('http');
const hostname = '127.0.0.1';
const port = 3001;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
/*========== Listen for POST (Trying to get the data from my REACT app
- will then assign it to "obj" below) ==========*/
var express = require("express");
var myParser = require("body-parser");
var app = express();
app.post("./postJson/", function(request, response) {
console.log("MURRRR");
console.log(request.body); //This prints the JSON document received (if it is a JSON document)
/*=== JSON Stuff ===*/
var jsonfile = require('jsonfile')
var file = './scene-setup.json'
var obj = {name: 'JP'}
jsonfile.writeFile(file, obj, function (err) {
console.error(err)
})
});
//Start the server and make it listen for connections on port 3000
app.listen(3000, function(){
console.log("server is listening to 3000");
});
Two things I noticed:
Your post endpoint doesn't need a leading "." I would make it just "/postJson"
Make sure you are posting to "http://localhost:3000/postJson"
Make sure you have the network tab open to see the actual URL you are requesting to.
Cheers
Turns out both react and my node server were running on localhost:3000 simultaneously which is apparently not okay.
Running my node server on localhost:3001 from a new command line window allowed me to do both at the same time.
Not sure how this would work when making a production build though.
I'm working with node and express. I try to create a simple server using express.static. I have a file in the following folder on my server :
client/index.html
However, when I try this url : http://myServer.com/index.html, the server answers that :
Cannot GET /index.html
Here, you will find my used code :
var express = require('express');
var app = express();
app.use(express.static('client'));
/*
app.get('/', function (req, res) {
res.send('Hello World!');
});*/
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
My file index.html is available. I already used other way to keep this like by using
app.get('/index.html', function (req, res, next) {
var options = {
root: __dirname + '/client/',
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
res.sendFile("index.html", options, function (err) {
if (err) {
console.log(err);
res.status(err.status).end();
}
else {
console.log('Sent:', "index.html");
}
});
});
And this approach works.
You said that you were trying this URL:
http://myServer.com/index.html
But, your server is listening on port 8080, so you need to use this URL:
http://myServer.com:8080/index.html
or this:
http://myServer.com:8080
Because express.static() will automatically use index.html for the / path.
FYI, when I run your first block of code on my laptop with the proper URL, it works just fine. The browser shows me the contents of client/index.html where "client" is a sub-directory below where my app.js file is run from to start the server.
I'm trying to create an http server. The server is created correctly but does NOT show the html content. It works when I do it without listeners. What am I failing then?
app.js
var server = require("./server.js");
server.server3((req, res, html) => {
res.writeHead(200, {"Content-Type": "text/html"});
html.pipe(res);
res.end();
}, 3000, "./index.html");
server.js
function Server3(applyFunction, port, path) {
var fs = require("fs"),
html = fs.createReadStream(path.toString().trim()), // Create stream from path
http = require("http");
html.on("data", _ => {})
.on("end", () => { // create server when all data is ready
http.createServer(function(req, res){ // createServer method
applyFunction(req, res, html); // execute the function
}).listen(+port); // add the port
});
}
module.exports.server3 = Server3;
If you're just trying to create an HTTP server on node.js, using the express framework (npm install express --save) would simplify your life a great deal. If you place the index.html file in the same directory as app.js, you can create the server with the following 5 lines of code:
// Setup Express
const express = require("express");
const app = express();
// Use main directory to find HTML file
app.use(express.static(__dirname));
// Render index.html
app.get("/", (req, res) => res.render("index"));
// Start Server on port 3000
app.listen(3000, () => console.log('Server started on port 3000'));