因此,我有一个连接到我的节点api的小角度应用程序。我的get请求没有问题,我从加载的api中获取数据。我的帖子请求抛出了错误
从源“ http://localhost:3000/api/heroes”到“ http://localhost:4200”的XMLHttpRequest的访问已被CORS策略阻止:Access-Control-Allow-Headers不允许请求标头字段的内容类型在飞行前反应中。
和
ERROR HttpErrorResponse {headers:HttpHeaders,status:0,statusText:“ Unknown Error”,url:“ http://localhost:3000/api/heroes”,ok:false,...}
这是我的@客户端发布方法;
addHero(hero: Hero) {
this.http.post<Hero>("http://localhost:3000/api/heroes", hero)
.subscribe((responseData) => {
console.log(responseData);
})
this.heroes.push(hero); //Adds new hero to original array
this.heroesUpdated.next([...this.heroes]); //Adds new array to subject
}
这是我的后端;
app.use((req,res,next) => {
res.setHeader("Access-Control-Allow-Origin", "localhost");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, DELETE, OPTIONS");
next();
})
app.post("/api/heroes", (req, res,next) => {
const post = req.body;
console.log(post);
res.status(201).json({message:"Succeed"});
});
所以我允许内容类型,但是仍然出现错误。有什么建议如何从这里继续吗?
答案 0 :(得分:1)
您正确理解问题出在CORS。
您的错误是:预检响应中的Access-Control-Allow-Headers不允许请求标头字段的内容类型。
在某些情况下,客户端将向服务器发送“预检请求”。什么时候?
例如,当您的内容类型为“复杂”时。复杂表示不在application/x-www-form-urlencoded
,multipart/form-data
或text/plain
中。
或者在发送带有正文的POST请求时。
还有其他场合,您可以阅读有关此on MDN的更多信息。
预检请求只是带有方法“ OPTIONS”的请求,该请求将到达同一端点。它希望收到一个
成功的响应
允许所有标头
并允许原点。
您的快速中间件app.use((req,res,next) => {...
符合要求2和3。(实际上,对于3,我建议将“ Access-Control-Allow-Origin”标头设置为http://localhost:4200
而不是{{1} })
但是您没有中间件或路由处理程序来处理OPTIONS请求。让我们添加一个:
如果收到OPTIONS请求,则返回200 OK。 如果不是OPTIONS请求,请转到下一个处理程序。
localhost
由于我们希望OPTIONS对ALSO的响应还设置了正确的标头,因此必须在“ cors中间件”的之后中添加它:
app.use((req, res) => {
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
最后,当然有解决方案,例如 npm 上的app.use((req,res,next) => {
// set cors headers and call next()
});
app.use((req, res, next) => {
// handle preflight requests
});
app.post('api/heroes', ...)
软件包,它为 express 提供中间件。检查如何在其npm page上使用它。