简体   繁体   English

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

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

I am deploying my Angular app and a Postgres Express backend to heroku to allow them to talk with one another.我正在将我的 Angular 应用程序和 Postgres Express 后端部署到 heroku 以允许他们相互交谈。 The big problem that I have now is that whenever I try to use fetch methods, it says that I need CORS enabled or a heading for it.我现在遇到的一个大问题是,每当我尝试使用 fetch 方法时,它都会说我需要启用 CORS 或指向它。 I already set it up in my express backend below:我已经在下面的快递后端设置了它:

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}`)});

I think my code is fine for the backend, so I feel that the Angular code is the problem, but I don't understand how to fix it.我认为我的代码对于后端来说很好,所以我觉得 Angular 代码是问题所在,但我不明白如何修复它。 Do I have to manually add a header for each fetch method done to have the CORS feature, or do I have to use some sort of proxy that I found but was too confused how to do it?我是否必须为每个获取方法手动添加 header 才能具有 CORS 功能,或者我是否必须使用某种我找到但太困惑如何做的代理?

An example of a fetch method I did is below:我做的一个 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');
        }
      });

Also for deploying the angular part, I followed this guide: https://youtu.be/KVFrTf4VD2o I just thought it might be important since it uses an express server to give the files instead of doing ng serve after building the app.同样为了部署 angular 部分,我遵循了本指南: https://youtu.be/KVFrTf4VD2o我只是认为这可能很重要,因为它使用快速服务器来提供文件而不是在构建应用程序后执行 ng serve 。

Edit: For the CORS error: Access to fetch at 'https://app-backend.herokuapp.com/register' from origin 'https://app-project.herokuapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.编辑:对于 CORS 错误:CORS 策略已阻止从源“https://app-project.herokuapp.com”获取“https://app-backend.herokuapp.com/register”的访问权限:否' Access-Control-Allow-Origin' header 存在于请求的资源上。 If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

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

It's possible that your server is just not ready to handle pre-flight requests.您的服务器可能还没有准备好处理飞行前请求。 You don't seem to have any route that handles the OPTIONS HTTP method which a pre-flight request would be.您似乎没有任何路线可以处理飞行前请求的 OPTIONS HTTP 方法。 Express' documentation on CORS has an example on how to handle pre-flight requests关于 CORS 的 Express 文档有一个关于如何处理飞行前请求的示例

The simplest way to enable it on all requests, as per the documentation, would be to configure a route that handles OPTIONS as such:根据文档,在所有请求上启用它的最简单方法是配置一个处理 OPTIONS 的路由,如下所示:

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

I was able to figure out how to solve my problem.我能够弄清楚如何解决我的问题。 @WiktorZychla's comment was correct in that any request with credentials will cause * to not work. @WiktorZychla 的评论是正确的,因为任何带有凭据的请求都会导致 * 不起作用。 Source To fix this, I found another discussion where they put: 来源为了解决这个问题,我发现了另一个讨论,他们把:

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`))
      }
    }
  }));

You first create an allowedOrigins array to put any urls that you use to access the API.您首先创建一个 allowedOrigins 数组来放置用于访问 API 的任何 url。 Then you let your server use a cors object that allows credentials and then checks the origin of the request.然后您让您的服务器使用允许凭据的 cors object,然后检查请求的来源。 If the origin exists in the array, then it will return a callback that allows each request to work.如果原点存在于数组中,那么它将返回一个允许每个请求工作的回调。

Also if you have separate routes like I do below:此外,如果您有单独的路线,如下所示:

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);

Then in each route file, you need to copy the cors info I have at the top and change it so that each router has cors configured.然后在每个路由文件中,您需要复制我在顶部的 cors 信息并进行更改,以便每个路由器都配置了 cors。 There may be another solution, but this was the fastest for me.可能还有另一种解决方案,但这对我来说是最快的。

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

相关问题 CORS angular 应用程序上的预检请求错误部署在 heroku 上,带有节点快递后端 - CORS preflight request error on angular app deployed on heroku with node express backend 如何使用 Heroku 上的 Angular App 解决 CORS 问题 - How to solve CORS problem with my Angular App on Heroku 使用 angular 9 部署在 heroku 上的 nodejs 应用程序中出现 CORS 错误 - CORS error in nodejs app deployed on heroku using with angular 9 我在 Heroku 上部署了我的应用程序,但后来我遇到了 cors 问题 - I deployed my app on Heroku but then I have cors problems 如何在 Heroku 上运行此节点快速应用程序? - How do I run this node express app on Heroku? 如何在不使用Express的情况下将节点应用部署到heroku - How do I deploy node app to heroku without using Express 部署到 Heroku 的 Nodejs Ionic-Angular 仅显示后端,而不是启动整个应用程序 - Nodejs Ionic-Angular deployed to Heroku displays only the backend, instead of launching the whole app 在 heroku 上部署 express 应用程序时无法获取/ - Cannot Get/ when express app is deployed on heroku 反应节点快递应用程序 - Heroku CORS 错误 - React node express app - Heroku CORS error 我是否需要 node.js(快递)将 Angular 应用程序部署到 Heroku? - Do I need node.js (express) to deploy an Angular App to Heroku?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM