【问题标题】:I am getting an "Invalid Host header" message when connecting to webpack-dev-server remotely远程连接到 webpack-dev-server 时收到“Invalid Host header”消息
【发布时间】:2017-09-22 23:56:32
【问题描述】:

我正在使用 Cloud9.io ubuntu VM Online 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

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

【问题讨论】:

标签: javascript webpack webpack-dev-server


【解决方案1】:

在 package.json 的“脚本”上,添加参数 --disableHostCheck=true 喜欢:

"scripts": {
        "start": "ng serve --host=0.0.0.0 --configuration=dev --disableHostCheck=true"
}

【讨论】:

    【解决方案2】:

    我尝试了上述建议,但以下解决方案对我不起作用:

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

    以下解决方案适用于我:

    devServer: {
        disableHostCheck: true
    }
    

    【讨论】:

      【解决方案3】:

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

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

      您可以通过以下方式实现:

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

      For more info: Official doc

      【讨论】:

        【解决方案4】:

        2021 年使用 webpack-dev-server v4+ 来到这里的任何人,

        allowedHostsdisableHostsCheck 被删除以支持 allowedHosts: 'all'

        要消除错误,请将您的 devServer 更改为:

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

        【讨论】:

          【解决方案5】:

          在发出 HTTP 请求时,默认情况下,浏览器/客户端会将“Host”(来自 URL)作为原始 HTTP 请求的标头的一部分。作为现在司空见惯的额外安全/健全性检查的一部分,Host 标头必须与 HTTP 服务器所期望的匹配,以便服务器向您发送您期望的内容。

          默认情况下,Webpack 开发服务器 (WDS) 只接受带有 Host 标头的传入 HTTP 请求,该标头与一些常见的主机名(如 localhost)匹配。当请求带有意外的 Host 标头时,服务器仍然需要以 something 进行响应。因此,它尽其所能:发送带有标准 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'(无数组)。

          创建 React 应用 (CRA)

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

          发送不同的Host头

          如果无法更改 Webpack 的配置,另一种解决方法是更改​​客户端的配置。

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

          更常见的情况是反向代理位于 WDS 前面。对于发送到后端 (WDS) 的请求,不同的代理有不同的默认值。您可能需要按照VivekDev's answer 的建议将Host 标头专门添加到后端请求中。

          【讨论】:

            【解决方案6】:

            vue-cli 用户注意事项

            将文件 vue.config.js 放在根目录下,内容相同:

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

            【讨论】:

              【解决方案7】:

              我正在使用在 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:
              

              【讨论】:

                【解决方案8】:

                在使用与本文相关的 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.
                

                解决方案

                所以,只需添加 --disable-host-checkwebpack serve 命令就可以了。

                【讨论】:

                  【解决方案9】:

                  我发现,我需要将 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 最近进行了此更改,需要正确的主机标头。请参阅github.com/webpack/webpack-dev-server/releases/tag/v2.4.3 了解更多信息。
                  • 此更改也会影响 webpack-dev-server 1.16.4。您可以在此处阅读更多信息:medium.com/webpack/…
                  • 当我在 vue cli 项目中遇到 Invalid Host header 错误时,这对我也有用。
                  • 嘿,我按照你说的做了,但我现在遇到了这个错误。stackoverflow.com/questions/65639318/…有什么想法吗?
                  • 2021 年更新:public 已重命名为 host (Docs)。例如host: 'example.com'
                  【解决方案10】:

                  从 webpack-dev-server 4 开始,您需要将其添加到您的配置中:

                  devServer: {
                    firewall: false,
                  }
                  

                  【讨论】:

                    【解决方案11】:

                    我通过在 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 HOST $host;

                    proxy_set_header 引用者 $http_referer;

                    【讨论】:

                      【解决方案12】:

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

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

                      正如您所料,这最初会导致出现“Invalid Host header”错误。在我添加如下所示的 devServer 配置选项之前,似乎没有任何帮助。


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

                      这修复了“错误”而没有引入任何安全风险。

                      参考:webpackDevServer docs

                      【讨论】:

                        【解决方案13】:

                        您好 React 开发人员

                        而不是这样做 webpackDevServer.config.js 中的disableHostCheck: true,。您可以通过将 .env 文件添加到项目中,添加变量 HOST=0.0.0.0DANGEROUSLY_DISABLE_HOST_CHECK=true.env 文件中。如果您想在 webpackDevServer.config.js 中进行更改,则需要使用 'npm runeject' 提取 react-scripts,不建议这样做。因此,更好的解决方案是在项目的 .env 文件中添加上述变量。

                        快乐编码:)

                        【讨论】:

                        • 这是 Kyle Ordona 下面现有答案的副本
                        • 是的。我遇到了同样的问题。我试图执行提供的解决方案。在尝试了很多解决方案之后,这个解决方案对我来说很好。但我个人觉得要详细说明答案。编码人员可能不知道要采用哪种解决方案。所以,我比较了最好的两种解决方案,并解释了两者中最好的。谢谢。 @mikemaccana
                        【解决方案14】:

                        如果您在容器中运行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 发出请求。

                        【讨论】:

                        • 我的开发环境中发生了一些复杂的 docker 网络,而这正是我所需要的
                        【解决方案15】:

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

                        DANGEROUSLY_DISABLE_HOST_CHECK=true
                        

                        正如变量名所暗示的那样,禁用它是不安全的,并且仅建议仅在开发环境中使用。

                        【讨论】:

                          【解决方案16】:

                          如果你还没有从 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
                          

                          【讨论】:

                          • 谢谢你,Lukas Kallbertodt,最佳答案。我用过: export DANGEROUSLY_DISABLE_HOST_CHECK=true; npm 开始
                          【解决方案17】:

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

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

                          编辑:请注意,此修复不安全。

                          请参阅以下答案以获得安全的解决方案: https://stackoverflow.com/a/43621275/5425585

                          【讨论】:

                          • 这是一个安全问题。改用 public 选项来指定允许的主机名。请参阅medium.com/webpack/… 了解更多信息。
                          • 单独的公共选项对我不起作用... disableHostCheck 是唯一解决它的方法:\
                          • @davidkomer 对我来说也一样。唯一有效的是 disableHostCheck...
                          • 如果你将 webpack 开发服务器用于本地开发以外的任何东西,这是一个安全问题。
                          • 这对我也有用。我的情况是我使用的是 bitnami Multisite Worpdress 安装,在 192.168.0.106.xip.io 上提供服务。奇怪的是,我可以在没有这个“修复”的情况下使用我的旧 Apache Linux 安装。直到我切换到出现此问题的 Bitnami 包。
                          【解决方案18】:

                          更安全的选择是将 allowedHosts 添加到您的 Webpack 配置中,如下所示:

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

                          该数组包含所有允许的主机,您也可以指定子域。 check out more here

                          【讨论】:

                            【解决方案19】:

                            这对我有用:

                            在 webpack.config.js 中的 devServer 下添加 allowedHosts:

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

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

                            【讨论】:

                            • 如果你有 HotModuleReload,似乎 public 参数设置了用作目标的 URL(如果它无法从页面的服务方式中猜到它,对我来说它不能)。
                            【解决方案20】:

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

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

                            【讨论】:

                            【解决方案21】:

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

                            npm run start --public $C9_HOSTNAME
                            

                            并从您的主机名访问应用程序(例如,在终端中输入 $C_HOSTNAME 以获取主机名)

                            【讨论】:

                              猜你喜欢
                              • 2018-10-25
                              • 2017-09-24
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2017-07-04
                              • 2015-10-15
                              • 1970-01-01
                              相关资源
                              最近更新 更多