J0rdAn
J0rdAn

Reputation: 151

Serve static files with ExpressJS Typescript NodeJS

I'm trying to serve static file uploaded using ExpressJS and NodeJS with Typescript but getting 404 error.

the file I want to read is ./src/data/uploads/test.txt and I'm trying to access it from web browser directly.

Note: When I do it in Javascript it worked but not in Typscript.

index.ts file (app entry point)

import express from 'express';
import bodyParser from 'body-parser';
import helmet from 'helmet';
import {cdg, config} from './utils';
import {Mongoose} from './db/monogdb';
import { setRoutes } from './routes/route.decorators';
import cors from 'cors';
import './routes';

const app = express();

app.use(helmet());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/ftp', express.static('data/uploads'));

setRoutes(app);

app.listen(config.server.port, () => {
    cdg.konsole("Server connected! :: " + config.server.port + "!");
});

Is there a specific way to serve static file with Typescript ?

Upvotes: 1

Views: 8911

Answers (2)

Charlen Rodrigues
Charlen Rodrigues

Reputation: 1

In my case I solved my problem like this: in the parameter relative to the directory path I used path.resolve and in its first parameter I used __dirname as the first parameter and the relative path of the target directory as the second one.

app.get('/', express.static(path.resolve(__dirname, '../static/'))); – 

Upvotes: 0

jfriend00
jfriend00

Reputation: 707318

Here's how express.static() works. You are apparently missing one of these steps, but your question is short of the details to identify exactly which step is not correct.

First, you define an express.static() middleware that contains some parameters. In your case, you've defined this:

app.use('/ftp', express.static('data/uploads'));

There are four elements that determine how this works:

  1. The /ftp that must be at the start of any URL for this middleware to match.
  2. The incoming URL request and how it was formed by the browser based on how you specified it in your HTML.
  3. The current working directory that is combined with data/uploads to make a full path reference or you could build your own absolute path and not depend upon the cwd.
  4. The files in cwd + /data/uploads that express.static() will attempt to match to the path of the incoming URL.

Let's look into these further:

Your middleware will first only look at URLs that start with /ftp. And, then for any URL it sees that does start with /ftp, it should take the rest of the URL and append it to data/uploads and see it finds a matching file in your local file system. It will use the current working directory in your server process at the time of the request to try to resolve the relative path data/uploads. That current working directory (if you haven't programmatically changed it) will depend upon how your app was started.

So, if you started your app with node index.js, then the current working directory will be the directory where index.js is located and express static will be looking in the data/uploads sub-directory below where 'index.js` is.

Then, we need to look at how the HTML tag that specifies this static resource is specified.

Let's say this is an <img> tag for example. If you specify something like this:

 <img src="/ftp/hello.jpg">

Then, the browser will create a request to your server for /ftp/hello.jpg. Since that does start with /ftp, your express.static() middleware will take the rest of the path /hello.jpg and append that to data/uploads and build a path that looks like this:

path.join(process.cwd(), 'data/uploads', '/hello.jpg')

And, it will look for that resulting file in your local file system. If it finds that file, then it will serve that file and return it as the response. If it doesn't find that exact file, then it will call next() and continue routing to your other route handlers.

There are a number of common mistakes (things that can go wrong):

  1. You don't specify the correct URL in your web page that lines up with your express.static() middleware line (including the /ftp prefix that your middleware specifies).

  2. Your middleware isn't quite pointing at the right directory in your file system so it never finds anything.

  3. You are using relative URLs in your web page which the browser combines with the path of your web page causing it to request something different than you want. Static resource URLs in your web page should nearly always start with / so they are not dependent upon the path of the parent page.

  4. The files aren't quite properly located in the file hierarchy you are pointing to with your middleware (often off by one level).


One other thing I will mention. Since you're using TypeScript, that means you have to compile/build your script into a regular .js script before it can be run. This will typically be in a different directory location.

This different directory location creates opportunities for you to not be referencing the proper directory where your static resources are, since they are probably located relative to your TypeScript files, not the built Javascript files that you're running (that depends upon your build script).

Again, if you show us where everything is in your file system (TypeScript files, built JS files, static resources) and what the HTML tag that references the static resource looks like, we can help you debug that more specifically.

Upvotes: 7

Related Questions