I watched a Youtube video & copied the code from it but my page is not loading properly, It looks like this-
Node.js code -
import express from "express";
import bcrypt from "bcrypt";
//init server
const app = express();
//middlewares
app.use(express.static("public"));
app.use(express.json())//enables from sharing
//routes
//home route
app.get('/', (req, res) => {
res.sendFile("index.html", {root : "public"})
})
// 404 route
app.get('/404', (req, res) => {
res.sendFile("404.html", {root : "public"})
})
app.use((req, res) => {
res.redirect('/404')
})
app.listen(3000, () => {
console.log('listening on port 3000');
})
You are using a file: path inside of your HTML code (or other public files) which isn't possible as you aren't reading from a filesystem, you are using HTTP. Use proper paths instead in your links.
Related
I made the following code to send .zip file upon get request to localhost:3000 but the file is being download without filename and without extension
const express = require("express");
const app = express();
app.get("/", async (req, res) => {
res.sendFile("/files/a.rar", {
extensions:["rar", "zip"]
})
})
app.listen(3000, () => {
console.log("server connected");
});
how i can do this
Have you tried using res.download(...) instead of res.sendFile(...)?
I had the same issue and I was able to make it work by using this code block.
import path from 'path';
...
app.get("/", async (req, res) => {
res.download(path.resolve('files/a.rar'), {
extensions: ["rar", "zip"],
});
});
Give it a try!
I'm new to frontend development and express server. When I tried to start an express.js server with react (with axios calls to external apis), it seems express.js is adding 'localhost:3000' in front of the external API calls so they fail.
In my server.js:
const path = require('path');
const express = require('express');
const app = express();
const publicPath = path.join(__dirname, '.', 'dist');
const port = process.env.PORT || 3000;
app.use(express.static(publicPath));
app.get('*', (req, res) => {
res.sendFile(path.join(publicPath, 'index.html'));
});
app.listen(port, () => {
console.log('Server is up!');
});
Which leads to the API call to www.example.com/api/ to become http://localhost:3000/www.example.com/api/
I also tried to filter the req by writing:
app.get('*', (req, res) => {
if (req.url.match(/\/api\//) === null) {
res.sendFile(path.join(publicPath, 'index.html'));
}
});
But it does not change things...
Can anyone help out this newbie that is me?
Update1 Adding the code for calling the api:
This is the api call:
const getSomething = () => {
try {
const url = endpoints.GET_SOMETHING;
return axios.get(url);
} catch (err) {
console.log(err);
}
};
endpoints.GET_SOMETHING is the api URL: www.example.com/api/getSomething
You need to put a / in the url
app.get('/*', (req, res) => {
res.sendFile(path.join(publicPath, 'index.html'));
});
and also your endpoint url should start with https://, http:// or //
My goal is
To print a message to my console when a user enters a specific page
To make it possible to access a page without having to write the .html extension.
If i use the following, where test.html is not an existing page, i will see
the expected message in my console when the user tries to access /test or /test.html page.
router.get(/^\/test(\.html)?$/, async (req, res) => {
console.log('User trying to access test.html page')
res.send('welcome to test page')
})
But if i do the same for an existing page (/dashboard.html)
router.get(/^\/dashboard(\.html)?$/, async (req, res) => {
console.log('User trying to access dashboard.html page')
res.send('welcome to dashboard page')
})
I will see the expected message in my console when the user tries to access /dashboard but when he tries to access /dashboard.html the page will just load without seeing any message in my console.
Why is this happening?
I think the problem is that you are telling your app to use the static files before you tell your app to use your router.
I mean, if you do this (let´s say we have in the public folder the dashboard.html file):
const express = require("express");
const app = express();
const router = express.Router();
const port = 3000;
router.get(/^\/test(\.html)?$/, async (req, res) => {
console.log("User trying to access test.html page");
res.send("welcome to test page");
});
router.get(/^\/dashboard(\.html)?$/, async (req, res) => {
console.log("User trying to access dashboard.html page");
res.send("welcome to dashboard page");
});
app.use("/", router);
app.use(express.static("public"));
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
It should work as you expected.
However it seems you are placing the app.use(express.static...) before the app.use router. Something like this:
const express = require("express");
const app = express();
const router = express.Router();
const port = 3000;
app.use(express.static("public"));
router.get(/^\/test(\.html)?$/, async (req, res) => {
console.log("User trying to access test.html page");
res.send("welcome to test page");
});
router.get(/^\/dashboard(\.html)?$/, async (req, res) => {
console.log("User trying to access dashboard.html page");
res.send("welcome to dashboard page");
});
app.use("/", router);
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
So in this case when you type the exact path for the dashboard.html it won´t use the router to resolve the content and it will simply take it from the public folder.
It is just a matter of order for the app.uses(...) in the code
I have an application built with reactjs with node js backend by using Create React App library.
in Nodejs-server.js I have the following code structure.
import express from 'express';
import path from 'path';
import bodyParser from 'body-parser';
import cors from 'cors';
import visitors from './routes/visitors';
import { cronNotification } from './cron/cron.js';
let app = express();
app.use(bodyParser.json({ limit: '15mb' }))
app.use(cors())
app.use('/api/visitors', visitors)
app.use('/docs/visitorTickets', express.static(path.join(__dirname, '../docs/visitorTickets')));
app.use('/images', express.static(path.join(__dirname, '../assets/images')));
app.use(express.static(path.join(__dirname, '../../build')));
app.get('/*', function (req, res, next) {
res.sendFile(path.join(__dirname, '../../build', 'index.html'));
});
app.use((req, res) => {
res.status(404).json({
errors: {
global: "Page Not Found."
}
})
});
let port = 8080
app.listen(port, () => console.log('Running on port:'+port));
cronNotification();
In Visitor file I have following code
import express from 'express';
import QRCode from 'qrcode';
import pdf from 'html-pdf';
let router = express.Router();
router.get('/test', (req, res) => {
res.json({ success: "test success page." })
});
router.get('/pdf', (req, res) => {
let html = '<div>test value</div>';
pdf.create(html).toStream((err, pdfStream) => {
if (err) {
return res.sendStatus(500)
} else {
res.statusCode = 200
pdfStream.on('end', () => {
return res.end()
})
pdfStream.pipe(res)
}
});
});
export default router;
This code working perfect with front end react app by using http://localhost:3000/test.
It gets the result via API from axios library from react action page.
In developr tool network -> result shows: success: "test success page."
Now the issues is:
When I access
http://localhost:8080/api/visitors/pdf OR
http://localhost:8080/api/visitors/test
Directly in browser, It shows blank page (directly frot end source is appearing from console)
While access it from private window, It shows the result.
It tried it with diffrent browsers and diffrent computers but issue remain the same.
I am suspecting something wrong in this code
app.use(express.static(path.join(__dirname, '../../build')));
app.get('/*', function (req, res, next) {
res.sendFile(path.join(__dirname, '../../build', 'index.html'));
});
It is neglecting app.use path (app.use('/api/visitors', visitors))
Kindly help me out why this is working only in private browser?
After a long battle, I have fixed that issue by unregister react's registerServiceWorker
import { unregister } from './registerServiceWorker';
unregister();
So, why you need to res.sendFile to send an html page ? Let try to use ejs or jade view engine and then :
app.get('/*', function (req, res) {
return res.render('../path_to_ejs_view_file');
});
Or in your case maybe call next() function can solve problem:
app.get('/*', function (req, res, next) {
res.sendFile(path.join(__dirname, '../../build', 'index.html'));
next();
});
By the way, I have an project like you. Use Nodejs for api and Reacjs for SPA here: https://github.com/dangminhtruong/havana hope it useful
I am debugging into a NODE JS application and I am very new to node js. I have a REST module file
students.js
module.exports = function (service) {
/**
* Retrives data from DB
*/
service.get('/mobile/students', function (req, res) {
res.set('Content-Type', 'application/json')
.status(200)
.json(DBHelper.getAllStudents());
});
service.post('/mobile/students', function (req, res) {
res.status(200).json(data);
});
});
To run it locally I am using the following app.js
const express = require('express');
const app = express();
var routes = require('./students');
app.get('/', function (req, res) {
res.send('Hello World!')
});
app.listen(3010, function () {
console.log('Example app listening on port 3010!')
});
When I hit
http://localhost:3010/students, I am hitting a 404.
How do I explicit route the path to the student modules?
you need to add routes(app); line after var routes = require('./students'); then Your routes will be mounted..
http://localhost:3010/students if use this it will prompt you again with 404 but if you use http://localhost:3010/mobile/students it will produce desire output..