ionic-cli
ionic-cli copied to clipboard
Ionic serve launches browser to "Invalid Host header" only
Bug Report
Ionic Info
Ionic:
ionic (Ionic CLI) : 4.0.1 (/home/david/.nvm/versions/node/v9.11.2/lib/node_modules/ionic)
Ionic Framework : @ionic/angular 4.0.0-beta.0
@angular-devkit/core : 0.7.0-rc.3
@angular-devkit/schematics : 0.7.0-rc.3
@angular/cli : 6.0.8
@ionic/ng-toolkit : 1.0.0
@ionic/schematics-angular : 1.0.1
System:
NodeJS : v9.11.2 (/home/david/.nvm/versions/node/v9.11.2/bin/node)
npm : 5.6.0
OS : Linux 4.14
Describe the Bug
In a new Ionic v4 beta project when I simply run ionic serve
it launches a browser but only displays the message "Invalid Host header" as the only page content.
Steps to Reproduce Steps to reproduce the behavior:
(Follow exact steps in docs for a new v4 beta project.)
-
npm install -g ionic
-
ionic start myApp tabs --type=angular
-
ionic serve
- See error in browser
Related Code
N/A
Expected Behavior
That it launches the app content in the browser.
Additional Context
I'm on a Pixelbook so running inside a LXC container so this issue might be limited to containers.
Maybe a workaround would be to configure webpack to work with the Chrome OS Linux LXC container (aka Crostini) default hostname of penguin.linux.test
?
@DavidFrahm This works, then, correct?
ionic serve --address penguin.linux.test
I had the same problem, and adding the --address
parameter did solve it for me.
The default host for ionic serve
is 0.0.0.0
, which should be accessible on all interfaces, including the alias 'localhost'. If your computer can't resolve localhost
, then the value needs to be changed.
My server (vanilla Debian install) resolves localhost
without a problem, but that wasn't the issue for me. The --address
parameter is necessary if you want to test from the network or Internet (which makes sense in retrospect), but ionic serve
doesn't make that very clear, nor does the slightly cryptic "Invalid Host header" message. A hint in the console to the developer when they run ionic serve
might be in order.
I was wrong about the default, sorry! The default is actually 0.0.0.0
, but localhost
should resolve to the host. If it does not, then the value needs to be changed.
@eslindsey So actually the default for ionic serve
is to spin up a server on all network interfaces (0.0.0.0
), allowing testing from the network. localhost
will resolve, but other hosts/addresses will resolve as well.
ionic serve --help
does make this clear:
By default, ionic serve boots up a development server on all network interfaces and prints the external address(es)
on which your app is being served. It also broadcasts your app to the Ionic DevApp on your network. To disable the
DevApp and bind to localhost, use --local.
Okay and this makes sense, because if it wasn't listening on all interfaces then I never could have gotten the "Invalid Host header" message in the first place (it would have refused the connection instead, probably).
Still, the server presents an error message with the default ionic serve
when it didn't before, which could confuse some people. I maintain my recommendation for some kind of hint that the --address
parameter is now necessary. (Unless you're using an IP address to access the site? What is the default --address
, anyway, localhost? What exactly will the default server respond to without the manual --address
parameter?)
Interestingly, without the --address
parameter, I get the following (snipped) output:
Local: http://localhost:8100 External: http://50.192.28.253:8100 DevApp: Blitz@8100 on blitz
so this might lead me to believe that I could copy and paste that address (External) and it should work--and it does. But since I have a domain name associated with that address, I naively thought that I could just use that instead (which worked in previous versions of Ionic).
Now, if I add the --address
parameter, then the output becomes:
Local: http://localhost:8100 DevApp: Blitz@8100 on blitz
...which would seem to imply that now I can't access it externally at all! (Although that assumption is incorrect and everything works the way it's supposed to.)
How come the External
line disappears when you manually supply an address?
Obviously there's some work to be done here!
To try to explain what's going on:
-
The default value for
--address
is0.0.0.0
, which binds to all interfaces, which means connecting tolocalhost
will resolve on nearly all computers (according to/etc/hosts
). -
The Angular CLI/webpack-dev-server have a mechanism for validating the host. I ran into the "Invalid Host header" issue when using
0.0.0.0
and attempting to access it viacustomhost
, which I defined in my/etc/hosts
file like so (at bottom):127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost 127.0.0.1 customhost
This validation can be disabled using the Angular CLI's
--disable-host-check
, but a better, safer way would be to use both--host
and--public-host
. The Ionic CLI only has a concept of--address
, which is the bind address, and thenlocalhost
is always used for public host, which is used in the browser.I think the behavior may need to change such that whenever
--address
is used, we use it for both the host and the browser URL. If0.0.0.0
is used,localhost
should be fine unless your computer can't resolve it... which is very rare. This issue is the first I've heard of it. -
Not showing
External
when an IP address is used is definitely a bug 😂 The server should still work externally, but it's just not being printed.
I agree with what you've said there.
I think there's more at play, as well (although I'm new to Ionic so I may be wrong). If I do ionic start myApp blank --type ionic-angular && ionic serve
(for Angular2 and no address), then I can access the server non-locally using an assigned domain name. However, if I do ionic start myApp blank --type angular && ionic serve
(for Angular4) then I cannot access the server non-locally--it gives me this "Invalid Host header" message. I think the host header check is new, and it changes the behavior of the default ionic serve
.
It's new because ionic-angular
does not use the Angular CLI at all. Only angular
.
Additionally, ionic-angular
is for (stable) Ionic 3 (Angular 5), angular
is for (beta) Ionic 4 (Angular 6).
@dwieeb No, using my container hostname as you suggest does not work.
david@penguin:~/projects/play/ionic-v4-beta$ ionic serve --address penguin.linux.test
> ng run app:serve --host=penguin.linux.test --port=8100
[INFO] Waiting for connectivity with ng...
[INFO] Development server running!
Local: http://localhost:8100
DevApp: myApp@8100 on penguin
Use Ctrl+C to quit this process
[INFO] Browser window opened to http://localhost:8100!
[ng] getaddrinfo ENOTFOUND penguin.linux.test
[ng] Error: getaddrinfo ENOTFOUND penguin.linux.test
[ng] at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:67:26)
[ERROR] A utility CLI has unexpectedly closed.
The Ionic CLI will exit. Please check any output above for error details.
What I thought was working the other day was finding my current external IP and passing that in. But now that's not working or I'm doing it wrong :(
So would be great if ionic serve
could magically do that kind of thing, but I don't know if that's really the right thing for general behavior or how challenging that would be.
@dwieeb Just remembered what I was doing the other day to get something usable:
- I run a default
ionic serve
- Above launches my browser to
http://penguin.linux.test:8100/
with failure "Invalid Host header" - I get the "External" ip address output from the
ionic serve
command (where it displays Local/External/DevApp) - Open the browser to that External address, and it works
@davidfrahm using a hostname will only work if the hostname is resolvable at the server and the client, which can be complicated if you're not testing locally. But here are a few pointers:
If the container is penguin.linux.test
, then you should be able to ping penguin.linux.test
successfully. If you can't, you need to add
127.0.0.1 penguin.linux.test
to your /etc/hosts
on the server.
Additionally, if you are testing from non-local, then you need to resolve the name there as well, so you would need to add
<ip_addr_of_penguin> penguin.linux.test
to that machine's /etc/hosts
.
That's a lot of work, so usually if you get to the point where you need that kind of testing, you'd add something like dnsmasq to take care of those details for you.
Regardless, the name you specify in --address
MUST be resolvable on the server and client in order for everything to work.
Edit: I often see problems like this if a host name is set in /etc/hostname
but doesn't have a corresponding entry in /etc/hosts
. The first sets the machine's hostname, but that doesn't automatically make it reachable or resolvable. For that, you need the second step. Doing one but not the other can lead to a plethora of mysterious Linux problems. Ionic is probably trying to use penguin.linux.test
because that's what you've told Linux this machine's name is. But your DNS server (or hosts
file if local) are unaware of that, so the name can't be resolved.
It's also worth noting that if you get to the point of using TLS/SSL/HTTPS, you will need to be able to resolve by name, because using the IP address won't match the certificate and you'll get security errors.
Not showing External when an IP address is used is definitely a bug 😂 The server should still work externally, but it's just not being printed.
@dwieeb is this bug? CLI checked using 0.0.0.0 in https://github.com/ionic-team/ionic-cli/blob/develop/packages/%40ionic/cli-utils/src/lib/serve.ts#L342 and if use other port, cam't access from dev Apps.
ref: https://github.com/ionic-team/ionic-cli/blob/develop/packages/%40ionic/cli-utils/src/lib/serve.ts#L248-L249
@rdlabo That code looks right to me. If options.address
is configured with a custom IP, it is used. If it's the default (0.0.0.0
), then it has to ask the user to select a specific one. This is for Cordova livereload so the CLI can write the specific IP to config.xml
so that the device can reach the livereload server on the dev's computer.
I think the issue is more with the display. It assumes an IP is only external if the externalNetworkInterfaces
array is not empty, which is not the case if a custom IP is provided.
This does appear to be Ionic-Angular related. When I create an Ionic only app I don't have the issue. I also don't have it with an Angular only app. The way to get around it was to get my containers IP Address and use it in the browser. I had tried to disable host check but that didn't work. Use the container IP for now.
@innovateworld You would get the issue with an Angular app if you used --host 0.0.0.0
and tried to access it via a different public host.
Trying to use ChromeOS Crostini and ngrok + devapp for testing and hitting this issue. What is the recommendation here in 2019?
@philips I'm experiencing this on Crostini too. I wasn't able to get penguin.linux.test
working but the external IP worked.
This should be added to the docs at least, everyone on Crostini can't even get past the getting started steps. All new Chromebooks starting this year (announced at Google I/O) will be Linux compatible so I imagine more people will run into this.
@kevin-brotcke @philips The default host is changing to localhost
with Ionic CLI 5 (likely to be released this month). Want to give it a try? npm i -g ionic@beta
. For external addresses, we'll have to document the --public-host
option, when implemented: https://github.com/ionic-team/ionic-cli/issues/3558
Having kind of the same problem. I have every .lcl domain pointed to localhost (127.0.0.1) and want ionic serve
to open xxx.lcl instead of localhost. When I do this with ionic serve --source-map --ssl --no-open --consolelogs --devapp --host='xxxx.lcl'
I still shows this:
[INFO] Development server running!
Local: https://localhost:8100
External: https://xxx.xxx.xxx.xxx:8100
DevApp: APPNAME@8100 on xxxx.xxxxx
Has anyone found a solution to this? I just want to develop on a remote machine and it seems there is no clear answer to get --disableHostCheck into the command line that starts the server.
My work around. Install angular at a global level.
npm install -g @angular/cli
Then run
ng run app:serve --host=0.0.0.0 --port=8100 --disable-host-check
Thank you! Working perfectly.
I used:
ionic serve --port 8080 --address 0.0.0.0 -- --disableHostCheck true
Hello all (especially @DavidFrahm @eslindsey @philips @kevin-brotcke) 👋
I have implemented the --public-host
option for the Ionic CLI which should resolve all issues here. This option provides a way for devs to specify which host the browser should use, regardless of which host the dev server is bound to.
Please help me test this PR by installing a test version of the Ionic CLI:
npm i -g @ionic/[email protected]
Couple things to note:
-
--address
is now named--host
- the default host is
localhost
, not0.0.0.0
- use
ionic serve --host=0.0.0.0 --public-host=<hostname>
to test
Let me know what you think! 💙
ionic serve --port 4200 --no-open --host=0.0.0.0 --public-host=iloveu.dev.luketic
Invalid Host header
server {
listen 80;
listen [::]:80;
server_name iloveu.dev.luketic;
index index.html;
error_log /var/log/nginx/iloveu.error;
location /sockjs-node/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
rewrite ^/(.*)$ /$1 break;
proxy_set_header Host localhost;
proxy_pass http://localhost:4200/;
}
location / {
proxy_pass http://localhost:4200;
proxy_read_timeout 30;
proxy_connect_timeout 30;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
proxy_pass http://unix:/tmp/i-lov.eu-restful.sock;
proxy_read_timeout 30;
proxy_connect_timeout 30;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
For the record nothing I did could make vue-cli play along and not show the invalid host header.
Where can we set the "devserver" webpack configuration?
Ok here's how:
create /vue.config.js
relative to project root
module.exports = {
devServer: {
allowedHosts: 'all'
}
}
docs: https://webpack.js.org/configuration/dev-server/#devserverallowedhosts