[英]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.