I am currently working on my first little Node/Express project, and I am having difficulties with the express.static function. Unfortunately, I couldn't find any solution for my issue amongst all the other threads about this topic on here. I have also gone through all the docs I could find. It seems that I am still not getting any further.
Here's my set up:
I have added a "/public" folder to my project dir. In "public" I have "documentation.html". The structure looks like this:
-project_folder
--public
----documentation
It is the "documentation.html" I would like to serve for the endpoint "/documentation".
By now I have tried the following:
The example from the Express docs:
app.use(express.static('public'));
With the endpoint "/documentation" I get a status: 301, moved permanently, type: document/redirect, and initiator: other for "documentation, and a status: 404, not found and type: document and initiator: :8080/documentation, redirect for "documentation/".
A suggestion to add a "/" before the "public":
app.use(express.static('/public'));
With the endpoint "/documentation" I get a status: 301, moved permanently, type: document/redirect, and initiator: other for "documentation, and a status: 404, not found and type: document and initiator: :8080/documentation, redirect for "documentation/".
The recommended way from the Express docs (I did require path for this one):
app.use(express.static(path.join(__dirname, 'public')));
With the endpoint "/documentation" I get a status: 301, moved permanently, type: document/redirect, and initiator: other for "documentation, and a status: 404, not found and type: document and initiator: :8080/documentation, redirect for "documentation/".
The endpoint "/movies" does return a JSON object, and the endpoint "/" does return "Some text".
Another thing to mention: I had an index.html within the "public" folder before. With
app.use(express.static('public'));
and the endpoint "/documentation" I received the "index.html" file.
Here is the code:
//Requiring Express
const express = require('express');
//Setting Express to var "app"
const app = express();
let topMovies = [{ title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: 'Die Hard', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }];
//GET requests
app.get('/movies', (req, res) => {
res.json(topMovies);
});
app.get('/', (req, res) => {
res.send('Some text')
});
//Serving static files from "public" folder using express "static" function
app.use(express.static('public'));
//Server PORT
app.listen(8080, () => {
console.log('Server running...');
});
As mentioned, this is my first time working with Node/Express. I am quite confident that I checked all the docs and threads with similar issues before creating this post. However, I apologize in advance if I overlooked something at this point.
Edit/Addition:
I have been able to run another test, which however, confuses my beginner brain even more. Here is the code:
const express = require('express');
const app = express();
const PORT = 3000;
app.use(express.static('public'));
let topMovies = [{ name: 'test' }, { name: 'testone' }, { name: 'testtwo' }];
app.get('/', (req, res) => {
res.send('Hello World');
});
app.get('/movies', (req, res) => {
res.json(topMovies);
});
app.listen(PORT, () => console.log(`Server listening on port: ${PORT}`));
I used this folder structure:
project_root index.js public index.html
With this code and folder structure, I can get the static files served on "localhost:3000".
What becomes clear to me is:
- The file name of "index.html" in /public works, while "documentation.html" doesn't.
- "/movies" still returns the JSON object
- The folder structure is the same in both examples.
- I simply changed the PORT # and how the PORT was "referenced" in app.listen
- I just don't know what the f I'm doing.
CodePudding user response:
The key issue is about conflict in the API call of GET /
. There are two binding points, first, return 'Some Text', and second, return static files.
To solve you should separate these endpoints either by removing app.get('/',...
or by adding another prefix for static files: app.use('/ui', express.static('public'));
To serve your documents, just rename document.html
to index.html
and bind the directory: app.use('/document', express.static('document'));
Best Practice
It is highly recommended to add a default prefix for all API calls.
app.get('/api/movies', (req, res) => {
res.json(topMovies);
});
app.get('/api/', (req, res) => {
res.send('Some text');
});
app.use('/document', express.static(path.join(__dirname, 'document')));
app.use('/', express.static(path.join(__dirname, 'public')));
project-root
public
index.html
document
index.html
index.js
package.json
CodePudding user response:
Ok, after a lot of trial an error I figured it out. Here's what worked for me:
const express = require('express');
const app = express();
const PORT = 8080;
app.use(express.static(__dirname '/public'));
let topMovies = [{ title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: 'Die Hard', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }, { title: '', director: '' }];
app.get('/movies', (req, res) => {
res.json(topMovies);
});
app.get('/', (req, res) => {
res.send('Netflix sucks');
});
app.listen(PORT, () => console.log('Server is running....'));
Folder structure:
-project_root
--index.js
--public
----documentation.html
Now, I get the "documentation.html" for the endpoint "/documentation.html" and also the other endpoints are returned correct.
Conclusion: I had the right folder structure, but I needed to add the "__dirname" to the express.static root and also make the "public" folder a path by adding "/".