Angular2到REST WebApi CORS问题

时间:2016-02-04 13:30:25

标签: angular asp.net-web-api cors

我正在使用angular2前端和WebApi后端。 webapi已启用CORS

var cors = new EnableCorsAttribute("*", "*", "*");
GlobalConfiguration.Configuration.EnableCors(cors);

它有效,因为我有不同的网站(jQuery / Javascript)使用这个API。但是对于angular2,它没有。我收到以下消息:

  

对预检请求的响应未通过访问控制检查:请求的资源上没有“Access-Control-Allow-Origin”标头。

也许与“预检请求”有关?

10 个答案:

答案 0 :(得分:9)

我在Angular2应用程序中遇到了同样的问题。 如前所述,问题是在客户端发出每个请求之前,预检请求被发送到服务器。

此类请求的类型为 OPTIONS ,服务器有责任发回状态为200的预检响应并设置接受标头来自该客户的请求。

这是我的解决方案(快递):

// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');

// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');

// Set to true if you need the website to include cookies in  requests
res.setHeader('Access-Control-Allow-Credentials', true);

// Check if preflight request
if (req.method === 'OPTIONS') {
    res.status(200);
    res.end();
}
else {
    // Pass to next layer of middleware
    next();
}

如您所见,我设置了标题,然后在请求类型为 OPTIONS 时获取。在那种情况下,我发送回状态200并结束响应。

通过这种方式,客户端将获得授权,您还可以在所有请求中设置自定义标头。

答案 1 :(得分:8)

您的错误消息表明您的通话响应中没有Access-Control-Allow-Origin。这是为此请求启用CORS所必需的。它与Angular2无关。

这是在客户端通过在请求中添加Origin标头触发的。你的请求中有这个标题吗?您是否在其他应用程序中使用了预检请求。提醒一下:

  • 简单请求。如果我们使用HTTP GET,HEAD和POST方法,则此用例适用。对于POST方法,仅支持具有以下值的内容类型:text/plainapplication/x-www-form-urlencodedmultipart/form-data
  • 预检请求。当"简单请求"用例不适用,第一个请求(使用HTTP OPTIONS方法)用于检查在跨域请求的上下文中可以做什么。

也许OPTIONS请求在服务器端没有正确处理(不要返回正确的标题,......)。

感兴趣的是告诉我们发生错误的请求:OPTIONS one或目标请求。您可以查看DevTools中的网络标签...

有关CORS如何运作的更多详细信息,请参阅以下链接:

希望它可以帮到你, 亨利

答案 2 :(得分:1)

你的web.config文件中是否有为cors设置的选项?即<add name="Access-Control-Allow-Origin" value="*"/>

之类的东西

如果是,请务必删除它,并仅通过代码控制cors。

答案here会对您有所帮助。

答案 3 :(得分:1)

我知道问题不是要求PHP代码。我来到这里是因为整个飞行前的事情和Angular2。当我看到Matteo的答案时,我意识到为什么我的服务器的请求回来了401.这是因为在预检浏览器中没有发送授权令牌,因此服务器返回401并且浏览器认为不允许CORS 。请注意,除非您知道自己在做什么,否则下面的代码只能在开发服务器中使用。

在PHP中,你可以这样做:

if (strtolower($_SERVER['REQUEST_METHOD']) === 'options') {
         header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
         header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
         header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type, Authorization');
         header('Access-Control-Allow-Credentials: true');
         echo 'Allowed';
         exit;
}

OR Nginx

if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }

记住您要发送到服务器的任何其他标头,您必须将其添加到Access-Control-Allow-Headers列表中。

答案 4 :(得分:1)

出于开发目的,添加this Chrome扩展程序并启用跨域资源共享。

答案 5 :(得分:0)

我正在使用Angular 2作为前端,将nodeJS(Expressjs)作为API

Angular 2在localhost:3000下运行,express正在使用localhost:8000

当localhost:3000尝试使用POST方法调用URL时出现问题... expressJS服务器拒绝该调用,因为它来自另一个服务器(或端口)

要解决此问题,您应该告诉节点js接受来自localhost:3000服务器的调用...

You can find a library (CORS) to avoid this problem in this link

答案 6 :(得分:0)

您可以在Firefox浏览器中添加一个加载项。它将在你的Firefox浏览器中工作,就像魅力一样。 Cors Everywhere解决了我的问题。 https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/

答案 7 :(得分:0)

我在cors和angular 6上也很难过。

对服务器的请求不是基本请求时,会有预检请求询问您的服务器是否可以回答您的请求。

服务器响应该请求应具有以下标头:

Access-Control-Allow-Origin //应该是您的域

Access-Control-Allow-Headers //应该是Accept,Origin,也可能是其他任何标头。

Access-Control-Allow-Method //您使用的任何方法

这些是您添加为Cors属性以接受所有内容的“ *”,“ *”,“ *” 但这仅在客户端和服务器都在同一台计算机上时才对我有效。 在我使用IIS服务器进行生产后,这些值不再起作用,尤其是因为标题。

因此非常容易修复,也适用于IOS 相反,我将其添加到每个控制器中:

[EnableCors(origins: "enter your domain here", headers: "authorization, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers", methods: "GET,POST", PreflightMaxAge = 600 // optional, SupportsCredentials = true // optional)]

您可以在帮助我了解我需要做什么的文章中阅读更多内容: https://msdn.microsoft.com/en-us/magazine/dn532203.aspx

希望有帮助, 墨粉

答案 8 :(得分:0)

在我的情况下,我使用了Owin,并且不得不将以下行移动到启动的开头

public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

            ...
        }
    }
}

答案 9 :(得分:0)

请按照以下步骤进行WEB API中的CROS ISSUE修复:

  1. 在应用程序中启用CORS必需的标题。即在“ Global.asax”文件中的“ Application_BeginRequest”方法中进行简单请求。

  2. 将下面的代码放入“ web.config”文件中有助于解决CORS发出的飞行前请求

    <system.webServer>
              <handlers>
                <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
                <remove name="OPTIONSVerbHandler" />
                <add name="ExtensionlessUrlHandler-Integrated-4.0"path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
              </handlers>
            </system.webServer>
    

参考: https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api#enable-cors