我的一个ASP。NET Web API控制器。我的客户端应用程序返回了以下错误:
对飞行前请求的响应未通过访问控制检查:"Access Control Allow Origin"标头包含多个值"*,*",但只允许一个。原点'http://localhost:8100因此不允许访问。
我认识到发生此错误是因为标头包含多个值。当通过Chrome调用API时,我可以在"响应头"中看到这一点,它看起来像这样:
HTTP/1.1 200 OK
缓存控制:无缓存
内容长度:0
服务器:Microsoft IIS/8.0
访问控制允许方法:GET、POST
访问控制允许来源:*
访问控制允许标头:内容类型,接受,Pragma,缓存控制、授权
访问控制最大年龄:1728000
X-Powered-Bor:ASP。净
访问控制允许来源:*
访问控制允许方法:GET、POST、OPTIONS、PUT、DELETE
访问控制允许标头:原始、X-Requested-Wise、内容类型、,接受、授权
设置Cookie:ARRAfinity=ef9b3770b61f10f9696b0dedcb39a7f47a83c0e4d6cdbf367f314982592ef06;路径=/;HttpOnly;域名=seirse.azurewebsites.net
正如你所看到的,它显然存在两次。
我遇到的问题是,我唯一启用CORS的地方是通过我的应用程序中的web.config,例如
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization" />
</customHeaders>
</httpProtocol>
我已经100%确定我没有通过Startup.cs或在控制器中启用CORS。
据我所见,控制器没有什么异常:
// GET: api/Address/all
[HttpGet]
public AddressResultModel All()
{
try
{
var userId = _accountService.GetUserId(Request);
return _customerRepository.GetAddresses(userId);
}
catch (Exception)
{
return null;
}
}
有什么想法吗?
原来我的Global.asax.cs中有代码,它正在为OPTIONS HTTP请求的响应添加标头。
我添加此代码的原因是由于另一个问题,即我收到OPTIONS HTTP请求的"405方法不允许"错误消息。
为了解决这两个问题,我删除了添加额外标题的代码,并将其精简为:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin", StringComparer.CurrentCultureIgnoreCase)
&& Request.HttpMethod == "OPTIONS")
{
Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Pragma, Cache-Control, Authorization ");
Response.End();
}
}
我不知道为什么这样可以解决问题。
在我的情况下,我收到了这个错误,因为我的端点直接从另一个请求返回了响应,因此我的cors过滤器使用现有过滤器向接收到的响应添加了新的头:
@GetMapping
public ResponseEntity getOmdbSearch(@RequestParam Map<String, String> requestParamMap, Principal principal) {
... ... ...
// Here an error !
return restTemplate.getForEntity(uriComponentsBuilder.toUriString(), String.class);
}
我通过只返回结果修复了它:
@GetMapping
public String getOmdbSearch(@RequestParam Map<String, String> requestParamMap,
Principal principal) {
ResponseEntity<String> response = restTemplate.getForEntity(uriComponentsBuilder.toUriString(), String.class);
return response.getBody();
}