当我远程连接webpack-dev-server时,出现了“Invalid Host header”错误信息。

288

我使用Cloud9.io Ubuntu VM在线IDE作为环境,我已经将解决此错误的步骤简化为仅使用Webpack dev服务器运行应用程序。

我使用以下命令启动它:

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

$IP是一个变量,代表主机地址 $PORT是端口号。

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

服务器启动并编译代码,没有问题,但它并没有向我显示索引文件。只有一个带有“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

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


似乎问题超出了注释范围。 - elmeister
我不明白问题是如何发生的。你能指导我正确的方向吗? - Artur Vieira
这是我在RedwoodJS中的解决方案:https://github.com/redwoodjs/redwood/issues/534#issuecomment-821832435 - Ryan
2021年更新:请指定host选项(文档)。例如:devServer: { host: 'example.com', ... } - rinogo
25个回答

3
在Visual Studio Code的终端中,你可以这样做: ng serve --disable-host-check 如果你想在端口4200上使用SSH启动一个临时服务器,你可以这样做:
ssh -R 80:localhost:4200 nokey@localhost.run

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

2

当使用与此帖子相关的webpack 5的默认行为(没有配置文件)时:[https://dev59.com/uVkS5IYBdhLWcg3wFi-k#65268634`]

注:本文中的链接需要手动复制到浏览器中打开。

"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即可解决问题。


1
我正在使用运行在Docker容器内的nginx来基于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:

1
我刚使用Windows子系统(WSL2)时遇到了这个问题,所以我也会分享这个解决方案。
我的目标是在wsl:3000localhost:3000上呈现webpack的输出,从而创建一个备用的本地端点。
正如您可能预期的那样,这最初导致了“无效的主机头”错误。 直到我添加了下面显示的devServer配置选项才有所帮助。
module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['http://wsl:3000'],
        target: 'http://localhost:3000',
      },
    ],
  },
}

这样做可以修复“漏洞”,而不会引入任何安全风险。
参考资料:webpack DevServer文档

1
当发起一个HTTP请求时,默认情况下,浏览器/客户端会将URL中的"Host"作为原始HTTP请求头的一部分。作为额外的安全/健全性检查,现在普遍采用的做法是,Host头必须与HTTP服务器所期望的匹配,才能使服务器返回你所期望的内容。
默认情况下,Webpack Dev Server (WDS) 只接受具有与某些常见主机名(如localhost)匹配的Host头的传入HTTP请求。当出现意外的Host头的请求时,服务器仍然需要响应一些内容。因此,它会尽可能地做最小的响应:发送带有标准HTTP错误代码和HTML中可读的人类可读消息的响应:"Invalid Host header"。
现在,关于如何解决这个问题,基本上有两个选项。告诉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'(没有数组)。

Create React App (CRA)

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

发送不同的Host头

如果改变Webpack的配置不可能,绕过这个问题的另一种方法是改变客户端的配置。

一个技巧是在客户端机器上使用hosts文件,使所需的主机名映射到服务器的IP地址。
更常见的情况是当反向代理位于WDS前面时。不同的代理对发送到后端(WDS)的请求有不同的默认值。您可能需要像VivekDev's answer建议的那样,特别添加Host头以请求后端。

1

如果您在2021年使用webpack-dev-server v4+,则需要注意以下内容:

allowedHostsdisableHostsCheck已被删除,取而代之的是allowedHosts: 'all'

为了消除错误,请将您的devServer更改为以下代码:

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

1

你好,React开发者们!

不要在webpackDevServer.config.js中使用 disableHostCheck: true。你可以通过添加一个.env文件到你的项目中并在其中加入变量 HOST=0.0.0.0DANGEROUSLY_DISABLE_HOST_CHECK=true 来轻松解决'invalid host headers'错误。如果你想要更改webpackDevServer.config.js的设置,你需要通过'npm run eject'来提取react-scripts,但这并不推荐这么做。因此,更好的解决方案是将以上提到的变量添加到你的项目的.env文件中。

愉快的编码 :)


这是Kyle Ordona下面现有答案的副本。 - mikemaccana
是的,我遇到了同样的问题。我尝试执行提供的解决方案。经过尝试很多解决方案后,这个解决方案对我来说很好用。但我个人感觉需要详细说明答案。程序员可能不知道该使用哪个解决方案。因此,我比较了最好的两个解决方案,并解释了其中最好的一个。谢谢。@mikemaccana - Eswar Nandam

0

对于vue-cli用户的注意事项:

在根目录下放置一个名为vue.config.js的文件,内容如下:

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

0
由于我使用 npm start 启动服务器,因此需要按照如下方式更改 package.json
"scripts": {
  "start": "webpack-dev-server --progress --disableHostCheck"
},

0
尝试在你的webpack.config.js文件中添加以下内容。这对我有效。
devServer: {
    allowedHosts: [yourhostname.com]
}

这个答案是 https://dev59.com/vlcP5IYBdhLWcg3w6-Op#51463168 的副本。 - kimbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接