使用 express 提供角度服务时出现 CORS 错误

Posted

技术标签:

【中文标题】使用 express 提供角度服务时出现 CORS 错误【英文标题】:CORS error when serving angular with express 【发布时间】:2020-05-30 13:43:30 【问题描述】:

我有 2 个 server.js 文件。其中之一位于后端文件夹中,当我在 localhost:3000 上运行 nodemon server.js 时。我将在 Angular 文件夹中使用 ng serve 开始 Angular 并登录到我的应用程序没问题。一切正常。没有 CORS 问题。

但是

如果我尝试在 express 为我的 angular build 文件夹提供服务的根目录中运行我的 server.js 文件。它在 localhost:8080 上启动,但是当我尝试登录我的应用程序时,我得到了

在我的 app.js 文件中,我有以下内容,应该是相关的。还有一点值得注意 是我制作了一个 docker 版本,那个版本也给了我 CORS 错误。所以它似乎只在使用 ng serve 和 nodemon server.js 在本地运行时才有效

app.use((req, res, next) => 
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept, Authorization"
  );
  res.header(
    "Access-Control-Allow-Methods",
    "GET, POST, PATCH, PUT, DELETE, OPTIONS"
  );

  next();
);

后端文件夹中的 server.js 文件(localhost:3000 无 CORS 错误)

const app = require("./app");
const debug = require("debug")("node-angular");
const http = require("http");
const mongoose = require("mongoose");
var redis = require("redis");

var env = require("dotenv").config();


const normalizePort = val => 
  var port = parseInt(val, 10);

  if (isNaN(port)) 
    e;
    // named pipe
    return val;
  

  if (port >= 0) 
    // port number
    return port;
  

  return false;
;

const onError = error => 
  if (error.syscall !== "listen") 
    throw error;
  
  const bind = typeof port === "string" ? "pipe " + port : "port " + port;
  switch (error.code) 
    case "EACCES":
      console.error(bind + " requires elevated privileges");
      process.exit(1);
      break;
    case "EADDRINUSE":
      console.error(bind + " is already in use");
      process.exit(1);
      break;
    default:
      throw error;
  
;
console.log("process.env.COSMODDB_USER");
console.log(env.COSMODDB_USER);
mongoose
  .connect(
    "mongodb://" +
      process.env.COSMOSDB_HOST +
      ":" +
      process.env.COSMOSDB_PORT +
      "/" +
      process.env.COSMOSDB_DBNAME +
      "?ssl=true&replicaSet=globaldb",
    
      auth: 
        user: process.env.COSMODDB_USER,
        password: process.env.COSMOSDB_PASSWORD
      
    
  )
  .then(() => console.log("Connection to CosmosDB successful"))
  .catch(err => console.error(err));

const onListening = () => 
  const addr = server.address();
  const bind = typeof port === "string" ? "pipe " + port : "port " + port;
  debug("Listening on " + bind);
;

const port = normalizePort(process.env.PORT || "3000");
app.set("port", process.env.PORT || port);

var server = app.listen(app.get("port"), function() 
  debug("Express server listening on port " + server.address().port);
);

根目录中的server.js(localhost:8080 CORS 错误)

var express    = require('express');
var app        = express();
var bodyParser = require('body-parser');
var morgan     = require('morgan');
const userRoutes = require("./app/routes/user");
const appRoutes = require("./app/app");

const cors = require("cors");
app.use(morgan('dev'));


app.use(cors( origin: 'http://localhost:8080' , credentials :  true));var mongoose   = require('mongoose');
var path       = require('path');
var config = 'mongodb://azure45:azure45@ds133321.mlab.com:33321/azure_chat'
//const app = require("./app");
const debug = require("debug")("node-angular");
var env = require("dotenv").config();

app.use(bodyParser.urlencoded( extended: true ));
app.use(bodyParser.json());

app.use(function(req, res, next) 
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
    next();
);


mongoose
  .connect(
    "mongodb://" +
      process.env.COSMOSDB_HOST +
      ":" +
      process.env.COSMOSDB_PORT +
      "/" +
      process.env.COSMOSDB_DBNAME +
      "?ssl=true&replicaSet=globaldb",
    
      auth: 
        user: process.env.COSMODDB_USER,
        password: process.env.COSMOSDB_PASSWORD
      
    
  )
  .then(() => console.log("Connection to CosmosDB successful"))
  .catch(err => console.error(err));

app.use(express.static(__dirname + '/public/dist/glass/'));

//var apiRoutes = require('./app/app')(app, express);
app.use("/api/", appRoutes);
app.use("/api/user", userRoutes);

app.get('*', function(req, res) 
    res.sendFile(path.join(__dirname + '/public/dist/glass/index.html'));
);

app.listen(8080);
console.log('Magic happens on port ' + 8080);




const normalizePort = val => 
  var port = parseInt(val, 10);

  if (isNaN(port)) 
    e;
    // named pipe
    return val;
  

  if (port >= 0) 
    // port number
    return port;
  

  return false;
;

const onError = error => 
  if (error.syscall !== "listen") 
    throw error;
  
  const bind = typeof port === "string" ? "pipe " + port : "port " + port;
  switch (error.code) 
    case "EACCES":
      console.error(bind + " requires elevated privileges");
      process.exit(1);
      break;
    case "EADDRINUSE":
      console.error(bind + " is already in use");
      process.exit(1);
      break;
    default:
      throw error;
  
;
console.log("process.env.COSMODDB_USER");
console.log(env.COSMODDB_USER);


const onListening = () => 
  const addr = server.address();
  const bind = typeof port === "string" ? "pipe " + port : "port " + port;
  debug("Listening on " + bind);
;



这是项目文件结构作为参考。 app.js 是我所有 API 所在的地方。

【问题讨论】:

【参考方案1】:

尝试使用 Node.js CORS library 进行 CORS。

如下所示。

const express = require("express");

const cors = require("cors");

const app = express();

app.use(cors());

【讨论】:

我安装了库并将代码添加到我的 app.js 文件中,但同样的问题【参考方案2】:

参考rise的回答: 为 cors 方法添加选项:

var corsOptions = 
origin: 'your client url',
optionsSuccessStatus: 200,

app.use(cors(corsOptions));

【讨论】:

以上是关于使用 express 提供角度服务时出现 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

尝试将数据从角度项目发布到 Spring Web 服务项目时出现 CORS 错误

将 Vue.js 用于客户端,将 Express 用于服务器端时出现“Access-Control-Allow-Origin”CORS 问题

在使用 node.js 和 Express 构建的 api 中使用 cors 中间件时出现 CORS 错误

在 React/Express 中使用 PassportJS 进行 Google OAuth 时出现 CORS 错误

在角度应用程序中使用 SignalR Core 时出现 CORS 错误

在部署的 AWS 环境中使用 cookie 时出现 CORS 问题