Webpack开发服务器CORS问题

77

我正在使用webpack-dev-server v1.10.1来加速我的Redux项目,并且有以下选项:

contentBase: `http://${config.HOST}:${config.PORT}`,
quiet: false,
noInfo: true,
hot: true,
inline: true,
lazy: false,
publicPath: configWebpack.output.publicPath,
headers: {"Access-Control-Allow-Origin": "*"},
stats: {colors: true}
在JS中,我正在使用来自superagent的request生成HTTP GET调用。
request
          .get(config.APIHost + apiUrl)
          .set('Accept', 'application/json')
          .withCredentials()
          .end(function (err, res) {
                if (!err && res.body) {
                    disptach(() => {
                        return {
                            type: actionType || GET_DATA,
                            payload: {
                                response: res.body
                            }
                        }
                    });
                }
          });

但我遇到了CORS错误:

XMLHttpRequest cannot load http://localhost:8000/api/getContentByType?category=all. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5050' is therefore not allowed access
任何解决此问题的建议?非常感谢。
5个回答

104

1
你找到这个内容的链接在哪里了吗? - aks
它在webpack文档中:https://webpack.js.org/configuration/dev-server/#devserver-headers- - jazmit
31
添加这个并没有起作用,没有任何改变。我仍然收到缺少access-control-allow-headers头的错误。 - prk_001
1
通常只需将"Access-Control-Allow-Origin"放在那里就足够了。 - Konstantin Smolyanin
如果您还通过某些重定向(代理,ssh 重定向等)使用浏览器,则使用 devServer 选项 sockPort: 'location',这样套接字端口将使用与位置端口相同的端口,通常足够了。 - Cyrille Pontvieux
@prk_001 请尝试指定允许的主机。在 headers: ... 下,添加 allowedHosts: ["localhost", ".host.com", "host2.com", "subdomain.host3.com"].host.com 条目是该域上任何子域的通配符。您还可以使用 "auto",有关详细信息,请参阅 此处 - ryanjdillon

52

使用webpack-dev-server 1.15.X版本,您可以在配置文件中使用以下配置:

devServer: {
   contentBase: DIST_FOLDER,
   port: 8888,
   // Send API requests on localhost to API server get around CORS.
   proxy: {
      '/api': {
         target: {
            host: "0.0.0.0",
            protocol: 'http:',
            port: 8080
         },
         pathRewrite: {
            '^/api': ''
         }
      }
   }
},

通过这个示例,您可以将所有从http://0.0.0.0:8888/api/*的调用重定向到http://0.0.0.0:8080/*并解决CORS问题。


我认为这是一个有点不同的问题,但显然只需设置 port: 8080 就足够了。我只是想在使用 Vue 时启用“热重载”。无论如何,谢谢! - kcpr
我喜欢这个解决方案,因为据我所见,这个设置最接近典型的生产设置。例如,一个适当的 NGINX 配置同样会将前端和后端统一在同一起源下。 - bluenote10
这适用于我。但是!在我的 API 中,我还使用了 websockets。为了允许 websockets 通过代理传递,请在 '/api' 节点中添加 ws: true - kejm
救了我的一天。谢谢你。 - undefined

17

我遇到了同样的问题,但我的API是基于HTTPS协议的(https://api....)。我必须以HTTPS启动服务器并使用https://localhost:8080。

devServer: {
    https: true,
    headers: {
        "Access-Control-Allow-Origin": "*",
    },
    // ....
}

这正是我正在寻找的!谢谢!! - Crysfel

11

4
第二个链接现在已经失效。 - StingyJack
这是官方文档。 https://webpack.js.org/configuration/dev-server/#devserverproxy - CF_Maintainer

4

针对此问题有两个解决方案。第一个是在客户端设置代理,第二个是在服务器上设置CORS。CORS是服务器问题,服务器不允许来自不同源的访问。即使使用不同的端口也被视为不同的来源。

第一解决方案

在您的后端代码中,您必须设置这些标头:以下示例是在express node.js中

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "OPTIONS, GET, POST, PUT, PATCH, DELETE"
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  next();
});

第二种解决方案:

在webpack的config.js中,如果你想传递任何变量,我们需要导出

module.exports=function(env){
return {}} 

替代

module.exports={}

我们通过脚本注入这个env

"dev-server": "webpack-dev-server --env.api='https://jsonplaceholder.typicode.com/users'",

现在Webpack可以在webpack.config.js中访问这个环境变量。

module.exports = function ({
  api = "https://jsonplaceholder.typicode.com/users",
}) {
  return {
    entry: { main: "./src/index.js" },
    output: {
      path: path.resolve(__dirname, "public"),
      filename: "[name]-bundle.js",
      publicPath: "/",
    },
    mode: "development",
    module: {
      rules: [
        {
          loader: "babel-loader",
          test: /\.js$/,
          exclude: [/node_modules/],
        },
        
        {
          // Load other files, images etc
          test: /\.(png|j?g|gif|ico)?$/,
          use: "url-loader",
        },
        {
          test: /\.s?css$/,
          use: ["style-loader", "css-loader", "sass-loader"],
        },
      ],
    },
    //Some JavaScript bundlers may wrap the application code with eval statements in development.
    //If you use Webpack, using the cheap-module-source-map setting in development to avoid this problem
    devtool: "cheap-module-eval-source-map",
    devServer: {
      contentBase: path.join(__dirname, "public"),
      historyApiFallback: true,
      proxy: {
        "/api": {
          changeOrigin: true,
          cookieDomainRewrite: "localhost",
          target: api,
          onProxyReq: (proxyReq) => {
            if (proxyReq.getHeader("origin")) {
              proxyReq.setHeader("origin", api);
            }
          },
        },
      },
    },
    
  };
};

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