I have made a full-stack app that has a frontend made from React and a server.js written in nodejs(Express) and I am using Postgres as my database. I have done this before once and host my site on Heroku.
The difference is that on Heroku I had my frontend and backend on separate Urls so that in my react app I could do
fetch('http://localhost:3005/url',{
method: 'get',
headers: {'Content-Type': 'application/json'},
})
.then(response => response.json())
The above code is while I am running my react and node on my laptop through npm start.
My server.js would be
app.get('/url', (req, res) => {
db.insert({
page_url: req.body.urlInfo,
user_visit_id: req.body.visitID,
})
.into('pageurl')
.then((id) => {
res.json(id);
}).catch(err => res.status(400).json('unable to write'))
})
In Heroku, I would just change the frontend React line to :
fetch('http://**Ther URL where my server.js is**/url',{
method: 'get',
headers: {'Content-Type': 'application/json'},
})
.then(response => response.json())
And this would run absolutely fine.
The issue comes now that I have to deploy the app to the school server. The server has nginx running and I have been given a domain for this project.
The front end is hosted on the nginx and whenever I vist my domain the frontend showsup but how do I connect it to my server.js endpoints given that I have to have the server.js in the same server as the react app which is hosted by the nginx. I am completely new to nginx and don't have a concrete idea about solving the problem. I have my node server.js running on the server using pm2.
But this is right now of little use, as my frontend fetch does the localhost:3005/url which looks for the url point in port 3005 of the device that visits the domain rather than the actual server that is hosting the frontend and the node server.js.
I also tried replacing the localhost:3005/url from the server.js to using the server's ip but that address only seems to be visitable if I am on the school's wifi connection.
If I change enter that ip address from my phone with a data connection, the address can't be reached. So, I assumed that "ipaddress:3005/url" is also not the correct way to do it. I am lost at this point and any sugesstions would be a great help!!! Ideally I would like to run host my frontend on nginx on the server and have pm2 running the server.js.
I just need a way to connect the endpoints of the frontend and the backend. I need the
URL where my server.js is part in
fetch('http://Ther URL where my server.js is/url',{
method: 'get',
headers: {'Content-Type': 'application/json'},
})
.then(response => response.json())
My nginx config file right now looks like this:
server {
listen 80;
listen [::]:80;
root /var/www/example.com/html/build;
index index.html index.php index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php-fpm (or other unix sockets):
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
# With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
}
location / {
try_files $uri /index.html;
#try_files $uri $uri/ =404;
}
}
This nginx configuration only serves the frontend at the moment. Also, the real domain.com is replaced by example.com in the above code.
Thanks!
What i would do is setup a virtual host in nginx on a different port, which proxies all requests to your nodejs app, like:
server {
listen 8080;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3005;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
In this example, the following assumptions have been made:
example.com is the domain that the school assigned to your project
port 8080 is the port that you will open and set in your front-pages: fetch('http://example.com:8080', {})
your nodejs app runs on port 3005
Edit 1: Here is a mini code I made that reproduces the error. Please follow README.md to install.
Edit 2: Finally, I found one solution. Besides $locationProvider.html5Mode(true); ($locationProvider.hashPrefix('') is NOT necessary for me) and <base href="/" />, I need to add the follows in routes/index.js, rather than app.js. Then, we do NOT need to add anything more to app.js or nginx or apache like this thread mentions.
var express = require('express');
var router = express.Router();
var path = require('path');
... ...
router.get('*', function(req, res) {
res.sendfile('./views/index.html'); // load our public/index.html sendFile
// res.sendFile('index.html', { root: path.join(__dirname, 'views') }); // does not work
});
One problem is, in the server console, it gives express deprecated res.sendfile: Use res.sendFile instead routes/index.js:461:9. But res.sendFile('index.html', { root: path.join(__dirname, 'views') }); can not help, it returns 404 error.
My express version is ~4.14.0... does anyone know how to fix that?
OP:
I develop in Mac with Apache a MEAN-stack application that can be requested by
https://localhost:3000/#/home. In production with an NGINX server, the application can be requested by
https://www.myapp.io/#/home. The fragment-identifier # is needed in all cases because of angular ui-router.
So I wanted to make pretty url without # (eg, https://www.myapp.io/home, https://localhost:3000/home) work. I have done the following:
added $locationProvider.html5Mode(true); $locationProvider.hashPrefix('') in app.config(['$stateProvider'....
added <base href="/" /> in index.html
As a result, https://localhost:3000/#/home changes automatically to https://localhost:3000/home in the browser bar, similarly for https://www.myapp.io/#/home.
However, directly entering https://localhost:3000/home or https://www.myapp.io/home in the browser will raise an error (I don't know how to turn previous <h1><%= message %></h1><h2><%= error.status %></h2><pre><%= error.stack %></pre> in error.ejs to error.html, so I don't have more details).
So now, the goal is to make https://localhost:3000/home and https://www.myapp.io/home work.
By following this thread, I added the follows to app.js:
app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));
app.all('/*', function(req, res, next) {
res.sendFile('index.html', { root: __dirname });
});
And in Apache of Mac, here is my httpd-vhosts.conf, after restarting apache,
https://localhost:3000/home still returns an error.
<VirtualHost *:443>
ServerName localhost
DocumentRoot "/Users/SoftTimur"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /etc/apache2/ssl/localhost.crt
SSLCertificateKeyFile /etc/apache2/ssl/localhost.key
<Directory "/Users/SoftTimur">
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>
In production, here is the NGINX server block. After restarting NGINX, https://www.myapp.io/home still returns an error.
server {
listen 443 ssl;
server_name myapp.io www.myapp.io;
ssl_certificate /etc/letsencrypt/live/myapp.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.io/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:EC$
ssl_session_timeout 1d;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
index index.html;
root /opt/myapp;
location / {
try_files $uri $uri/ /index.html;
}
location ~ /.well-known {
allow all;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Accept-Encoding "";
proxy_set_header Proxy "";
proxy_pass https://127.0.0.1:3000;
# These three lines added as per https://github.com/socketio/socket.io/issues/1942 to remove sock$
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Could anyone help?
This might useful stuff,
AngularJS routing without the hash '#'
Also, use this line in your express server file.
app.use(express.static(path.join(__dirname, 'client folder')));
this will directly finds your index.html file in that views folder and loads it
try this in your express server
var express = require('express');
var app = express();
app.get('*', function (req, res) { res.sendFile(__dirname + '/views/index.html'); });
and in your angular app:
$locationProvider.hashPrefix('!').html5Mode({
enabled: true
});
$urlRouterProvider.otherwise('/');
and you still need the <base href="/"> in your index.html
let me know if this works for you
EDIT:
I just found your app in https://github.com/chengtie/mini-mean,
looks like your app.use order is wrong. Please copy paste this in your express server and check if it's okay now. pastebin
You don't need Apache or Nginx to run NodeJs in development, just node server.js is enough
Express gave you that error because you are using a deprecated API res.sendfile please use res.sendFile (capital F)
Some info for doing SPA:
When you have the '#' in your URL, the browser interpret it as a local reference and thus, won't send new request to the server
By enabling $locationProvider.html5Mode(true) you are now using html5 push state to navigate around your application history and (if I'm not mistaken you are happening to be using) angular effectively remove the '#' in url
Without the '#' (hash-bang) browser will interpret it as a new request and send it to server, so you have to map all requests from server to your SPA entry file
For exact steps of replicating this behavior, consult this article: https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag (the base href in your entry file is important)
If it's just about the #. You can remove it in Angular itself.
Just inject locationProvider at your app entry and set htmlMode to true. In your index.html set the baseUrl.
$locationProvider.html5Mode(true)
And in you index.html add:
<base href="/" />
That will generate your urls without the #. Does that help?
I am using as an environment, a Cloud9.io ubuntu VM Online IDE and I have reduced by troubleshooting this error to just running the app with Webpack dev server.
I launch it with:
webpack-dev-server -d --watch --history-api-fallback --host $IP --port $PORT
$IP is a variable that has the host address
$PORT has the port number.
I am instructed to use these vars when deploying an app in Cloud 9, as they have the default IP and PORT info.
The server boots up and compiles the code, no problem, it is not showing me the index file though. Only a blank screen with "Invalid Host header" as text.
This is the Request:
GET / HTTP/1.1
Host: store-client-nestroia1.c9users.io
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
This is my package.json:
{
"name": "workspace",
"version": "0.0.0",
"scripts": {
"dev": "webpack -d --watch",
"server": "webpack-dev-server -d --watch --history-api-fallback --host $IP --port $PORT",
"build": "webpack --config webpack.config.js"
},
"author": "Artur Vieira",
"license": "ISC",
"dependencies": {
"babel-core": "^6.18.2",
"babel-loader": "^6.2.8",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.24.1",
"file-loader": "^0.11.1",
"node-fetch": "^1.6.3",
"react": "^15.5.4",
"react-bootstrap": "^0.30.9",
"react-dom": "^15.5.4",
"react-router": "^4.1.1",
"react-router-dom": "^4.1.1",
"url-loader": "^0.5.8",
"webpack": "^2.4.1",
"webpack-dev-server": "^2.4.4",
"whatwg-fetch": "^2.0.3"
}
}
This is the webpack.config.js:
const path = require('path');
module.exports = {
entry: ['whatwg-fetch', "./app/_app.jsx"], // string | object | array
// Here the application starts executing
// and webpack starts bundling
output: {
// options related to how webpack emits results
path: path.resolve(__dirname, "./public"), // string
// the target directory for all output files
// must be an absolute path (use the Node.js path module)
filename: "bundle.js", // string
// the filename template for entry chunks
publicPath: "/public/", // string
// the url to the output directory resolved relative to the HTML page
},
module: {
// configuration regarding modules
rules: [
// rules for modules (configure loaders, parser options, etc.)
{
test: /\.jsx?$/,
include: [
path.resolve(__dirname, "./app")
],
exclude: [
path.resolve(__dirname, "./node_modules")
],
loader: "babel-loader?presets[]=react,presets[]=es2015,presets[]=stage-0",
// the loader which should be applied, it'll be resolved relative to the context
// -loader suffix is no longer optional in webpack2 for clarity reasons
// see webpack 1 upgrade guide
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(png|jpg|jpeg|gif|svg|eot|ttf|woff|woff2)$/,
loader: 'url-loader',
options: {
limit: 10000
}
}
]
},
devServer: {
compress: true
}
}
Webpack dev server is returning this because of my host setup. In webpack-dev-server/lib/Server.js line 60. From https://github.com/webpack/webpack-dev-server
My question is how do I setup to correctly pass this check. Any help would be greatly appreciated.
The problem occurs because webpack-dev-server 2.4.4 adds a host check. You can disable it by adding this to your webpack config:
devServer: {
compress: true,
disableHostCheck: true, // That solved it
}
Please note, this fix is insecure.
Please see this answer for a secure solution.
The option was refactored in version 4.0.0. The allowedHosts option should now be used:
devServer: {
allowedHosts: "all"
}
I found out, that I need to set the public property of devServer, to my request's host value. Being that it will be displayed at that external address.
So I needed this in my webpack.config.js
devServer: {
compress: true,
public: 'store-client-nestroia1.c9users.io' // That solved it
}
Another solution is using it on the CLI:
webpack-dev-server --public $C9_HOSTNAME <-- var for Cloud9 external IP
This is what worked for me:
Add allowedHosts under devServer in your webpack.config.js:
devServer: {
compress: true,
inline: true,
port: '8080',
allowedHosts: [
'.amazonaws.com'
]
},
I did not need to use the --host or --public params.
Rather than editing the webpack config file, the easier way to disable the host check is by adding a .env file to your root folder and putting this:
DANGEROUSLY_DISABLE_HOST_CHECK=true
As the variable name implies, disabling it is insecure and is only advisable to use only in dev environment.
Add this config to your webpack config file when using webpack-dev-server (you can still specify the host as 0.0.0.0).
devServer: {
disableHostCheck: true,
host: '0.0.0.0',
port: 3000
}
The more secure option would be to add allowedHosts to your Webpack config like this:
module.exports = {
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
}
};
The array contains all allowed host, you can also specify subdomians. check out more here
If you have not ejected from CRA yet, you can't easily modify your webpack config. The config file is hidden in node_modules/react_scripts/config/webpackDevServer.config.js. You are discouraged to change that config.
Instead, you can just set the environment variable DANGEROUSLY_DISABLE_HOST_CHECK to true to disable the host check:
DANGEROUSLY_DISABLE_HOST_CHECK=true yarn start
# or the equivalent npm command
on package.json, on "scripts", add the param --disableHostCheck=true
Like:
"scripts": {
"start": "ng serve --host=0.0.0.0 --configuration=dev --disableHostCheck=true"
}
If you are running webpack-dev-server in a container and are sending requests to it via its container name, you will get this error. To allow requests from other containers on the same network, simply provide the container name (or whatever name is used to resolve the container) using the --public option. This is better than disabling the security check entirely.
In my case, I was running webpack-dev-server in a container named assets with docker-compose. I changed the start command to this:
webpack-dev-server --mode development --host 0.0.0.0 --public assets
And the other container was now able to make requests via http://assets:5000.
If you are using create-react-app on C9 just run this command to start
npm run start --public $C9_HOSTNAME
And access the app from whatever your hostname is (eg type $C_HOSTNAME in the terminal to get the hostname)
While using the default behavior (no config file) with webpack 5 related to this post: [https://stackoverflow.com/a/65268634/2544762`]
"scripts": {
"dev": "webpack serve --mode development --env development --hot --port 3000"
...
...
},
"devDependencies": {
...
"webpack": "^5.10.1",
"webpack-cli": "^4.2.0"
},
With webpack 5 help webpack serve --help:
Usage: webpack serve|server|s [entries...] [options]
Run the webpack dev server.
Options:
-c, --config <value...> Provide path to a webpack configuration file e.g.
./webpack.config.js.
--config-name <value...> Name of the configuration to use.
-m, --merge Merge two or more configurations using
'webpack-merge'.
--env <value...> Environment passed to the configuration when it
is a function.
--node-env <value> Sets process.env.NODE_ENV to the specified value.
--progress [value] Print compilation progress during build.
-j, --json [value] Prints result as JSON or store it in a file.
-d, --devtool <value> Determine source maps to use.
--no-devtool Do not generate source maps.
--entry <value...> The entry point(s) of your application e.g.
./src/main.js.
--mode <value> Defines the mode to pass to webpack.
--name <value> Name of the configuration. Used when loading
multiple configurations.
-o, --output-path <value> Output location of the file generated by webpack
e.g. ./dist/.
--stats [value] It instructs webpack on how to treat the stats
e.g. verbose.
--no-stats Disable stats output.
-t, --target <value...> Sets the build target e.g. node.
--no-target Negative 'target' option.
--watch-options-stdin Stop watching when stdin stream has ended.
--no-watch-options-stdin Do not stop watching when stdin stream has ended.
--bonjour Broadcasts the server via ZeroConf networking on
start
--lazy Lazy
--liveReload Enables/Disables live reloading on changing files
--serveIndex Enables/Disables serveIndex middleware
--inline Inline mode (set to false to disable including
client scripts like livereload)
--profile Print compilation profile data for progress steps
--progress Print compilation progress in percentage
--hot-only Do not refresh page if HMR fails
--stdin close when stdin ends
--open [value] Open the default browser, or optionally specify a
browser name
--useLocalIp Open default browser with local IP
--open-page <value> Open default browser with the specified page
--client-log-level <value> Log level in the browser (trace, debug, info,
warn, error or silent)
--https HTTPS
--http2 HTTP/2, must be used with HTTPS
--key <value> Path to a SSL key.
--cert <value> Path to a SSL certificate.
--cacert <value> Path to a SSL CA certificate.
--pfx <value> Path to a SSL pfx file.
--pfx-passphrase <value> Passphrase for pfx file.
--content-base <value> A directory or URL to serve HTML content from.
--watch-content-base Enable live-reloading of the content-base.
--history-api-fallback Fallback to /index.html for Single Page
Applications.
--compress Enable gzip compression
--port <value> The port
--disable-host-check Will not check the host
--socket <value> Socket to listen
--public <value> The public hostname/ip address of the server
--host <value> The hostname/ip address the server will bind to
--allowed-hosts <value...> A list of hosts that are allowed to access the
dev server, separated by spaces
Global options:
--color Enable colors on console.
--no-color Disable colors on console.
-v, --version Output the version number of 'webpack',
'webpack-cli' and 'webpack-dev-server' and
commands.
-h, --help [verbose] Display help for commands and options.
To see list of all supported commands and options run 'webpack --help=verbose'.
Webpack documentation: https://webpack.js.org/.
CLI documentation: https://webpack.js.org/api/cli/.
Made with ♥ by the webpack team.
Done in 0.44s.
Solution
So, just add --disable-host-check with the webpack serve command do the trick.
Hello React Developers,
Instead of doing this
disableHostCheck: true, in webpackDevServer.config.js. You can easily solve 'invalid host headers' error by adding a .env file to you project, add the variables HOST=0.0.0.0 and DANGEROUSLY_DISABLE_HOST_CHECK=true in .env file. If you want to make changes in webpackDevServer.config.js, you need to extract the react-scripts by using 'npm run eject' which is not recommended to do it. So the better solution is adding above mentioned variables in .env file of your project.
Happy Coding :)
I just experienced this issue while using the Windows Subsystem for Linux (WSL2), so I will also share this solution.
My objective was to render the output from webpack both at wsl:3000 and localhost:3000, thereby creating an alternate local endpoint.
As you might expect, this initially caused the "Invalid Host header" error to arise. Nothing seemed to help until I added the devServer config option shown below.
module.exports = {
//...
devServer: {
proxy: [
{
context: ['http://wsl:3000'],
target: 'http://localhost:3000',
},
],
},
}
This fixed the "bug" without introducing any security risks.
Reference: webpack DevServer docs
I am using nginx running inside of a docker container to route traffic based on the url.
Adding the following two lines of code in the nginx config file fixed the error Invalid Host header for me. See below for the config file(default.conf).
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
First the following is my simple two liner Dockerfile to create the nginx container and then configure it with routing.
FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf
So when the image is built, the default.conf file is copied to the configuration directory inside of the nginx container.
Next the default.conf file looks as follows.
upstream ui {
# The ui service below is a ui app running inside of a container. Inside of the container, the ui app is listening on port 3000.
server ui:3000;
}
upstream node-app {
# The node-app service below is a server app running inside of a container. Inside of the container, the server is listening on port 8080.
server node-app:8080;
}
server {
listen 80;
location / {
# The root path, with is '/' will routed to ui.
proxy_pass http://ui;
################## HERE IS THE FIX ##################
# Adding the following two lines of code finally made the error "Invalid Host header" go away.
# The following two headers will pass the client ip address to the upstream server
# See upstream ui at the very begining of this file.
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /api {
# Requests that have '/api' in the path are rounted to the express server.
proxy_pass http://node-app;
}
}
#
Finally, if you want to take a look at my docker compose file, which has all the services(including nginx), here it is
version: '3'
services:
# This is the nginx service.
proxy:
build:
# The proxy folder will have the Dockerfile and the default.conf file I mentioned above.
context: ./proxy
ports:
- 7081:80
redis-server:
image: 'redis'
node-app:
restart: on-failure
build:
context: ./globoappserver
ports:
- "9080:8080"
container_name: api-server
ui:
build:
context: ./globo-react-app-ui
environment:
- CHOKIDAR_USEPOLLING=true
ports:
- "7000:3000"
stdin_open: true
volumes:
- ./globo-react-app-ui:/usr/app
postgres:
image: postgres
volumes:
- postgres:/var/lib/postgresql/data
- ./init-database.sql:/docker-entrypoint-initdb.d/init-database.sql
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
volumes:
postgres:
When an HTTP request is made, by default, browsers/clients include the "Host" (from the URL) as part of the headers of the raw HTTP request. As part of an extra security/sanity check that is now commonplace, that Host header must match what is expected by the HTTP server for the server to send you back what you expect.
By default, the Webpack Dev Server (WDS) only accepts incoming HTTP requests with Host header that matches some common hostnames like localhost. When a request comes in with an unexpected Host header, the server still needs to respond with something. So it does the minimum it can: send a response with a standard HTTP error code and a human readable message in the HTML: "Invalid Host header".
Now, as for how to fix this issue, there are basically two options. Tell WDS to accept more (or all) "Host" headers or fix the Host header that is sent with the HTTP request.
Configure Webpack
Generally, it's easier (and more correct) to tell the WDS configuration to allow more "Host"names to be used. By default, WDS only accepts connections from the local development machine and so, by default, only needs to support the hostname localhost. Most commonly this "Invalid Host header" issue comes up when trying to server to other clients on the network. After adding host: '0.0.0.0' to the devServer configuration, WDS needs to be told which names might be used by clients to talk to it. require('os').hostname() is usually (one of) the hostnames but other names could be just as valid. Because of this, WDS accepts a list of allowed names.
module.exports = {
//...
devServer: {
allowedHosts: [
require('os').hostname(),
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
}
};
However, sometimes getting this list correct is more trouble than it's worth and it's good enough to just tell WDS to ignore the Host header check. In Webpack 4, it was the disableHostCheck option. In Webpack 5, the allowedHosts option could be set to the single string 'all' (no array).
Create React App (CRA)
The popular package create-react-app uses Webpack internally. CRA has an extra environment variable just to override this particular setting: DANGEROUSLY_DISABLE_HOST_CHECK=true.
Send different Host header
If changing the configuration of Webpack is not possible, the other way to get around this is to change the configuration of the client.
One trick is to use the hosts file on the client machine such that the hostname needed maps to the server's IP.
More common is when a reverse proxy is in-front of WDS. Different proxies have different defaults for the request that's sent to the backend (WDS). You might need to specifically add the Host header to the requests to the backend as VivekDev's answer suggests.
Anyone coming here in 2021 on webpack-dev-server v4+,
allowedHosts and disableHostsCheck were removed in favor of allowedHosts: 'all'
To get rid of the error, change your devServer to this:
devServer: {
compress: true,
allowedHosts: 'all'
}
I solved this problem by adding proxying of the host header in the nginx configuration, like this:
server {
listen 80;
server_name localhost:3000;
location / {
proxy_pass http://myservice:8080/;
proxy_set_header HOST $host;
proxy_set_header Referer $http_referer;
}
}
I added that:
proxy_set_header HOST $host;
proxy_set_header Referer $http_referer;
Since webpack-dev-server 4 you need to add this to your config:
devServer: {
firewall: false,
}
note for vue-cli users:
put a file vue.config.js in the root, with the same lines:
module.exports = {
configureWebpack: {
devServer: {
public: '0.0.0.0:8080',
host: '0.0.0.0',
disableHostCheck: true,
}
}
};
This may happen under two situations:
When you run your webpack-dev-server in cloud-9 or any other online IDE other than localhost.
When you want to run the dev mode on mobile or quickly share the web app with another person via a public URL for your localhost (e.g. using ngrok). For security purposes, you cannot externally access your webpack-dev-server.
You can achieve this in the following way:
devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}
If you have no regard for security, you may set allowedHosts to 'all'. (Not recommended, though)
If you use some-host-url to make public URLs, you can do as follows:
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com'
]
}
For more info: Official doc
I tried the suggestions above but the following solution didn't work for me:
devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}
The following solution works for me:
devServer: {
disableHostCheck: true
}
For webpack-dev-server 4.7 you can use --allowed-hosts all
npx webpack serve --open --allowed-hosts all
Since I am starting the server with npm start, I need to alter package.json as follows,
"scripts": {
"start": "webpack-dev-server --progress --disableHostCheck"
},
Try adding the following in your webpack.config.js file. This worked for me.
devServer: {
allowedHosts: [yourhostname.com]
}
There is some webpack dev server config (it's part of the whole config):
config.devServer = {
contentBase: './' + (options.publicFolder ? options.publicFolder : 'public'),
stats: {
modules: false,
cached: false,
colors: true,
chunk: false
},
proxy: [{
path: /^\/api\/(.*)/,
target: options.proxyApiTarget,
rewrite: rewriteUrl('/$1'),
changeOrigin: true
}]
};
function rewriteUrl(replacePath) {
return function (req, opt) { // gets called with request and proxy object
var queryIndex = req.url.indexOf('?');
var query = queryIndex >= 0 ? req.url.substr(queryIndex) : "";
req.url = req.path.replace(opt.path, replacePath) + query;
console.log("rewriting ", req.originalUrl, req.url);
};
}
I execute webpack with the following command:
node node_modules/webpack-dev-server/bin/webpack-dev-server.js --host 0.0.0.0 --history-api-fallback --debug --inline --progress --config config/webpack.app.dev.js
I can get access to dev server using http://localhost:8080 on my local machine, but I also want to get access to my server from my mobile, tablet (they are in the same Wi-Fi network).
How can I enable it? Thanks!
(If you're on a Mac and network like mine.)
Run webpack-dev-server with --host 0.0.0.0 — this lets the server listen for requests from the network, not just localhost.
Find your computer's address on the network. In terminal, type ifconfig and look for the en1 section or the one with something like inet 192.168.1.111
In your mobile device on the same network, visit http://192.168.1.111:8080 and enjoy hot reloading dev bliss.
You can set your ip address directly in webpack config file:
devServer: {
host: '0.0.0.0',//your ip address
port: 8080,
disableHostCheck: true,
...
}
It may not be the perfect solution but I think you can use ngrok for this.
Ngrok can help you expose a local web server to the internet.
You can point ngrok at your local dev server and then configure your app to use the ngrok URL.
e.g Suppose your server is running on port 8080. You can use ngrok to expose that to outer world via running
./ngrok http 8080
Good thing about ngrok is that it provides a more secure https version of exposed url which you give to any other person in the world to test or show your work.
Also it has lots of customization available in the command such as set a user friendly hostname instead of random string in the exposed url and lots of other thing.
If you just want to open your website to check mobile responsiveness you should go for browersync.
For me, what helped eventually was adding this to the webpack-dev-server config:
new webpackDev(webpack(config), {
public: require('os').hostname().toLowerCase() + ':3000'
...
})
and then also changing babel's webpack.config.js file:
module.exports = {
entry: [
'webpack-dev-server/client?http://' + require('os').hostname().toLowerCase() + ':3000',
...
]
...
}
Now just get your computer hostname (hostname on OSX's terminal), add the port you defined, and you're good to go on mobile.
Compared to ngrok.io, this solution will also let you use react's hot reloading module on mobile.
I could not comment in order to add additional information to forresto's answer, but here in the future (2019) you'll need to add a --public flag due to a security vulnerability with --host 0.0.0.0 alone. Check out this comment for more details.
In order to avoid "responding to other answers" as an answer here's forresto's advice plus the additional details you'll need to make this work:
Add both:
--host 0.0.0.0
and
--public <your-host>:<port>
where your-host is the hostname (for me it is (name)s-macbook-pro.local)) and port is whatever port you're trying to access (again, for me it's 8081).
So here's what my package.json looks like:
"scripts": {
...
"start:webpack": "node_modules/.bin/webpack-dev-server --host 0.0.0.0 --public <name>s-macbook-pro.local:8081",
...
},
I found this thread while searching for a solution that would satisfy the following requirements:
automatically open URL using the public IP. For example, http://192.168.86.173:8080. So it could be copied from the browser and sent to another device in the network.
dev server is available in the local network.
Webpack 4
devServer: {
host: '0.0.0.0',
useLocalIp: true,
}
Webpack 5
devServer: {
host: 'local-ip',
}
With webpack-dev-server v4.0.0+ you need
devServer: {
host: '0.0.0.0',
port: 8030,
allowedHosts: ['all'] // or use 'auto' for slight more security
}
If you tried everything stated in the other answers here, without success... also make sure there's no firewall running on you machine(s) or open the needed ports on it.