CORS在本地工作正常但在使用Azure网站时中断

时间:2015-10-06 23:20:00

标签: javascript angularjs azure asp.net-web-api

我正在使用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错误。

1 个答案:

答案 0 :(得分:0)

我最近遇到了类似的问题,也有一个在Azure上托管的网站,虽然我不认为这是原因。发现CORS错误在某种程度上是由SQL超时异常触发的,因为我们的存储过程正在处理大量数据并且耗时太长。加快了一些过程并且大多数CORS错误停止发生,同样需要为其他过程完成,然后它们将再次起作用。

看起来你遇到了不同的问题,但是如果有任何人在发出请求后几分钟内出现了CORS错误,那么就值得研究一下。