i wrote an api node.js mysql and i created a folder called images in the same directory with index.js file , but when go to http://localhost:3000/images/bike.png a message says that Cannot GET /images/bike.png
the same message also for Cannot GET /images
my index.js file
/* RESTFUL SERVICES BY NODEJS */
var express = require('express');
var mysql = require('mysql');
var bodyParser = require('body-parser');
//connect to mysql
var con = mysql.createConnection({
host: 'localhost' ,
user: 'root' ,
password: '',
database: 'nodeapp'
})
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static('images/'));
//connect to database
con.connect((err) =>{
if(err) throw err;
console.log('Mysql Connected...');
});
/Server listening
app.listen(3000,() =>{
console.log('Server started on port 3000...');
});
how to make images folder accessible and to go to the bike.png by url
Firstly you should remove the trailing slash in app.use(express.static('images/')); as #ptothep already mentioned.
If you don't indicate a route for static assets they will be accessible from a root URL like this localhost:3000/bike.png.
If you wish to map images folder to /images then indicate this route like this:
app.use('/images', express.static('images'));
See Static files
Related
I have created a simple Express JS app. and it is working fine in localhost. when I visit localhost:8000 I see static files (index.html, style.css and frontend.js).
I have tried to deploy that app in a server using cPanel. and I have installed Node app and dependencies using package.json successfully. But when I visit the domain I just see a message (Node JS app is working, Node version is 10.24.1).
How to make my app to point and display the static folder (index.html) and run the app?
My app architecture:
server.js
package.json
public/index.html
public/style.css
public/frontend.js
And here is my server.js startup file:
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Dependencies */
const bodyParser = require('body-parser');
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('public'));
// Setup Server
const port = 8000;
const server = app.listen(port, function(){
console.log(`server running on localhost: ${port}`);
});
//POST Route to store data in the app endpoint, projectData object
app.post('/addData', addData);
function addData (req, res){
let data = req.body;
projectData = data;
console.log(projectData);
}
app.get('/getData', getData);
function getData(req, res) {
res.send(projectData);
}
The problem here is that you are not pointing a route to send the HTML file. Otherwise the client would have to point it to the correct path of the file, Like localhost:3000/index.html.
you need to send it from the server using app.get
app.get("/", (req, res) => {
res.sendFile(__dirname + "path to the file");
});
The problem was that I have created the app in a subfolder of my domain.
But when I have created subdomain and reinstalled the app inside it, the app is pointing to static folder successfully.
I am trying to make a front end using node js and angular.
For the backend, I am trying to access the couchdb data in the code as follows:
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const NodeCouchdb = require('node-couchdb');
const couch = new NodeCouchdb({
auth:{
user: 'admin'
password: '**' ///hidden for security
}
});
couch.listDatabases().then(function(dbs){
console.log(dbs);
});
const app = express();
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use (bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.get('/', function(req,res){
res.render('index');
});
app.listen(3000, function(){
console.log('Server is started on Port 3000');
})
My couchdb host is something like this
*http://admin#***#172.26.132.189:5984*
The above code is just trying to list the databases in my couch db server. But when I run the code it gives me the following error:
{error:unauthorised: name or password is incorrect}
I tried defining my host also in the above code by adding these lines:
const couchExternal = new NodeCouchDb({
host: 'couchdb.external.service',
protocol: 'https://172.26.132.189',
port: 5984
});
But still gives me the same error.
I am giving the correct credentials.
Can someone please help me with a solution or tell me where I'm going wrong?
you are missing a coma after the user i.e. it should have been like: user:'admin', password.... so on since auth is an object variable. Check out this video for more help:
https://www.youtube.com/watch?v=R6LUMXrAoCE&list=PLx3witYKF_5KjQj8i_OTrYbm8WNcZdccG
I've got a React app that via an API pulls data from a separate database.
When I run it locally, the app is one port and the API is on another port.
Since when I make AJAX calls in the app to the API, I need to include the URL where the API can connect.
It works if I hardcode the separate port (e.g., the app is on http://localhost:3000 and the API on http://localhost:3100, making the AJAX url call to the API http://localhost:3100/api/trusts).
However, since the app and API are on different ports, I can't make the AJAX url a relative path because it erroneously sends the AJAX call to http://localhost:3000/api/trusts and not http://localhost:3100/api/trusts.
How do I get them to run on the same port?
Thanks!
Here's my server.js:
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var path = require('path');
var app = express();
var router = express.Router();
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//set our port to either a predetermined port number if you have set it up, or 3001
var port = process.env.PORT || 5656;
//db config
var mongoDB = 'mongodb://XXX:XXX!#XXX.mlab.com:XXX/XXX';
mongoose.connect(mongoDB);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
//body parsing
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// allow cross-browser
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
next();
});
// handling static assets
app.use(express.static(path.join(__dirname, 'build')));
// api handling
var TrustsSchema = new Schema({
id: String,
name: String
});
var Trust = mongoose.model('Trust', TrustsSchema);
const trustRouter = express.Router();
trustRouter
.get('/', (req,res) => {
Trust.find(function(err, trusts) {
if (err) {
res.send(err);
}
res.json(trusts)
});
});
app.use('/api/trusts', trustRouter);
//now we can set the route path & initialize the API
router.get('/', function(req, res) {
res.json({ message: 'API Initialized!'});
});
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(port, function() {
console.log(`api running on port ${port}`);
});
Below is the AJAX call I'm trying to make that doesn't work because the relative path is appended to the app's port (i.e., http://localhost:3000/) and not the API's port (i.e., http://localhost:3100/):
axios.get("/api/trusts")
.then(res => {
this.setState({trusts: res.data});
})
.catch(console.error);
To tell the development server to proxy any unknown requests to your API server in development, add a proxy field to your package.json, for example:
"proxy": "http://localhost:4000",
This way, when you fetch('/api/todos') in development, the development server will recognize that it’s not a static asset, and will proxy your request to http://localhost:4000/api/todos as a fallback. The development server will only attempt to send requests without text/html in its Accept header to the proxy.
"Keep in mind that proxy only has effect in development (with npm start), and it is up to you to ensure that URLs like /api/todos point to the right thing in production."
Note: this feature is available with react-scripts#0.2.3 and higher.
More details here: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development
So I have a pretty simple question, at the moment my server file and HTML documents all live in the same directory. However, I've realised this has lead to quite an annoying problem. If I user were to type:
http://localhost:3000/HTML/homepage.html
The server serves them the HTML document, where usually they'd have to go through sign in, and have their session ID verified before they could access the homepage.
Is there any way to deny access to files held in the server directory?
Example of how my code currently runs:
var http = require('http'),
fs = require('fs');
var path = require("path");
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser')
var session = require('express-session')
var sqlite3 = require('sqlite3').verbose();
var express = require('express');
var app = express();
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
app.use(bodyParser());
app.use(express.static(__dirname));
app.get('/signin', function (req, res) {
res.sendFile(path.join(__dirname + '/HTML/signin'));
});
app.post('/signin', function (req, res) {
var email = req.body.email;
var password = req.body.password;
if (email!="" || password != ""){
req.session.sessID = email //using email for example purposes
res.setHeader('Content-Type', 'application/json' );
res.send(JSON.stringify({
success: true //the client then catches the JSON, and will redirect to http://localhost:3000/homepage
}));
}
}
app.get('/homepage', function(req, res){
if (req.session.sessID == undefined){
res.send("You must login first!")
}else{
res.sendFile(path.join(__dirname + '/HTML/homepage.html'));
}
}
The source of your problem is this:
app.use(express.static(__dirname));
This tells express to serve ANY file it can find on your hard drive from the app directory on down. This is not advisable. This will even serve up your private server source code files if the right path is entered into the browser.
You should distinguish between your static files and your dynamically handled routes and you should make sure there is no possibility of conflict between them.
A common design is to designate a separate directory on your hard drive for static HTML files (not your app directory) and then set up express static routing to there. And, make sure that none of your dynamic routes will ever be satisfied with the static routing.
For example, if your static HTML files are in a sub-directory HTML which is below your __dirname directory, then you can do this:
app.use(express.static(path.join(__dirname, "HTML")));
And, then make sure none of your dynamic HTML files such as homepage.html are in that directory (put them somewhere else that express.static() will not ever see).
If you don't actually want the user to be able to see anything except your custom routes, then get rid of the app.use(express.static(__dirname)); line entirely and just create custom routes for each page you are serving.
I am playing around and trying to learn the MEAN stack to create a single page application. I was able to get my back-end routes to work correctly. I've tested it using Postman and get the results I expect, however I cannot get my front-end to talk to the back-end correctly.
I reduced my front-end to very basic html and javascript, but still get a syntax error "Unexpected token <". When I inspect my coreTest.js file in the browser, I see that it's just a copy of my html file, rather than javascript code.
When I run index.html by itself (without server.js) coreTest.js runs just fine. I'm not sure why, when running my server.js file, my coreTest.js file doesn't work properly.
server.js
// Setup
var express = require('express');
var app = express(); // create app w/ express
var mongoose = require('mongoose'); // used for MongoDB connection
var morgan = require('morgan'); // log requests to the console
var bodyParser = require('body-parser'); // pull information from HTML POST
var methodOverride = require('method-override'); // simulate DELETE and PUT requests
// Configure
mongoose.connect('localhost:27017/test'); // connect to localhost db "test"
// varify connection
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error: '));
app.use(express.static(__dirname + '/public')); // set static files location
app.use(morgan('dev')); // log every request to console
app.use(bodyParser.urlencoded({'extended':'true'})); // parse application/x-www-form-url
app.use(bodyParser.json());
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse vnd.api+json as json
app.use(methodOverride());
// define db model
var Todo = mongoose.model('Todo', {
text: String
});
var router = express.Router();
router.route("/todos")
.get(function(req, res) {
Todo.find(function(err, todos) {
if (err)
res.send(err);
res.json(todos);
});
})
.post(function(req, res) {
var todo = new Todo();
todo.text = req.body.text;
todo.save(function(err) {
if (err)
res.send(err);
res.json({mes: "Todo item created"});
})
});
router.route("/todos/:todo_id")
.delete(function(req, res) {
Todo.remove( {
_id: req.params.todo_id
}, function(err, todo) {
if (err)
res.send(err);
res.json({mes: "Successfully deleted"});
});
});
// route to application
router.route("*")
.get(function(req, res) {
res.sendfile('./public/index.html');
});
// Register our routes
app.use('/api', router);
// Listen, start node app
app.listen(8080);
console.log("app listening on port 8080");
coreTest.js
alert("ping");
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Starter MEAN Single Page Application</title>
<script type="text/javascript" src="coreTest.js"></script>
</head>
<body>
I did it!! Wooo!!
</body>
</html>
I suspect the problem is between
app.use(express.static(__dirname + '/public'));
and
// route to application
router.route("*")
.get(function(req, res) {
res.sendfile('./public/index.html');
});
When you're running the server, your client-side code is trying to load "coreTest.js", which is matched by the last rule ; and so the server returns the content of index.html.
I'm not sure what you mean about "runing index.html by itself" ; if you mean "visiting file://..../public/index.html", it works because the browser will try to load coreTest.js from your file system.
Try using the "static" plugin only to serve files from "public", and use this prefix in the client side code :
app.use("/public", express.static(...))
and in the client
<script type=".." src="public/coreTest.js"></script>
Getting the path rights will depend on what's on your disk.
This might help, too : static files with express.js
I was able to solve my issue using what phtrivier recommended.
Instead of serving my files from "public" I chose to serve them from "api" because I already set my router to take requests from that path as well.
app.use("/api", express.static(__dirname + '/public'));
I didn't need to change my reference to coreTest.js in the html because my files were organized with coreTest already in the root directory like this:
public
-index.html
-coreTest.js