繁体   English   中英

对于部署在 heroku 上的 Angular 应用程序,我该如何处理 CORS 问题?

[英]How do I deal with CORS problem for Angular app deployed on heroku with a Postgres express backend?

我正在将我的 Angular 应用程序和 Postgres Express 后端部署到 heroku 以允许他们相互交谈。 我现在遇到的一个大问题是,每当我尝试使用 fetch 方法时,它都会说我需要启用 CORS 或指向它。 我已经在下面的快递后端设置了它:

const app = express();
const cors = require('cors');
const port = process.env.PORT || 5000;
const Pool = require('pg').Pool;
const transRoutes = require('./transactions');
const groupsRoutes = require('./budget-group');
const itemsRoutes = require('./budget_item');
const accRoutes = require('./account');

app.use(cors({origin: '*'})); //I also tried cors()
app.use(express.json());
app.use('/transactions', transRoutes);
app.use('/groups', groupsRoutes);
app.use('/items', itemsRoutes);
app.use('/accounts', accRoutes);
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
 })

const pool = new Pool({
    connectionString: process.env.DATABASE_URL,
    ssl: {
        rejectUnauthorized: false
    }
});

app.get('/', (req, res) => {
    res.send('Welcome to your server.');
});

app.get('/users', async (req, res) => {
    try {
        const getAllUsers = await pool.query("SELECT * FROM users");
        res.json(getAllUsers);
    } catch (err) {
        console.log(err);
    }
});

app.get('/login/:username/:password', async (req, res) => {
    try {
        const getUser = await pool.query("SELECT * FROM users WHERE username = $1 AND password = $2",
        [
            req.params.username,
            req.params.password
        ]);
        res.json(getUser.rows);
    } catch (err) {
        console.log(err);
    }
});

//More routes omitted for brevity

app.listen(port, () => {console.log(`Listening on port ${port}`)});

我认为我的代码对于后端来说很好,所以我觉得 Angular 代码是问题所在,但我不明白如何修复它。 我是否必须为每个获取方法手动添加 header 才能具有 CORS 功能,或者我是否必须使用某种我找到但太困惑如何做的代理?

我做的一个 fetch 方法的例子如下:

fetch(`https://name-redacted.herokuapp.com/login/${this.username}/${this.password}`, {
        method: 'GET',
        headers: {'Content-Type': 'application/json'}
      }).then(res => res.json())
      .then(info => {
        if (info.length === 0) {
          this.failedAuth = true;
        } else {
          this.infoService.setUpLoginInfo(info[0]);
          this.router.navigateByUrl('/instructions');
        }
      });

同样为了部署 angular 部分,我遵循了本指南: https://youtu.be/KVFrTf4VD2o我只是认为这可能很重要,因为它使用快速服务器来提供文件而不是在构建应用程序后执行 ng serve 。

编辑:对于 CORS 错误:CORS 策略已阻止从源“https://app-project.herokuapp.com”获取“https://app-backend.herokuapp.com/register”的访问权限:否' Access-Control-Allow-Origin' header 存在于请求的资源上。 如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

标头:Access-Control-Allow-Headers:Origin、X-Requested-With、Content-Type、Accept Access-Control-Allow-Methods 未显示。

您的服务器可能还没有准备好处理飞行前请求。 您似乎没有任何路线可以处理飞行前请求的 OPTIONS HTTP 方法。 关于 CORS 的 Express 文档有一个关于如何处理飞行前请求的示例

根据文档,在所有请求上启用它的最简单方法是配置一个处理 OPTIONS 的路由,如下所示:

app.options('*', cors())

我能够弄清楚如何解决我的问题。 @WiktorZychla 的评论是正确的,因为任何带有凭据的请求都会导致 * 不起作用。 来源为了解决这个问题,我发现了另一个讨论,他们把:

const allowedOrigins = ['https://someapp.com'];
app.use(cors({
    credentials: true,
    origin: (origin, callback) => {
      if (allowedOrigins.includes(origin)) {
        callback(null, true) 
      } else {
        callback(new Error(`Origin: ${origin} is now allowed`))
      }
    }
  }));

您首先创建一个 allowedOrigins 数组来放置用于访问 API 的任何 url。 然后您让您的服务器使用允许凭据的 cors object,然后检查请求的来源。 如果原点存在于数组中,那么它将返回一个允许每个请求工作的回调。

此外,如果您有单独的路线,如下所示:

const transRoutes = require('./transactions');
const groupsRoutes = require('./budget-group');
const itemsRoutes = require('./budget_item');
const accRoutes = require('./account');
app.use('/transactions', transRoutes);
app.use('/groups', groupsRoutes);
app.use('/items', itemsRoutes);
app.use('/accounts', accRoutes);

然后在每个路由文件中,您需要复制我在顶部的 cors 信息并进行更改,以便每个路由器都配置了 cors。 可能还有另一种解决方案,但这对我来说是最快的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM