不允许访问控制允许标头

Posted

技术标签:

【中文标题】不允许访问控制允许标头【英文标题】:Access-control-allow-headers isn't allowed 【发布时间】:2019-07-09 00:05:46 【问题描述】:

所以我有一个小角度应用程序连接到我的节点 api。我的获取请求没有问题,我在加载时从我的 api 获取数据。我的发布请求引发了错误;

从源“http://localhost:4200”对“http://localhost:3000/api/heroes”处的 XMLHttpRequest 的访问已被 CORS 策略阻止:在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段内容类型。

ERROR HttpErrorResponse headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://localhost:3000/api/heroes", 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

这是我的后端;

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

所以我已经允许 content-type 但我仍然收到错误。有什么建议可以从这里继续吗?

【问题讨论】:

【参考方案1】:

您正确理解问题在于 CORS。

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

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

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

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

还有其他场合,你可以阅读更多关于这个on MDN的内容。

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

    成功响应

    允许所有标题

    并允许原点。

您的 express 中间件 app.use((req,res,next) =&gt; ... 符合要求 2 和 3。(实际上对于 3,我建议将“Access-Control-Allow-Origin”标头设置为 http://localhost:4200 而不仅仅是 localhost

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

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

app.use((req, res) => 
    if (req.method === 'OPTIONS') 
        return res.sendStatus(200);
    
    next();
);

由于我们希望对 ALSO 的 OPTIONS 响应设置正确的标头,因此我们必须将其包含在 “cors 中间件”之后:

app.use((req,res,next) => 
// set cors headers and call next()
);

app.use((req, res, next) => 
// handle preflight requests
);

app.post('api/heroes', ...)

最后,当然有现成的解决方案,例如 npm 上的 cors 包,它为 express 提供中间件。在其npm page 上查看如何使用它。

【讨论】:

非常感谢。接受并赞成。当您不仅被告知要做什么,而是被告知实际发生了什么时,这真是太神奇了。真的很辛苦

以上是关于不允许访问控制允许标头的主要内容,如果未能解决你的问题,请参考以下文章

如何避免“访问控制允许标头不允许请求标头字段授权”从本地驱动器运行 JavaScript? [复制]

SEC7123:访问控制允许标头列表中不存在请求标头密钥

ionic 2 没有“访问控制允许来源”标头

访问控制允许 Origin 标头不存在于 fetch api 调用中

本地主机已被 cors 策略请求标头字段内容类型阻止访问控制不允许

HTTP响应标头中“允许”和“访问控制允许方法”之间的区别?