【问题标题】:Angular2 to REST WebApi CORS issueAngular2 到 REST WebApi CORS 问题
【发布时间】:2016-05-14 03:26:18
【问题描述】:

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

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

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

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

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

【问题讨论】:

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


【解决方案1】:

请按照 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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我也很难使用 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

      希望对你有帮助, 汤姆。

      【讨论】:

        【解决方案4】:

        为开发目的添加this Chrome 扩展并启用跨域资源共享。

        【讨论】:

        • 即使扩展程序正常工作,这也是一个糟糕的解决方案。 OP 需要正确设置 CORS 标头在他的服务器上
        • @sr9yar 是的,这不是一个永久的解决方案,但如果你有一些服务器依赖项,那么你可以继续使用这个 chrome 扩展。
        【解决方案5】:

        您可以在 Firefox 浏览器中添加一个插件。它将像魅力一样在您的 Firefox 浏览器中运行。 Cors Everywhere 解决了我的问题。 https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/

        【讨论】:

          【解决方案6】:

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

          Angular 2 在 localhost:3000 下工作,而 express 在 localhost:8000 下工作

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

          要解决这个问题,你应该告诉 node js 接受来自 localhost:3000 服务器的调用...

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

          【讨论】:

            【解决方案7】:

            我知道问题不是要求 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;
            }
            

            或 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 列表中。

            【讨论】:

              【解决方案8】:

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

              这种类型的请求具有 OPTIONS 类型,服务器有责任发回 preflight 响应,状态为 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 并结束响应。

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

              【讨论】:

              • 你把这些行放在哪里了?
              • 在路由声明之前。
              • 成功了,谢谢。我使用了the CORS middleware,但它没有用。为什么?这段代码不是在做同样的事情吗?
              • 非常感谢!这个解决方案也适用于 PHP-Angular
              【解决方案9】:

              您的 web.config 文件中是否为 cors 设置了任何选项?即类似&lt;add name="Access-Control-Allow-Origin" value="*"/&gt;

              如果是,请确保将其删除,并仅通过代码控制 cors。

              答案here 会帮助你。

              【讨论】:

                【解决方案10】:

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

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

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

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

                感兴趣的是告诉我们错误发生在哪些请求上:OPTIONS 之一或目标请求。您可以查看 DevTools 中的 Network 选项卡...

                有关 CORS 工作原理的更多详细信息,请参阅以下链接:

                希望对你有帮助, 蒂埃里

                【讨论】:

                • +1 当我在客户端上苦苦挣扎时,给了我正确的方向,但飞行前错误是因为服务器阻塞了带有一些标头的 cors 请求。所以必须允许我的场景中的所有标题。
                • @Thierry Templier 你能看看这个question吗?
                • 很好的解释。 @"Matteo Tosi" 给出了解决方案
                猜你喜欢
                • 2017-02-01
                • 2023-03-16
                • 2014-12-16
                • 2019-05-22
                • 1970-01-01
                • 2016-10-26
                • 1970-01-01
                • 2016-09-20
                • 2021-09-19
                相关资源
                最近更新 更多