这个CORS再次让我跪倒在地。我的意思是它可以令人沮丧。在你投票给我之前,请理解我一直关注这个主题的所有500万个帖子。我意识到这个主题有很多。这是我的React UI代码中的Fetch Post。这是在带有已编译JS的IIS服务器上运行的,而且只是用于SPA的Index.html。我试图在同一服务器上调用API不同的端口。这是在Chrome和其他现代浏览器中杀死我的预检(在IE中似乎很好)。
这是获取:
return (
fetch(mypost, {
method: 'POST',
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Accept": "application/json",
},
mode: 'cors',
body: JSON.stringify({
name: this.state.value,
})
}).then(response => {
if (response.status >= 400) {
this.setState({
value: 'no greeting - status > 400'
});
throw new Error('no greeting - throw');
}
return response.text()
}).then(data => {
var myData = JSON.parse(data);
this.setState({
greeting: myData.name,
path: myData.link
});
}).catch(() => {
this.setState({
value: 'no greeting - cb catch'
})
})
);
标准的预见错误我们都看到了。
Fetch API无法加载http://myApiServer:81/values/dui/。对预检请求的响应没有通过访问控制检查:否'访问控制 - 允许 - 来源'标头出现在请求的资源上。起源' http://localhost:82'因此不允许访问。如果不透明的回复符合您的需求,请将请求的模式设置为“无人”状态。获取CORS禁用的资源。
这是预检的小提琴:
OPTIONS http://myApiServer:81/values/dui/ HTTP/1.1
Host: myApiServer:81
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:82
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Access-Control-Request-Headers: access-control-allow-origin, content-type
Accept: */*
Referer: http://localhost:82/validator
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
现在我已经了解到设置no-cors基本上会设置一个默认标头,这也不是我想要的,我需要我的应用程序/ json,因为谁不想要JSON,对吧? :)
我很想知道如何解决这个问题。基本上,因为这只是编译Javascript和index.html坐在IIS服务器上,我需要知道处理这些似乎正在发生的预检选项检查的最佳解决方案。
******更新
我尝试添加webconfig以强制IIS服务器处理预检。它似乎需要在两端,我的UI和API?
这是我的UI Web.Config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
我的WebApi web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
</customHeaders>
</httpProtocol>
<aspNetCore processPath="dotnet" arguments=".\dui.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true" />
</system.webServer>
</configuration>
我现在所有人都是:
fetch API无法加载http://myApiServer:81/values/dui/。预检的响应具有无效的HTTP状态代码415。
这是小提琴。
REQ
OPTIONS http://myApiServer:81/values/dui/ HTTP/1.1
Host: myApiServer:81
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:82
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: http://localhost:82/validator
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
并回复
HTTP/1.1 415 Unsupported Media Type
Content-Length: 0
Server: Kestrel
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Date: Thu, 02 Mar 2017 18:35:31 GMT
答案 0 :(得分:2)
我已经为我的dotnet核心webAPi切换到这个解决方案。我发现它更干净,因为我不需要webconfig加上cors配置,需要设置正确的2才能一起工作。这消除了你的webConfig中的cors东西,所以你只能在一个地方设置它,在你的API应用程序代码本身。
https://www.codeproject.com/Articles/1150023/Enable-Cross-origin-Resource-Sharing-CORS-in-ASP-N
只是简要概述一下链接中的内容。
添加到project.json
//Cross Origin Resource Sharing
"Microsoft.AspNetCore.Cors": "1.0.0"
在启动时将此添加到您的ConfigureServices。
services.AddCors(
options => options.AddPolicy("AllowCors",
builder =>
{
builder
//.WithOrigins("http://localhost:4456") //AllowSpecificOrigins;
//.WithOrigins("http://localhost:4456",
"http://localhost:4457") //AllowMultipleOrigins;
.AllowAnyOrigin() //AllowAllOrigins;
//.WithMethods("GET") //AllowSpecificMethods;
//.WithMethods("GET", "PUT") //AllowSpecificMethods;
//.WithMethods("GET", "PUT", "POST") //AllowSpecificMethods;
.WithMethods("GET", "PUT",
"POST", "DELETE") //AllowSpecificMethods;
//.AllowAnyMethod() //AllowAllMethods;
//.WithHeaders("Accept", "Content-type", "Origin", "X-Custom-Header");
//AllowSpecificHeaders;
.AllowAnyHeader(); //AllowAllHeaders;
})
);
还可以在启动时配置
//Enable CORS policy "AllowCors"
app.UseCors("AllowCors");
然后在你的控制器中确保你有这些参考:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Cors;
using CrossOrigin.WebService.Models.DbEntities;
using Microsoft.EntityFrameworkCore;
最后将属性添加到控制器类中。
[EnableCors("AllowCors"), Route("api/[controller]")]
public class ContactController : Controller
答案 1 :(得分:2)
我现在已经摸不着头脑了2个小时,最后找到了一个适合我案例的解决方案。如果你和我一样处于同样的境地,我希望我的回答可以帮助你节省这些时间。由于我可以控制Web API(aspnet core
)和客户端(fetch
),因此我执行了以下操作:
现在我们了解了一些关于CORS的内容,请在Startup.cs
文件中执行以下操作:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment environment)
{
app.UseCors(builder =>
{
builder.WithOrigins("http://yourclient/");
builder.AllowAnyMethod();
builder.AllowAnyHeader();
});
app.UseMvc();
}
现在在客户端,执行此操作:
fetch("http://yourapi/api/someresource", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Access-Control-Request-Headers": "*",
"Access-Control-Request-Method": "*"
},
body: JSON.stringify(data)
})...;
就是这样。
答案 2 :(得分:2)
正如某人建议的是另一篇文章,假设您未使用Nodejs,请在服务器端执行此操作。请注意,我遇到类似问题的客户端是Reactjs驱动的,这使我们什至
app.use(函数(req,res,next){
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
答案 3 :(得分:1)
所以我要发布这个答案,因为它现在实际上对我有用。这是我经历的。我不完全确定为什么,但我会尽力解释我在这路上学到的东西。如果有人关心纠正或进一步解释,我将很乐意给予信任和支持。
因此,似乎在API中有3层CORS认知。
第1层
API本身的代码将有一些CORS设置,你应该特别注意,你一定要仔细阅读。在我的例子中,标准位置在webApi的Startup.cs中。我总是在我的WebApi中有这些,坦率地说,我认为这是最初需要的(我知道的很少)。
services.AddCors();
app.UseCors(builder => builder.AllowAnyOrigin())
我也将它设置在我的webconfig中,它将我们带到:
第2层
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
</customHeaders>
我使用这个是因为一个聪明人说(感谢@sideshowbarker)我的React UI中的Fetch生成了一个自定义标题,因此在我的服务器上产生了预检响应,因此需要在服务器级别处理响应
第3层
所以第3层结果确实不是我的问题,但在这个过程中你必须要注意这一点。所以不是在API代码中,不是在服务器上,而是在UI(调用应用程序)本身。
一般来说,除了"Access-Control-Allow-Origin": "*"
之外,我在这里有正确的东西,这显然在这里并不需要所有地方,因为这是响应标题,而在fetch中我指定了请求标题,再次感谢@sideshowbarker。
所以我的Fetch请求如下所示:
fetch(mypost, {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
mode: 'cors',
body: JSON.stringify({
name: this.state.value,
})
})
在我的案例中,主要是因为我'context-type: application/json'
导致了预检反应。我想这不标准。在我们这个世界里,对我来说似乎很标准,但我知道什么。
无论如何,尽管如此,我还是得到了以下信息,坦率地说比看到预检错误更好。进步是进步。
Access-Control-Allow-Origin'标头包含多个值'*,*', 但只允许一个。
我在网上发现了一些提到我在两个地方都不需要AllowAnyOrigin
的东西(网络服务器和API)所以我试着评论这段代码。
//app.UseCors(builder => builder.AllowAnyOrigin());
得到了:
Fetch API无法加载
http://ApiServer:81/values/dui/
。回应 预检具有无效的HTTP状态代码415
然后根据一些搜索发现一篇文章说最后一个错误可能与标题相关。我回到API源dotnet Core cors。
https://docs.microsoft.com/en-us/aspnet/core/security/cors
这是一个很好的参考。我应该更加关注这一点。它并没有完全解决我的问题,但我注意到有另一个我可以用于标题的构建器,所以我插入,重建,发布和bam,没有更多的CORS问题。一切正常!
这是我插入API的代码:
app.UseCors(builder => builder.AllowAnyHeader());
我的所有其余代码在第2层和第3层保持不变。我将第1层API中的AllowAnyOrigin
构建器留下了注释。
我很遗憾在这里过于冗长,但我发现CORS很痛苦,我希望这对某人有所帮助。我想现在是Coors的时候了,但我想我们都知道啤酒很糟糕。我想这毕竟是有道理的。