Node.js 访问控制允许标头是';不允许

Node.js 访问控制允许标头是';不允许,node.js,angular,cors,http-headers,Node.js,Angular,Cors,Http Headers,所以我有一个小的angular应用程序,它连接到我的节点api。我的get请求没有问题,我从加载的api中获取数据。我的post请求抛出一个错误tho CORS策略已阻止从源“”访问“”处的XMLHttpRequest:飞行前响应中的访问控制允许标头不允许请求标头字段内容类型 及 错误HttpErrorResponse{headers:HttpHeaders,状态:0,状态文本:“未知错误”,url:,ok:false,…} 这是我的post方法@客户端 addHero(hero: Hero)

所以我有一个小的angular应用程序,它连接到我的节点api。我的get请求没有问题,我从加载的api中获取数据。我的post请求抛出一个错误tho

CORS策略已阻止从源“”访问“”处的XMLHttpRequest:飞行前响应中的访问控制允许标头不允许请求标头字段内容类型

错误HttpErrorResponse{headers:HttpHeaders,状态:0,状态文本:“未知错误”,url:,ok:false,…}

这是我的post方法@客户端

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
}

所以我允许使用内容类型,但仍然会出现错误。有什么建议可以让我们继续前进吗

您正确理解问题在于CORS

您的错误是:飞行前响应中的访问控制允许标头不允许请求标头字段内容类型

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

例如,当您的内容类型为“复杂”时。复杂表示不在
应用程序/x-www-form-urlencoded
多部分/表单数据
文本/普通

或者当你发送一个带有主体的POST请求时

还有其他场合,你可以阅读更多关于这方面的内容

飞行前请求只是一个带有方法“OPTIONS”的请求,该方法指向同一个端点。它希望收到一份回执

  • 成功响应

  • 允许所有标题

  • 并允许原点

  • 您的快速中间件
    app.use((req,res,next)=>{…
    勾选需求2和3。(实际上,对于3,我建议将“访问控制允许来源”标题设置为
    http://localhost:4200
    而不仅仅是
    localhost

    但是您没有中间件或路由处理程序来处理选项请求。让我们添加一个:

    如果我们收到一个选项请求,我们将返回一个200 OK。 如果不是选项请求,请转到下一个处理程序

    app.use((req, res) => {
        if (req.method === 'OPTIONS') {
            return res.sendStatus(200);
        }
        next();
    });
    
    由于我们希望选项响应也设置正确的标题,因此必须在“cors中间件”之后包含它:


    最后,当然还有一些现成的解决方案,例如npm上的
    cors
    包,它为express提供了一个中间件。检查如何在its上使用它。

    非常感谢。接受并投票通过。当你不只是被告知要做什么,而是实际发生了什么时,这真是太神奇了。真的很难接受它
    app.use((req, res) => {
        if (req.method === 'OPTIONS') {
            return res.sendStatus(200);
        }
        next();
    });
    
    app.use((req,res,next) => {
    // set cors headers and call next()
    });
    
    app.use((req, res, next) => {
    // handle preflight requests
    });
    
    app.post('api/heroes', ...)