ES6 modules in chrome: ERR_ABORTED 404 (not found) - node.js

I am making an ultra simplistic site using the new-ish module tags inside the html file I serve from node. I have the latest version of chrome.
My node js function: (appController)
exports.getMainPage = (req, res) => {
res.writeHead(200, {'Content-type': 'text/html'});
fs.readFile('./public/views/index.html', null, (err, data) => {
if (err) console.error(err);
else res.write(data);
res.end();
});
};
I'm using express:
const express = require('express');
const router = express.Router();
const appController = require('../appController');
router.get('/', appController.getMainPage);
module.exports = router;
The html file:
<html lang="eng">
<head>
<script type="module">
import { $, $$ } from '../javascript/modules/bling';
</script>
<title>Logs</title>
</head>
<body>
</body>
</html>
Webstorm confirms that the path is fine but the console keeps showing:
GET http://localhost:7777/javascript/modules/bling net::ERR_ABORTED 404 (Not Found)

Related

Serve multiple type files on pure node.js

I have a simple pure node.js server which sends back html page on request.
In my html page i have connected js file.
When i make a request i get on response the html page but no the js file.
In my console i got an error.
Uncaught SyntaxError: Unexpected token '<'
my node.js server file:
const http = require('http');
const fs = require('fs');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html', });
fs.readFile('index.html', function(err, data){
if(err){
return console.log(err);
}
res.end(data);
});
}).listen(8080);
console.log('Server is running on Port: 8080');
my html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>here</h1>
<script src="./app.js"></script>
</body>
</html>
Any suggestions how to send multiple files on request with pure js ?
You're currently serving all requests with index.html, so when the browser requests app.js you do not get the script, but the index-page instead, hence the error.
You'd need to check the request path in your server's callback and then send the correct file (see this for a more detailed example):
http.createServer(function (req, res) {
if (req.path === '/app.js') {
// read app.js file and send it to the client
} else {
res.writeHead(200, {'Content-Type': 'text/html', });
fs.readFile('index.html', function(err, data){
if(err){
return console.log(err);
}
res.end(data);
});
}).listen(8080);
You see that this is pretty cumbersome, so I highly recommend using a framework like express (it provides a middleware to serve static files out of the box) to do this.

Node js, i can't get my browser button to get a list of teams in the json file

I'm new to Node js, and i'm cuurently writing a program to fetch data from a local json file and display in the browser, but nothing happens when i click the button. Not getting errors either. The program runs as follows: 1). node app.js 2.) opens index.html on the server (127.0.0.1:3000) 3.) click the button "Get list of the team". the button has an action = "teams" and the Controller should invoke the action to fetch the teams from the json file. The Controller invokes the Model, then renders the data in the index.htm property called "teamList". Then i expect to see the teams displayed in the browser. Here is my code:
app.js:
const path = require("path");
const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');
const bodyParser = require('body-parser');
const router = require('./routes/router');
const app = express();
app.use(express.urlencoded({extended: false}));
app.use(express.json());
app.use(express.static("public"));
app.set("views" , "views");
app.set("view engine", "hbs");
const host = "127.0.0.1"
const port = 3000
app.use(cors());
app.use(bodyParser.json());
//app.use('/', router);
app.get('/', (req, res) =>{
res.render("index", {
teamsList: ""
})
})
app.get('/add', (req, res) =>{
res.render("post-tal", {
Sum: ""
})
})
app.listen(port, host, () => {
console.log(`The server is running at: http://${host}:${port}`);
});
index.html:
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>WebApp</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css">
<style>
.eNavAction {cursor:pointer}
.buttons {margin-top: 20px}
</style>
<script src="js/simple-helper.js"></script>
<script src="../controller/MainController.js"></script>
<script src="apiServer/controller.js"></script>
<script src="apiServer/model/apiServer-model.js"></script>
<script src="apiServer/routes/router.js"></script>
<script>
var Current = {};
const Model = new TeamsModel();
const View = new TeamView();
const ViewTal = new TalView();
const Controller = new MainController();
document.addEventListener('DOMContentLoaded', function() {
// Controller.init();
Helper.onClassClick('eNavAction', Controller.navAction);
});
</script>
</head>
<body>
<nav class="navbar is-link" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="/">
<span style="font-weight:bold; font-size:20px">My Web App</span>
</a>
</div>
<div id="navbar" class="navbar-menu">
<div class="navbar-start">
<a class="eNavAction navbar-item" action ="teams">Teams</a>
<a class="navbar-item" action= "tal" href="http://127.0.0.1:3000/add">Sum</a>
</div>
</div>
</nav>
<div class="section">
<div id="main-container">
<button class="eNavAction navbar-item" action ="teams">Get list of the team</button>
<div id="listContainer">
{{teamsList}}
</div>
</div>
</div>
</body>
</html>
MainController.js:
class MainContainer {
teamList = (req, res) => {
Model.loadTeams()
.then(function (data) {
res.json(data);
//res.send(data);
res.render("index", {
teamList: {data} // A property called teamList to be displayed on the browser
})
})
.catch(error => console.log(error));
}
navAction() {
let action = this.getAttribute('action');
if (action == "teams") {
Controller.teamList();
}else if(action == "tal")
Controller.calculateSum();
}
}
Model.js
class TeamsModel {
async loadTeams() {
try {
const json = await fetch('./json/prov-nodes.json', 'utf8')
.then(function(response){
return response.json();
})
.then(function(data){
console.log(data);
});
}catch (error) {
console.log(error)
}
}
}
I tried to reconstruct your problem. First of all I show that I fixed code and get result:
that code in controller.js (Model.js)
class TeamsModel {
async loadTeams() {
try {
const json = await fetch('/data/prov-nodes.json')
return json.json(); // Important! return must be in loadTeams!
}catch (error) {
console.log(error) // it'll never been shown!
}
}
}
As you can see I used '/data/prov-nodes.json' as path. Yes now I can access to file that I had not before by './json/prov-nodes.json'.
I just add two strings in app.js:
app.use('/js', express.static(__dirname + '/controllers')); // allows an access
app.use('/data', express.static(__dirname + '/json')); // allows an access
so import of scripts looks like:
<script src="/js/MainController.js"></script>
<script src="/js/controller.js"></script>
in index.hbs file I just do:
const Model = new TeamsModel();
const Controller = new MainController();
Controller.teamList()
I renamed MainContainer class to MainController class (just for test)
...
teamList = (req, res) => {
Model.loadTeams()
.then(function (data) {
console.log('DATA', data); // just output to console if success
})
.catch(error => console.log(error));
}
...
I believe that this helps you continue coding!
I'm not sure that I reconstruct your code right (models/controllers), but I have showed you how to read json file in express.
├── app.js
├── controllers - just modules not real controllers :)
│ ├── MainController.js
│ └── controller.js - I think this would be a model, sorry :)
├── json
│ └── prov-nodes.json
├── package-lock.json
├── package.json
└── views
└── index.hbs

