不允许访问控制允许标题

时间:2019-02-14 21:25:32

标签: node.js angular cors http-headers

因此,我有一个连接到我的节点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"});
});

所以我允许内容类型,但是仍然出现错误。有什么建议如何从这里继续吗?

1 个答案:

答案 0 :(得分:1)

您正确理解问题出在CORS。

您的错误是:预检响应中的Access-Control-Allow-Headers不允许请求标头字段的内容类型。

在某些情况下,客户端将向服务器发送“预检请求”。什么时候?

例如,当您的内容类型为“复杂”时。复杂表示不在application/x-www-form-urlencodedmultipart/form-datatext/plain中。

或者在发送带有正文的POST请求时。

还有其他场合,您可以阅读有关此on MDN的更多信息。

预检请求只是带有方法“ OPTIONS”的请求,该请求将到达同一端点。它希望收到一个

  1. 成功的响应

  2. 允许所有标头

  3. 并允许原点。

您的快速中间件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上使用它。