我得到一个“无效主机”标题;远程连接webpack-dev-server时的消息

我正在使用Cloud9作为一个环境。io ubuntu虚拟机在线IDE和我已经减少了这个错误,只是运行应用程序与Webpack开发服务器。

我用:

webpack-dev-server -d --watch --history-api-fallback --host $IP --port $PORT

$IP是一个包含主机地址的变量

. $PORT包含端口号

当在Cloud 9中部署应用程序时,我被指示使用这些变量,因为它们有默认的IP和PORT信息。

服务器启动并编译代码,没有问题,它是显示我的索引文件。只有一个空白屏幕与“无效的主机标题”作为文本。

这是请求:

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

这是我的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"
}
}

这是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开发服务器返回这个,因为我的主机设置。在webpack-dev-server/lib/Server.js第60行。从https://github.com/webpack/webpack-dev-server

我的问题是我如何设置正确通过这个检查。任何帮助都将不胜感激。

319692 次浏览

我发现,我需要设置devServer的public属性为我的请求的主机值。因此,它将显示在该外部地址。

所以我需要在我的webpack.config.js中

devServer: {
compress: true,
public: 'store-client-nestroia1.c9users.io' // That solved it
}

另一个解决方案是在CLI中使用它:

webpack-dev-server --public $C9_HOSTNAME   <-- var for Cloud9 external IP

出现这个问题是因为webpack-dev-server 2.4.4添加了一个主机检查。你可以通过添加到你的webpack配置来禁用它:

 devServer: {
compress: true,
disableHostCheck: true,   // That solved it


}

请注意,此修复是不安全的

请参阅这个答案的安全解决方案。

在版本4.0.0中,选项为重构。现在应该使用allowedHosts选项:

devServer: {
allowedHosts: "all"
}

如果您正在C9上使用create-react-app,只需运行此命令启动

npm run start --public $C9_HOSTNAME

不管你的主机名是什么(例如在终端中输入$C_HOSTNAME来获得主机名)

当使用webpack-dev-server时,将此配置添加到webpack配置文件中(您仍然可以将主机指定为0.0.0.0)。

devServer: {
disableHostCheck: true,
host: '0.0.0.0',
port: 3000
}

这对我来说很管用:

在webpack.config.js中添加allowedHosts:

devServer: {
compress: true,
inline: true,
port: '8080',
allowedHosts: [
'.amazonaws.com'
]
},

我不需要使用——host或——public参数。

更安全的选择是在你的Webpack配置中添加allowwedhosts,如下所示:

module.exports = {
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
}
};

数组包含所有允许的主机,还可以指定子域名。点击这里查看更多信息

如果你还没有从CRA中弹出,你不能轻易地修改你的webpack配置。配置文件隐藏在node_modules/react_scripts/config/webpackDevServer.config.js中。不建议您更改该配置。

相反,你可以将环境变量DANGEROUSLY_DISABLE_HOST_CHECK设置为true来禁用主机检查:

DANGEROUSLY_DISABLE_HOST_CHECK=true yarn start
# or the equivalent npm command

与其编辑webpack配置文件,更简单的禁用主机检查的方法是添加一个.env文件到你的根文件夹,并放入:

DANGEROUSLY_DISABLE_HOST_CHECK=true

正如变量名所暗示的,禁用它是不安全的,并且只能在开发环境中使用明智的

如果你在容器中运行webpack-dev-server,并通过容器名向它发送请求,你会得到这个错误。要允许来自同一网络上其他容器的请求,只需使用--public选项提供容器名(或任何用于解析容器的名称)。这比完全禁用安全检查要好。

在我的例子中,我使用docker-compose在名为assets的容器中运行webpack-dev-server。我把开始命令改为这样:

webpack-dev-server --mode development --host 0.0.0.0 --public assets

另一个容器现在可以通过http://assets:5000发出请求。

你好React开发者

而不是这样做 webpackDevServer.config.js中的disableHostCheck: true,。你可以通过在你的项目中添加一个.env文件来轻松解决“无效的主机头”错误,在.env文件中添加变量主机= 0.0.0.0DANGEROUSLY_DISABLE_HOST_CHECK = true。如果你想在webpackDevServer.config.js中进行更改,你需要使用'npm run eject'来提取反应脚本,不建议这样做。因此,更好的解决方案是在项目的.env文件中添加上述变量

快乐编码:)

我刚刚在使用Windows子系统for Linux (WSL2)时遇到了这个问题,所以我也将分享这个解决方案。

我的目标是在wsl:3000localhost:3000处呈现webpack的输出,从而创建一个备用本地端点。

如您所料,这最初会导致“无效主机标题”;出现错误。似乎没有什么帮助,直到我添加了如下所示的devServer配置选项。


module.exports = {
//...
devServer: {
proxy: [
{
context: ['http://wsl:3000'],
target: 'http://localhost:3000',
},
],
},
}

这修复了“bug”;不存在安全风险。

参考:webpack DevServer文档

我通过在nginx配置中添加主机头的代理来解决这个问题,就像这样:

server {
listen 80;
server_name     localhost:3000;


location / {
proxy_pass http://myservice:8080/;


proxy_set_header HOST $host;
proxy_set_header Referer $http_referer;
}
}

我补充说:

proxy_set_header主机