POST request not working in NodeJs app in Cpanel

I was creating a Node App using Express JS. There's a route which accepts a POST Request. The app works fine on localhost, but when I host on Cpanel Shared Hosting, I get the following error for POST request. GET works fine. Can anyone please help or guide where I went wrong?
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /v1/email</pre>
</body>
</html>
My Express JS code
var app = express();
var em =require('./mailjet')
var bodyParser = require('body-parser');
app.use(bodyParser.json())
app.get('/v1', function (req, res) {
return res.json('Hello World');
})
app.post('/v1/email', function (req, res) {
let {name, email, message}=req.body
if (!name || !email || !message){
return res.status(400).send({
'Message':'Bad Request'
})
}
em.request(name, email, message)
return res.status(200).send({
'Message':'Email Sent'
});
})
app.listen()

Stylesheet not loaded, even though statics has been configured

I'm going crazy over this...
I have this simple NodeJS server running - it serves the ./start.html file fine, but the CSS-file is not loaded.
My folder structure looks like this:
/public/css/styles.css
/interface.js (the Node-file)
/start.html
Node is running this code:
const app = express();
const hostname = '127.0.0.1';
const port = 3000;
let serials;
app.use(express.static('public'));
// Make these folders accessible by our HTML-files
app.use('/css', express.static(__dirname + '/public/css'));
//app.use('/js', express.static(__dirname + '/public/js')); // Not used at the moment
//app.use('/images', express.static(__dirname + '/public/images')); // Not used at the moment
app.get('/start', (req, res) => {
const fs = require('fs');
var content;
// We load the file asynchronously and pass on the content to the screen when loaded.
fs.readFile('./start.html', function read(err, data) {
if (err) {
throw err;
}
res.writeHead(200, { 'Content-Type': 'text/html', 'Content-Length': data.length, 'Expires': new Date().toUTCString()});
res.end(data);
});
});
The start.html file looks like this:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>start</title>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<link href="css/styles.css" rel="stylesheet" type="/text/css">
<script type="text/javascript">
$(document).ready(function() {
etc...
When accessed, using localhost:3000/start, it only shows the HTML-code.
When opening localhost:3000/css/styles.css it displays the stylesheet just fine.
The browser console also does not show any CSS-file loaded.
Any suggestions, please?
Simple mistake: the CSS linkage had a "/text/css" instead of "text/css" and not an error in the JS after all. Now it works perfectly.

Express static css not served

I have been trying to figure this out for hours and my head is about to explode. I really hope it's not some stupid little detail I missed...
I have a server-side rendering react application set-up. Everything is going fine. The only problem I have is that I can't seem to get the css to load.
Here is my file tree (without node_modules): https://i.stack.imgur.com/xevUb.png'
I have the following code in my server.js file
app.use('static', express.static(__dirname + '/public'));
app.use('dist', express.static(__dirname + '/dist'));
app.get('*', (req, res) => {
match({
routes,
location: req.url
}, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
var html = renderToString( < RouterContext { ...renderProps
}
/>);
res.status(200).send(template({
body: html
}));
}
else {
res.status(400).send('Not found.')
}
});
});
And this is my template.js file :
export default ({ body }) => {
return `
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="/static/css/style.css" />
</head>
<body>
<div id="root">${body}</div>
</body>
<script src="dist/client.js"></script>
</html>
`;
};
When I go on my local server. I get the html delivered and the bootstrap styles are applied to it. However, I get a 400 bad request error for the style.css and client.js linked in my template.js file.
I really hope someone can help me out on this one...
EDIT
Here is what I see on the developer console :
Your server.js file appears to be inside your dist folder, which means that __dirname would be ./dist instead of ./ like your code seems to be written. What you need to do is something like this:
const path = require('path')
const projectRoot = path.resolve(__dirname, '../')
app.use('static', express.static(projectRoot + '/public'))
app.use('dist', express.static(__dirname))

Resources