26

I have installed http-server globally.

I launch it from myDir on localhost port 8080. In myDir I have index.html.

If I request (from the browser) http://localhost:8080/ I get index.html, which is OK.

If I request though http://localhost:8080/anything I do not get any response from the server.

What I would like, on the contrary, is that my server always responds with index.html to any http request reaching localhost on port 8080.

Is this possible.

Thanks in advance

Picci
  • 16,775
  • 13
  • 70
  • 113
  • 1
    `-P or --proxy Proxies all requests which can't be resolved locally to the given url. e.g.: -P http://someurl.com` => Could you try `http-server -P http://localhost:8080/`? – DrakaSAN Sep 28 '16 at 10:20
  • So did the solution in [my answer](http://stackoverflow.com/questions/39744309/node-http-server-to-respond-with-index-html-to-any-request/39744827#39744827) work for you? – rsp Sep 29 '16 at 08:29
  • having a similar issue but I want my dist will serve as http://127.0.0.1:8080/myprofile how this will possible when I refresh this will be lost. – Amit kumar Feb 03 '21 at 08:06

8 Answers8

25

Use as specified in the documentation.

http-server --port 8080 -P http://localhost:8080?

Note the ? at the end of the proxy URL.

Farkhod Daniyarov
  • 748
  • 12
  • 14
19

To achieve what you are asking for, I recommend you live-server instead of http-server.

live-server --port=8080 --entry-file=./index.html

live-server is also providing a hot-reload but it was not one of your request

Edit: live-server is not designed to be used in production. No gzip compression for example

Edit 2: The maintainer of http-server clearly said in this comment that never, http-server will consider the SPA use-cases

Edit 3: serve seems to be a good option too

Gabriel
  • 3,633
  • 1
  • 23
  • 13
8

Simple and straight-forward example using Express 4.x:

var express = require('express');
var app = express();

var path = __dirname + '/public';
var port = 8080;

app.use(express.static(path));
app.get('*', function(req, res) {
    res.sendFile(path + '/index.html');
});
app.listen(port);

This implementation will always respond with index.html if the requested file is not found, and it's almost as simple as using http-server, which lacks this option.

Jaime Gómez
  • 6,961
  • 3
  • 40
  • 41
6

Yes there is, with the -P/--proxy option:

http-server -P http://localhost:8080/

Note that any error, 404 included, will redirect to your index, not just missing path.

DrakaSAN
  • 7,673
  • 7
  • 52
  • 94
  • Unfortunately when I do what you suggests I get (on the browser) the following messages `This site can’t be reached` and 'localhost refused to connect.' and 'ERR_CONNECTION_REFUSED'. On the server I see a stream of requests which end with the server itself throwing an error `Error: socket hang up` – Picci Sep 28 '16 at 10:26
  • 4
    I don't know `http-server`, but since any error get redirected to index, I assume you got in a loop until the client gave up. I personally would have do as @rsp did, write your own little server with express, it's easy and fast too. – DrakaSAN Sep 28 '16 at 10:33
  • 1
    Yes. Accessing `http://localhost:8080/anything` would redirect to `http://localhost:8080/anything` and so on. The `--proxy` option takes the part after host name and port and appends it to the given proxy host/port. – Simon A. Eugster Sep 28 '16 at 10:40
  • 1
    This is what finally worked for me for serving a local production build of an angular app: http-server -p 8080 --proxy "http://localhost:8080?" ./dist – egalot Aug 20 '20 at 04:48
3

Sometimes for specific cases like this one, it's easy enough to write your own server:

'use strict';
var host = '127.0.0.1', port = 3333;
var path = require('path');
var app = require('express')();
app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
app.listen(port, () => console.log(`Listening on http://${host}:${port}/`));

But keep in mind that if every path returns index.html then in the index.html you cannot reference anything like images, style sheets or client side JavaScript files. Not only with the code shown above but with any solution that sends the same response (index.html) to every request.

You may need to make some exceptions and it's not hard with Express:

'use strict';
var host = '127.0.0.1', port = 3333;
var path = require('path');
var app = require('express')();
app.get('/x.png', (req, res) => res.sendFile(path.join(__dirname, 'x.png')));
app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
app.listen(port, () => console.log(`Listening on http://${host}:${port}/`));

Just keep in mind that the exceptions have to go to the top because the first matching route will be used for a given request.

Of course you need to save this code e.g. to app.js, install Express:

npm install express

and start it with:

node app.js

It's more complicated than using a ready solution (though, as you can see, not that complicated either) but you have much more flexibility in how exactly you want it to behave. It's also easy to add logging etc.

rsp
  • 107,747
  • 29
  • 201
  • 177
  • Please explain why that is so ? "But keep in mind that if every path returns index.html then in the index.html you cannot reference anything like images, style sheets or client side JavaScript files. Not only with the code shown above but with any solution that sends the same response (index.html) to every request." – joedotnot Apr 25 '18 at 02:21
2

I've faced this issue while trying to a svelte app build for production. Instead of using http-server I'm using sirv:

first install it npm i --save-dev sirv-cli

then add this script on package.json: "start": "sirv public --single",

Happy coding!

Guille Acosta
  • 2,051
  • 23
  • 35
1

If you create "Vite" project, it can handle this. vite preview command serves dist folder with single file (index.html) mode.

kodmanyagha
  • 932
  • 12
  • 20
-1

A bit after the war, but anyway. for angular app, I suggest to add to your package.json:

"serve-prod": "cp dist/app-name/index.html dist/app-name/404.html && http-server dist/app-name"

Then call

npm run serve-prod
movaction.com
  • 537
  • 6
  • 6