我正在使用Angular JS构建SPA应用程序,而后端是使用bearer令牌的asp.net WebAPI。我有一个有趣的问题,应用程序在我的本地机器上工作正常,但当我上传到azure网站时,我突然收到一个CORS错误,我不确定根本原因。有趣的是,我可以正常登录应用程序,获取持票人令牌,但我无法访问任何控制器方法。下面的代码显示了localhost,但是当我上传到Azure网站时,显然会替换服务名称。
我得到的错误是
"XMLHttpRequest cannot load https://tradesservice.azurewebsites.net/api/OpenPnL. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://perseus1.azurewebsites.net' is therefore not allowed access. The response had HTTP status code 500."
Perseus1当然是我的角应用程序和tradesservice是我的后端API。
发出请求的代码如下:
perseusApp.factory('openpnlData', function ($resource,currentUser) {
return $resource('http://localhost:36080/api/OpenPnL/:id', null,
{
'get': {
headers: { 'Authorization': 'Bearer ' + currentUser.getProfile().token },
isArray: true
},
'save': {
headers: { 'Authorization': 'Bearer ' + currentUser.getProfile().token }
},
'update': {
method: 'PUT',
headers: { 'Authorization': 'Bearer ' + currentUser.getProfile().token }
}
});
});
基本上我的控制器在用户通过身份验证后调用数据的角度服务。
控制器代码当前配置为允许来自任何地方的请求。
namespace TradesService.Controllers
{
[Authorize]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class OpenPnLController : ApiController
{
private benderEntities db = new benderEntities();
// GET: api/OpenPnL
public IQueryable<OpenPnL> GetOpenPnL()
{
return db.OpenPnL;
}
// GET: api/OpenPnL/5
[ResponseType(typeof(OpenPnL))]
public IHttpActionResult GetOpenPnL(int id)
{
OpenPnL openPnL = db.OpenPnL.Find(id);
if (openPnL == null)
{
return NotFound();
}
return Ok(openPnL);
}
我的WebAPIConfig确实启用了CORS
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.EnableCors();
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
以及我为令牌服务启用它
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
请求看起来像这样
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Authorization:Bearer Rlau_KVh9WUjrVw1smLaJjkR3G_nT1mUlliGVFW8YwoGQjL4RUyozVug7bXiFrdQQAKWowDlx2OpTbUYbL3XS_pouVQMT6YYzNDxb67byWg1szpuDTt-f3XAakKf0ilLN-0T1CI8dDO5PWewBzA7B3mbI0XNGvfZpPpZc_f5orVW4RC58OqTm35Brh73_lOPtlLrdG3rQwqUIHTI6Tqi69TXdl8D8I7KjTo5ruboIpGJHvqQOF38Flqvskdh4M6ottajp3znE4SToil78yOrZ9oPmeFemdpVde9UpTJRcDqF2tVf-9eALorym6cYYWBoji11chr594lsTp0IW30_Xa9uyxwDIOSgEGGxWzbFBuE6fKzpTy49dSW-kxD6mii-M7eW1D_aFdXVEp8IsTbLL6Pa5o_i3izsFR2MajfWFu-KwzOcWJ0SL38XAIz12ouq6ifnRZQe4ezOZkc5ckgy1T86xVVa0z4q0_2jsx-TCYw
Cache-Control:no-cache
Connection:keep-alive
Host:tradesservice.azurewebsites.net
Origin:https://perseus1.azurewebsites.net
Pragma:no-cache
Referer:https://perseus1.azurewebsites.net/openpnl
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
我得到的回应是
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Length: 36
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Set- Cookie:ARRAffinity=b0cea33dbc4e2efdaae3fe9feccd731de0b41e0e9fe1259e0169810645b448f9;Path=/;Domain=tradesservice.azurewebsites.net
Date: Tue, 06 Oct 2015 23:15:21 GMT
Chrome中的javascript控制台显示以下内容。
XMLHttpRequest cannot load https://tradesservice.azurewebsites.net/api/OpenPnL. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://perseus1.azurewebsites.net' is therefore not allowed access. The response had HTTP status code 500.
对我在这里做错了什么的想法?
更新
有人提到服务器配置可能是个问题。以下是web api的web.config的相关部分 <system.web>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
以及托管角度代码的网站
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,POST,DELETE,HEAD,PUT,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Olaround-Debug-Mode, Authorization, Accept" />
<add name="Access-Control-Expose-Headers" value="X-Olaround-Debug-Mode, X-Olaround-Request-Start-Timestamp, X-Olaround-Request-End-Timestamp, X-Olaround-Request-Time, X-Olaround-Request-Method, X-Olaround-Request-Result, X-Olaround-Request-Endpoint" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
我修改了web.config以包含上面列出的主体,现在请求看起来像这样
在网站的web.config中添加了代码,现在请求看起来像这样..
OPTIONS /api/OpenPnL HTTP/1.1
Host: tradesservice.azurewebsites.net
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: https://perseus1.azurewebsites.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: https://perseus1.azurewebsites.net/openpnl
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
和回复
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Content-Length: 0
Server: Microsoft-IIS/8.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=b0cea33dbc4e2efdaae3fe9feccd731de0b41e0e9fe1259e0169810645b448f9;Path=/;Domain=tradesservice.azurewebsites.net
Date: Tue, 06 Oct 2015 23:59:16 GMT
不再有500错误。
答案 0 :(得分:0)
我最近遇到了类似的问题,也有一个在Azure上托管的网站,虽然我不认为这是原因。发现CORS错误在某种程度上是由SQL超时异常触发的,因为我们的存储过程正在处理大量数据并且耗时太长。加快了一些过程并且大多数CORS错误停止发生,同样需要为其他过程完成,然后它们将再次起作用。
看起来你遇到了不同的问题,但是如果有任何人在发出请求后几分钟内出现了CORS错误,那么就值得研究一下。