$http_referer;

因为webpack-dev-server 4你需要添加这个到你的配置:

devServer: {
firewall: false,
}

当使用webpack 5的默认行为(没有配置文件)时,这篇文章:[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"
},

使用webpack 5帮助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.

解决方案

所以,只要用webpack serve命令添加--disable-host-check就可以了。

我使用nginx运行在docker容器内部,根据url路由流量。

在nginx配置文件中添加以下两行代码,为我修复了错误无效的主机报头。参见下面的配置文件(default.conf)。

proxy_set_header Host            $http_host;
proxy_set_header X-Forwarded-For $remote_addr;

首先,下面是我简单的两行Dockerfile来创建nginx容器,然后用路由配置它。

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf

因此,当构建映像时,default.conf文件被复制到nginx容器内的配置目录。

接下来,default.conf文件如下所示。

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;
}
}
#

最后,如果你想看一下我的docker compose文件,它有所有的服务(包括nginx),在这里

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:

vue-cli用户的注释:

将vue.config.js文件放在根目录下,使用相同的代码行:

module.exports = {
configureWebpack: {
devServer: {
public: '0.0.0.0:8080',
host: '0.0.0.0',
disableHostCheck: true,
}
}
};

当发出HTTP请求时,默认情况下,浏览器/客户端包含"Host"(来自URL)作为原始HTTP请求头的一部分。作为额外的安全/完整性检查的一部分,现在很常见,Host报头必须匹配HTTP服务器所期望的内容,以便服务器向你发送你所期望的内容。

默认情况下,Webpack Dev Server (WDS)只接受带有Host报头的传入HTTP请求,该报头与一些常见主机名(如localhost)匹配。当一个带有意外Host报头的请求进入时,服务器仍然需要用某物进行响应。因此,它尽其所能:发送一个带有标准HTTP错误代码的响应,并在HTML中发送一条人类可读的消息:“无效主机标题”。

现在,至于如何解决这个问题,基本上有两个选择。告诉WDS接受更多(或全部)“Host"头或修复与HTTP请求一起发送的Host头。

配置Webpack

通常,告诉WDS配置允许使用更多的“主机”名称更容易(也更正确)。默认情况下,WDS只接受来自本地开发机器的连接,因此默认情况下,只需要支持主机名localhost。最常见的是这个“无效的主机标题”;当试图向网络上的其他客户端提供服务器时出现问题。在将host: '0.0.0.0'添加到devServer配置后,需要告诉WDS客户端可能使用哪些名称与它对话。require('os').hostname()通常是主机名(其中之一),但其他名称也可以同样有效。因此,WDS接受一个允许的名称列表。

module.exports = {
//...
devServer: {
allowedHosts: [
require('os').hostname(),
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
}
};

然而,有时获得正确的列表是比它的价值更多的麻烦,它足够好,只是告诉WDS忽略Host头检查。在Webpack 4中,它是disableHostCheck选项。在Webpack 5中,allowedHosts选项可以设置为单个字符串'all'(没有数组)。

创建React App (CRA)

流行的包create-react-app在内部使用Webpack。CRA有一个额外的环境变量来覆盖这个特定的设置:DANGEROUSLY_DISABLE_HOST_CHECK=true

发送不同的主机报头

如果改变Webpack的配置是不可能的,另一种解决方法是改变客户端的配置。

一个技巧是在客户端机器上使用hosts文件,以便所需的主机名映射到服务器的IP。

更常见的情况是反向代理位于WDS的前面。对于发送到后端(WDS)的请求,不同的代理具有不同的默认值。你可能需要像VivekDev的回答所建议的那样,专门将Host头添加到后端请求中。

2021年使用webpack-dev-server v4+的人,

allowedHostsdisableHostsCheck被删除,改为allowedHosts: 'all'

要摆脱这个错误,将你的devServer更改为:

devServer: {
compress: true,
allowedHosts: 'all'
}

这可能发生在两种情况下:

  1. 当你在cloud-9或除localhost以外的任何在线IDE中运行webpack-dev-server时。
  2. 当你想在移动设备上运行开发模式或通过本地主机的公共URL与他人快速共享web应用程序时(例如使用ngrok)。出于安全考虑,你不能从外部访问你的webpack-dev-server

你可以通过以下方式实现这一点:

devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}
  1. 如果您不考虑安全性,您可以将allowedHosts设置为“all”。(不过不推荐)
  2. 如果使用some-host-url设置url为公共url,可以执行以下操作:
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com'
]
}

更多信息:官方文档

我尝试了上面的建议,但下面的解决方案并不适合我:

devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}

下面的解决方案适合我:

devServer: {
disableHostCheck: true
}
< p >包。在“scripts"”上,添加参数--disableHostCheck=true . json 如:< / p >
"scripts": {
"start": "ng serve --host=0.0.0.0 --configuration=dev --disableHostCheck=true"
}

对于webpack-dev-server 4.7,您可以使用——allowed-hosts all

npx webpack serve --open --allowed-hosts all

因为我用npm start启动服务器,所以我需要像下面这样修改package.json

"scripts": {
"start": "webpack-dev-server --progress --disableHostCheck"
},

尝试在webpack.config.js文件中添加以下内容。这对我很管用。

devServer: {
allowedHosts: [yourhostname.com]
}