我们有以下设置:
Front end code : REACT (Hosted using express js) (lets call this www.domainA.com)
Backend : .NET WEB API (Hosted in IIS 7.5) (lets call this www.domainB.com)
FE应用程序的域正在向Web api发出GET数据和POST数据的请求。
GET工作正常,但每当我尝试将数据发布到Web API时,都会抛出以下错误:
Request URL: http://www.domainB.com/api/postdataoperation
Request Method: OPTIONS
Status Code: 403 Forbidden
我查看了许多CORS文章,并继续在IIS中设置HTTPResponseHeaders,如下所示:
Access-Control-Allow-Methods : POST,GET,OPTIONS,PUT,DELETE
Access-Control-Allow-Origin : http://www.domainA.com
反应解决方案的发布请求如下:
axios.post(`http://www.domainB.com/api/postdataoperation`, {userId});
答案 0 :(得分:4)
问题是您的服务器未配置为以正确的响应状态 2xx成功状态响应 OPTIONS 请求。
GET正在运行,因为它没有发出预检请求,因为它符合simple request
定义的CORS documentation标准另一方面,POST请求符合条件Preflighted request,这意味着应首先进行预检OPTIONS请求。
简而言之,您已正确设置了CORS响应标头,但服务器未配置为响应OPTIONS方法请求的 2xx响应(通常为200状态)。
服务器必须以2xx成功状态(通常为200或204)响应OPTIONS请求。
如果服务器不这样做,那么它配置为发送的Access-Control- *标头没有区别。配置服务器以正确方式处理OPTIONS请求的答案 - 发送200或204成功消息 - 取决于它运行的服务器软件
从this answer借用解决方案,在你的后端.NET WEB API上执行此操作:
在 BaseApiController.cs :
中我们这样做是为了允许OPTIONS http动词
public class BaseApiController : ApiController
{
public HttpResponseMessage Options()
{
return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}
}
response for preflight 403 forbidden
在domainA.com上运行nodejs服务器是无关紧要的。 "axios"库可以用于a)从浏览器生成XMLHttpRequests或b)从node.js发出http请求。在这种情况下,它是第一个选项," axios.post"到domainB是通过浏览器的 XMLHttpRequest 完成的,这就是你在domainB.com上获得预检请求的原因。
答案 1 :(得分:0)
POST请求失败时.NET Web API的输出是什么?
答案 2 :(得分:0)
Jannes Botis的回答很好地解释了Preflighted机制。我只是添加了我用来解决Node.js / Express
上的这个问题的代码const express = require('express');
const app = express();
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://www.domainA.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
res.setHeader(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
next();
});
// All OPTIONS requests return a simple status: 'OK'
app.options('*', (req, res) => {
res.json({
status: 'OK'
});
});
app.get('/', ...);
app.post('/api/postdataoperation', ...);