远程连接到 webpack-dev-server 时收到 "Invalid Host header" 消息
I am getting an "Invalid Host header" message when connecting to webpack-dev-server remotely
我正在使用 Cloud9.io ubuntu VM Online IDE 作为环境,并且通过解决此错误我已将 运行 应用程序与 Webpack dev 减少服务器。
我启动它:
webpack-dev-server -d --watch --history-api-fallback --host $IP --port $PORT
$IP 是一个包含主机地址的变量
$PORT 有端口号。
我被指示在 Cloud 9 中部署应用程序时使用这些变量,因为它们具有默认 IP 和端口信息。
服务器启动并编译代码,没问题,但不是显示索引文件。只有 "Invalid Host header" 作为文本的空白屏幕。
这是请求:
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
我的问题是如何设置才能正确通过此检查。任何帮助将不胜感激。
我发现,我需要将 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
中为 refactored。现在应该使用 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:
的 devServer 下添加 allowedHosts
devServer: {
compress: true,
inline: true,
port: '8080',
allowedHosts: [
'.amazonaws.com'
]
},
我不需要使用 --host 或 --public 参数。
更安全的选择是像这样将 allowedHosts 添加到您的 Webpack 配置中:
module.exports = {
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
}
};
数组包含所有允许的主机,您也可以指定子域名。 check out more here
如果你还没有从 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
选项提供容器名称(或用于解析容器的任何名称)。这比完全禁用安全检查要好。
就我而言,我是 运行 webpack-dev-server
在一个名为 assets
的容器中,使用 docker-compose。我将启动命令更改为:
webpack-dev-server --mode development --host 0.0.0.0 --public assets
并且另一个容器现在可以通过 http://assets:5000
发出请求。
你好React 开发者,
而不是这样做
disableHostCheck: true,
在 webpackDevServer.config.js。您可以通过向项目添加 .env 文件轻松解决 'invalid host headers' 错误,添加变量 HOST= .env 文件中的 0.0.0.0 和 DANGEROUSLY_DISABLE_HOST_CHECK=true。如果要在 webpackDevServer.config.js 中进行更改,则需要使用 'npm run eject' 提取 react-scripts不建议这样做。所以更好的解决方案是在项目的 .env 文件中添加上述变量。
快乐编码:)
我刚刚在为 Linux (WSL2) 使用 Windows 子系统时遇到了这个问题,所以我也会分享这个解决方案。
我的 objective 是在 wsl:3000
和 localhost:3000
上渲染 webpack 的输出,从而创建一个备用本地端点。
如您所料,这最初导致出现“无效主机 header”错误。在我添加如下所示的 devServer 配置选项之前似乎没有任何帮助。
module.exports = {
//...
devServer: {
proxy: [
{
context: ['http://wsl:3000'],
target: 'http://localhost:3000',
},
],
},
}
这修复了“错误”,没有引入任何安全风险。
参考:webpack DevServer docs
我通过在 nginx 配置中添加主机代理 header 解决了这个问题,如下所示:
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 主机 $host;
proxy_set_header 推荐人 $http_referer;
从 webpack-dev-server 4 开始,您需要将此添加到您的配置中:
devServer: {
firewall: false,
}
在与此相关的 webpack 5 中使用默认行为(无配置文件)时 post:[
"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
即可。
我在 docker 容器内使用 nginx 运行 来根据 url.
路由流量
在 nginx 配置文件中添加以下两行代码为我修复了 Invalid Host header 错误。请参阅下面的配置文件(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 请求时,默认情况下,browsers/clients 包含“Host
”(来自 URL)作为 header 的一部分原始 HTTP 请求。作为现在常见的额外 security/sanity 检查的一部分,Host
header 必须与 HTTP 服务器期望的内容相匹配,以便服务器向您发送您期望的内容。
默认情况下,Webpack 开发服务器 (WDS) 只接受带有 Host
header 的传入 HTTP 请求,这些请求与 localhost
等常见主机名匹配。当请求以意外 Host
header 传入时,服务器仍需要以 某些内容 进行响应。因此它会尽其所能:发送一个带有标准 HTTP 错误代码的响应,并在 HTML 中发送一条人类可读的消息:“无效主机 header”。
现在,至于如何解决这个问题,基本上有两种选择。告诉 WDS 接受更多(或所有)“主机”header 或修复随 HTTP 请求发送的 Host
header。
配置 Webpack
通常,告诉 WDS 配置允许使用更多“主机”名称会更容易(也更正确)。默认情况下,WDS 只接受来自本地开发机器的连接,因此默认情况下,只需要支持主机名 localhost
。最常见的是,当尝试向网络上的其他客户端提供服务器时,会出现此“无效主机 header”问题。将 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 忽略主机 header 检查。在 Webpack 4, it was the disableHostCheck
option. In Webpack 5 中,allowedHosts
选项可以设置为单个字符串 'all'
(无数组)。
创建 React 应用程序 (CRA)
流行的包 create-react-app
在内部使用 Webpack。 CRA 有一个额外的环境变量来覆盖这个特定的设置:DANGEROUSLY_DISABLE_HOST_CHECK=true
.
发送不同的主机header
如果无法更改 Webpack 的配置,另一种解决方法是更改客户端的配置。
一个技巧是在客户端机器上使用 hosts
文件,这样所需的主机名就会映射到服务器的 IP。
更常见的是当反向代理是 WDS 的 in-front 时。对于发送到后端 (WDS) 的请求,不同的代理具有不同的默认值。您可能需要按照 VivekDev's answer 的建议将 Host
header 特别添加到对后端的请求中。
任何人在 2021 年来到这里使用 webpack-dev-server v4+,
allowedHosts
和 disableHostsCheck
被删除,取而代之的是 allowedHosts: 'all'
要消除错误,请将您的 devServer 更改为:
devServer: {
compress: true,
allowedHosts: 'all'
}
这可能在两种情况下发生:
- 当您 运行 您的
webpack-dev-server
在 cloud-9 或除 localhost 以外的任何其他在线 IDE 中时。
- 当您想 运行 在移动设备上使用开发模式或通过 public URL 为您的本地主机(例如使用 ngrok)快速与其他人共享网络应用程序时。出于安全考虑,您无法从外部访问您的
webpack-dev-server
.
您可以通过以下方式实现:
devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}
- 如果您不考虑安全问题,您可以将 allowedHosts 设置为 'all'。 (虽然不推荐)
- 如果使用some-host-url制作publicURL,可以如下操作:
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com'
]
}
我尝试了上面的建议,但以下解决方案对我不起作用:
devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}
以下解决方案适用于我:
devServer: {
disableHostCheck: true
}
在 package.json 上,在“脚本”上添加参数 --disableHostCheck=true
喜欢:
"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
我正在使用 Cloud9.io ubuntu VM Online IDE 作为环境,并且通过解决此错误我已将 运行 应用程序与 Webpack dev 减少服务器。
我启动它:
webpack-dev-server -d --watch --history-api-fallback --host $IP --port $PORT
$IP 是一个包含主机地址的变量 $PORT 有端口号。
我被指示在 Cloud 9 中部署应用程序时使用这些变量,因为它们具有默认 IP 和端口信息。
服务器启动并编译代码,没问题,但不是显示索引文件。只有 "Invalid Host header" 作为文本的空白屏幕。
这是请求:
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
我的问题是如何设置才能正确通过此检查。任何帮助将不胜感激。
我发现,我需要将 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
中为 refactored。现在应该使用 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:
的 devServer 下添加 allowedHostsdevServer: {
compress: true,
inline: true,
port: '8080',
allowedHosts: [
'.amazonaws.com'
]
},
我不需要使用 --host 或 --public 参数。
更安全的选择是像这样将 allowedHosts 添加到您的 Webpack 配置中:
module.exports = {
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
}
};
数组包含所有允许的主机,您也可以指定子域名。 check out more here
如果你还没有从 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
选项提供容器名称(或用于解析容器的任何名称)。这比完全禁用安全检查要好。
就我而言,我是 运行 webpack-dev-server
在一个名为 assets
的容器中,使用 docker-compose。我将启动命令更改为:
webpack-dev-server --mode development --host 0.0.0.0 --public assets
并且另一个容器现在可以通过 http://assets:5000
发出请求。
你好React 开发者,
而不是这样做
disableHostCheck: true,
在 webpackDevServer.config.js。您可以通过向项目添加 .env 文件轻松解决 'invalid host headers' 错误,添加变量 HOST= .env 文件中的 0.0.0.0 和 DANGEROUSLY_DISABLE_HOST_CHECK=true。如果要在 webpackDevServer.config.js 中进行更改,则需要使用 'npm run eject' 提取 react-scripts不建议这样做。所以更好的解决方案是在项目的 .env 文件中添加上述变量。
快乐编码:)
我刚刚在为 Linux (WSL2) 使用 Windows 子系统时遇到了这个问题,所以我也会分享这个解决方案。
我的 objective 是在 wsl:3000
和 localhost:3000
上渲染 webpack 的输出,从而创建一个备用本地端点。
如您所料,这最初导致出现“无效主机 header”错误。在我添加如下所示的 devServer 配置选项之前似乎没有任何帮助。
module.exports = {
//...
devServer: {
proxy: [
{
context: ['http://wsl:3000'],
target: 'http://localhost:3000',
},
],
},
}
这修复了“错误”,没有引入任何安全风险。
参考:webpack DevServer docs
我通过在 nginx 配置中添加主机代理 header 解决了这个问题,如下所示:
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 主机 $host;
proxy_set_header 推荐人 $http_referer;
从 webpack-dev-server 4 开始,您需要将此添加到您的配置中:
devServer: {
firewall: false,
}
在与此相关的 webpack 5 中使用默认行为(无配置文件)时 post:[ 有了 webpack 5 的帮助 因此,只需使用 "scripts": {
"dev": "webpack serve --mode development --env development --hot --port 3000"
...
...
},
"devDependencies": {
...
"webpack": "^5.10.1",
"webpack-cli": "^4.2.0"
},
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
即可。
我在 docker 容器内使用 nginx 运行 来根据 url.
路由流量在 nginx 配置文件中添加以下两行代码为我修复了 Invalid Host header 错误。请参阅下面的配置文件(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 请求时,默认情况下,browsers/clients 包含“Host
”(来自 URL)作为 header 的一部分原始 HTTP 请求。作为现在常见的额外 security/sanity 检查的一部分,Host
header 必须与 HTTP 服务器期望的内容相匹配,以便服务器向您发送您期望的内容。
默认情况下,Webpack 开发服务器 (WDS) 只接受带有 Host
header 的传入 HTTP 请求,这些请求与 localhost
等常见主机名匹配。当请求以意外 Host
header 传入时,服务器仍需要以 某些内容 进行响应。因此它会尽其所能:发送一个带有标准 HTTP 错误代码的响应,并在 HTML 中发送一条人类可读的消息:“无效主机 header”。
现在,至于如何解决这个问题,基本上有两种选择。告诉 WDS 接受更多(或所有)“主机”header 或修复随 HTTP 请求发送的 Host
header。
配置 Webpack
通常,告诉 WDS 配置允许使用更多“主机”名称会更容易(也更正确)。默认情况下,WDS 只接受来自本地开发机器的连接,因此默认情况下,只需要支持主机名 localhost
。最常见的是,当尝试向网络上的其他客户端提供服务器时,会出现此“无效主机 header”问题。将 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 忽略主机 header 检查。在 Webpack 4, it was the disableHostCheck
option. In Webpack 5 中,allowedHosts
选项可以设置为单个字符串 'all'
(无数组)。
创建 React 应用程序 (CRA)
流行的包 create-react-app
在内部使用 Webpack。 CRA 有一个额外的环境变量来覆盖这个特定的设置:DANGEROUSLY_DISABLE_HOST_CHECK=true
.
发送不同的主机header
如果无法更改 Webpack 的配置,另一种解决方法是更改客户端的配置。
一个技巧是在客户端机器上使用 hosts
文件,这样所需的主机名就会映射到服务器的 IP。
更常见的是当反向代理是 WDS 的 in-front 时。对于发送到后端 (WDS) 的请求,不同的代理具有不同的默认值。您可能需要按照 VivekDev's answer 的建议将 Host
header 特别添加到对后端的请求中。
任何人在 2021 年来到这里使用 webpack-dev-server v4+,
allowedHosts
和 disableHostsCheck
被删除,取而代之的是 allowedHosts: 'all'
要消除错误,请将您的 devServer 更改为:
devServer: {
compress: true,
allowedHosts: 'all'
}
这可能在两种情况下发生:
- 当您 运行 您的
webpack-dev-server
在 cloud-9 或除 localhost 以外的任何其他在线 IDE 中时。 - 当您想 运行 在移动设备上使用开发模式或通过 public URL 为您的本地主机(例如使用 ngrok)快速与其他人共享网络应用程序时。出于安全考虑,您无法从外部访问您的
webpack-dev-server
.
您可以通过以下方式实现:
devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}
- 如果您不考虑安全问题,您可以将 allowedHosts 设置为 'all'。 (虽然不推荐)
- 如果使用some-host-url制作publicURL,可以如下操作:
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com'
]
}
我尝试了上面的建议,但以下解决方案对我不起作用:
devServer: {
allowedHosts: 'auto' | 'all' | Array[string]
}
以下解决方案适用于我:
devServer: {
disableHostCheck: true
}
在 package.json 上,在“脚本”上添加参数 --disableHostCheck=true
喜欢:
"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