AngularJS为一个跨源资源执行一个选项HTTP请求

时间:2022-08-22 19:22:11

I'm trying to setup AngularJS to communicate with a cross-origin resource where the asset host which delivers my template files is on a different domain and therefore the XHR request that angular performs must be cross-domain. I've added the appropriate CORS header to my server for the HTTP request to make this work, but it doesn't seem to work. The problem is that when I inspect the HTTP requests in my browser (chrome) the request sent to the asset file is an OPTIONS request (it should be a GET request).

我正在尝试设置AngularJS与一个跨源资源通信,在这个资源中,提交模板文件的资产主机位于不同的域中,因此,角执行的XHR请求必须是跨域的。我已经为HTTP请求向服务器添加了适当的CORS报头以使此工作,但它似乎不工作。问题是,当我检查浏览器(chrome)中的HTTP请求时,发送到资产文件的请求是一个选项请求(它应该是一个GET请求)。

I'm not sure whether this is a bug in AngularJS or if I need to configure something. From what I understand the XHR wrapper can't make an OPTIONS HTTP request so it looks like the browser is trying to figure out if is "allowed" to download the asset first before it performs the GET request. If this is the case, then do I need to set the CORS header (Access-Control-Allow-Origin: http://asset.host...) with the asset host as well?

我不确定这是AngularJS中的一个bug,还是我需要配置一些东西。从我了解的情况来看,XHR包装器不能做出一个选择HTTP请求,所以看起来浏览器正在试图弄清楚是否“允许”在执行GET请求之前下载该资产。如果是这种情况,那么我是否需要使用资产主机设置CORS报头(Access-Control-Allow-Origin: http://asset.host...) ?

12 个解决方案

#1


213  

OPTIONS request are by no means an AngularJS bug, this is how Cross-Origin Resource Sharing standard mandates browsers to behave. Please refer to this document: https://developer.mozilla.org/en-US/docs/HTTP_access_control, where in the "Overview" section it says:

选项请求绝不是一个AngularJS bug,这是跨源资源共享标准强制浏览器的行为方式。请参考此文档:https://developer.mozilla.org/en-US/docs/HTTP_access_control,在“概述”一节中它说:

The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. Additionally, for HTTP request methods that can cause side-effects on user data (in particular; for HTTP methods other than GET, or for POST usage with certain MIME types). The specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request header, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether "credentials" (including Cookies and HTTP Authentication data) should be sent with requests.

跨源资源共享标准通过添加新的HTTP头来工作,允许服务器描述允许使用web浏览器读取信息的源集。此外,对于可能对用户数据产生副作用的HTTP请求方法(特别是;用于除GET之外的HTTP方法,或用于某些MIME类型的POST使用)。规范要求浏览器“飞行”请求,用HTTP选项请求头从服务器请求受支持的方法,然后,在服务器“批准”后,用实际的HTTP请求方法发送实际的请求。服务器还可以通知客户端“凭据”(包括cookie和HTTP身份验证数据)是否应该随请求一起发送。

It is very hard to provide a generic solution that would work for all the WWW servers as setup will vary depending on the server itself and HTTP verbs that you intend to support. I would encourage you to get over this excellent article (http://www.html5rocks.com/en/tutorials/cors/) that has much more details on the exact headers that needs to be sent by a server.

很难提供适用于所有WWW服务器的通用解决方案,因为设置会根据您打算支持的服务器本身和HTTP谓词而有所不同。我鼓励您阅读这篇优秀的文章(http://www.html5rocks.com/en/tutorials/cors/),该文章详细介绍了服务器需要发送的确切标题。

#2


65  

For Angular 1.2.0rc1+ you need to add a resourceUrlWhitelist.

对于角1.2.0rc1+,您需要添加resourceUrlWhitelist。

1.2: release version they added a escapeForRegexp function so you no longer have to escape the strings. You can just add the url directly

他们添加了一个escapeForRegexp函数,这样您就不必转义字符串了。你可以直接添加url

'http://sub*.assets.example.com/**' 

make sure to add ** for sub folders. Here is a working jsbin for 1.2: http://jsbin.com/olavok/145/edit

确保为子文件夹添加**。下面是1.2的一个工作jsbin: http://jsbin.com/olavok/145/edit


1.2.0rc: If you are still on a rc version, the Angular 1.2.0rc1 the solution looks like:

1.2.0rc:如果你仍然使用rc版本,角度为1.2.0rc1,那么解是这样的:

.config(['$sceDelegateProvider', function($sceDelegateProvider) {
     $sceDelegateProvider.resourceUrlWhitelist(['self', /^https?:\/\/(cdn\.)?yourdomain.com/]);
 }])

Here is a jsbin example where it works for 1.2.0rc1: http://jsbin.com/olavok/144/edit

下面是一个jsbin示例,它适用于1.2.0rc1: http://jsbin.com/olavok/144/edit


Pre 1.2: For older versions (ref http://better-inter.net/enabling-cors-in-angular-js/) you need to add the following 2 lines to your config:

Pre 1.2:对于旧版本(ref http://better-inter.net/enabling-cors-in angular-js/),您需要在配置中添加以下两行:

$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

Here is a jsbin example where it works for pre 1.2 versions: http://jsbin.com/olavok/11/edit

下面是一个jsbin示例,它适用于pre 1.2版本:http://jsbin.com/olavok/11/edit

#3


58  

NOTE: Not sure it works with the latest version of Angular.

注意:不确定它是否适用于最新版本的角度。

ORIGINAL:

原:

It's also possible to override the OPTIONS request (was only tested in Chrome):

也可以覆盖选项请求(仅在Chrome中测试):

app.config(['$httpProvider', function ($httpProvider) {
  //Reset headers to avoid OPTIONS request (aka preflight)
  $httpProvider.defaults.headers.common = {};
  $httpProvider.defaults.headers.post = {};
  $httpProvider.defaults.headers.put = {};
  $httpProvider.defaults.headers.patch = {};
}]);

#4


32  

Your service must answer an OPTIONS request with headers like these:

您的服务必须以以下标题回答选项请求:

Access-Control-Allow-Origin: [the same origin from the request]
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: [the same ACCESS-CONTROL-REQUEST-HEADERS from request]

Here is a good doc: http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server

这里有一个很好的文档:http://www.html5rocks.com/en/tutorials/cors/#toc- adding-cors-supportto- to-the-server

#5


20  

The same document says

相同的文件说

Unlike simple requests (discussed above), "preflighted" requests first send an HTTP OPTIONS request header to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:

与上面讨论的简单请求不同,“预置”请求首先向另一个域中的资源发送一个HTTP选项请求头,以确定实际的请求是否安全。跨站点请求是这样的,因为它们可能对用户数据有影响。特别是,如果:

It uses methods other than GET or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.

它使用的方法不是GET或POST。另外,如果POST用于发送除application/ www-form- urlencodes、multipart/form-data或text/plain之外的内容类型的请求数据,例如,如果POST请求使用application/ XML或text/ XML向服务器发送XML有效负载,那么该请求是预先完成的。

It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)

它在请求中设置自定义头(例如,请求使用一个头,如X-PINGOTHER)

When the original request is Get with no custom headers, the browser should not make Options request which it does now. The problem is it generates a header X-Requested-With which forces the Options request. See https://github.com/angular/angular.js/pull/1454 on how to remove this header

当原始请求没有自定义标头时,浏览器就不应该做出现在做的选项请求。问题是它会生成一个x - requestee头,从而强制执行选项请求。请参阅https://github.com/angular/angular/angular.js/pull/1454如何删除该标题。

#6


10  

This fixed my problem:

这固定我的问题:

$http.defaults.headers.post["Content-Type"] = "text/plain";

#7


10  

If you are using a nodeJS server, you can use this library, it worked fine for me https://github.com/expressjs/cors

如果您正在使用一个nodeJS服务器,您可以使用这个库,它对我来说运行良好:https://github.com/expressjs/cors

var express = require('express')
  , cors = require('cors')
  , app = express();

app.use(cors());

and after you can do an npm update.

在你可以进行npm更新之后。

#8


4  

Here is the way I fixed this issue on ASP.NET

这是我在ASP.NET中解决这个问题的方法。

  • First, you should add the nuget package Microsoft.AspNet.WebApi.Cors

    首先,您应该添加nuget包microsoft.aspnet . webap . cors

  • Then modify the file App_Start\WebApiConfig.cs

    然后修改文件App_Start\WebApiConfig.cs

    public static class WebApiConfig    
    {
       public static void Register(HttpConfiguration config)
       {
          config.EnableCors();
    
          ...
       }    
    }
    
  • Add this attribute on your controller class

    在控制器类中添加此属性

    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class MyController : ApiController
    {  
        [AcceptVerbs("POST")]
        public IHttpActionResult Post([FromBody]YourDataType data)
        {
             ...
             return Ok(result);
        }
    }
    
  • I was able to send json to the action by this way

    我可以通过这种方式向action发送json

    $http({
            method: 'POST',
            data: JSON.stringify(data),
            url: 'actionurl',
            headers: {
                'Content-Type': 'application/json; charset=UTF-8'
            }
        }).then(...)
    

Reference : Enabling Cross-Origin Requests in ASP.NET Web API 2

引用:在ASP中启用跨源请求。净Web API 2

#9


1  

Somehow I fixed it by changing

我改变了它

Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"

访问-控制-允许-标题"来源,x -请求-与,内容类型,接受,授权"

to

Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization"

“来源、内容类型、接受、授权”

#10


0  

Perfectly described in pkozlowski's comment. I had working solution with AngularJS 1.2.6 and ASP.NET Web Api but when I had upgraded AngularJS to 1.3.3 then requests failed.

pkozlowski的评论完美地描述了这一点。我有AngularJS 1.2.6和ASP的工作解决方案。NET Web Api,但是当我将AngularJS升级到1.3.3时,请求就失败了。

  • Solution for Web Api server was to add handling of the OPTIONS requests at the beginning of configuration method (more info in this blog post):

    Web Api服务器的解决方案是在配置方法开始时添加对选项请求的处理(本文将提供更多信息):

    app.Use(async (context, next) =>
    {
        IOwinRequest req = context.Request;
        IOwinResponse res = context.Response;
        if (req.Path.StartsWithSegments(new PathString("/Token")))
        {
            var origin = req.Headers.Get("Origin");
            if (!string.IsNullOrEmpty(origin))
            {
                res.Headers.Set("Access-Control-Allow-Origin", origin);
            }
            if (req.Method == "OPTIONS")
            {
                res.StatusCode = 200;
                res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET", "POST");
                res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "authorization", "content-type");
                return;
            }
        }
        await next();
    });
    

#11


0  

If you are using Jersey for REST API's you can do as below

如果您使用Jersey的REST API,您可以做到如下所示。

You don't have to change your webservices implementation.

您不必更改webservices实现。

I will explain for Jersey 2.x

我会为新泽西2。x解释

1) First add a ResponseFilter as shown below

1)首先添加一个ResponseFilter,如下所示

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

public class CorsResponseFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext,   ContainerResponseContext responseContext)
    throws IOException {
        responseContext.getHeaders().add("Access-Control-Allow-Origin","*");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");

  }
}

2) then in the web.xml , in the jersey servlet declaration add the below

2)然后在网络上。在jersey servlet声明中添加下面的xml

    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>YOUR PACKAGE.CorsResponseFilter</param-value>
    </init-param>

#12


0  

I gave up trying to fix this issue.

我放弃了解决这个问题的尝试。

My IIS web.config had the relevant "Access-Control-Allow-Methods" in it, I experimented adding config settings to my Angular code, but after burning a few hours trying to get Chrome to call a cross-domain JSON web service, I gave up miserably.

我的IIS web。配置中有相关的“访问控制允许的方法”,我尝试在我的角代码中添加配置设置,但是在花了几个小时让Chrome调用跨域JSON web服务之后,我痛苦地放弃了。

In the end, I added a dumb ASP.Net handler webpage, got that to call my JSON web service, and return the results. It was up and running in 2 minutes.

最后,我添加了一个哑ASP。Net handler页面,调用JSON web服务,返回结果。它在两分钟内就跑起来了。

Here's the code I used:

下面是我使用的代码:

public class LoadJSONData : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";

        string URL = "......";

        using (var client = new HttpClient())
        {
            // New code:
            client.BaseAddress = new Uri(URL);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("Authorization", "Basic AUTHORIZATION_STRING");

            HttpResponseMessage response = client.GetAsync(URL).Result;
            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().Result;
                context.Response.Write("Success: " + content);
            }
            else
            {
                context.Response.Write(response.StatusCode + " : Message - " + response.ReasonPhrase);
            }
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

And in my Angular controller...

在我的角度控制器中。

$http.get("/Handlers/LoadJSONData.ashx")
   .success(function (data) {
      ....
   });

I'm sure there's a simpler/more generic way of doing this, but life's too short...

我相信有一种更简单/更通用的方法可以做到这一点,但是生命太短暂了……

This worked for me, and I can get on with doing normal work now !!

这对我很有效,我现在可以继续做正常的工作了!!

#1


213  

OPTIONS request are by no means an AngularJS bug, this is how Cross-Origin Resource Sharing standard mandates browsers to behave. Please refer to this document: https://developer.mozilla.org/en-US/docs/HTTP_access_control, where in the "Overview" section it says:

选项请求绝不是一个AngularJS bug,这是跨源资源共享标准强制浏览器的行为方式。请参考此文档:https://developer.mozilla.org/en-US/docs/HTTP_access_control,在“概述”一节中它说:

The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. Additionally, for HTTP request methods that can cause side-effects on user data (in particular; for HTTP methods other than GET, or for POST usage with certain MIME types). The specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request header, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether "credentials" (including Cookies and HTTP Authentication data) should be sent with requests.

跨源资源共享标准通过添加新的HTTP头来工作,允许服务器描述允许使用web浏览器读取信息的源集。此外,对于可能对用户数据产生副作用的HTTP请求方法(特别是;用于除GET之外的HTTP方法,或用于某些MIME类型的POST使用)。规范要求浏览器“飞行”请求,用HTTP选项请求头从服务器请求受支持的方法,然后,在服务器“批准”后,用实际的HTTP请求方法发送实际的请求。服务器还可以通知客户端“凭据”(包括cookie和HTTP身份验证数据)是否应该随请求一起发送。

It is very hard to provide a generic solution that would work for all the WWW servers as setup will vary depending on the server itself and HTTP verbs that you intend to support. I would encourage you to get over this excellent article (http://www.html5rocks.com/en/tutorials/cors/) that has much more details on the exact headers that needs to be sent by a server.

很难提供适用于所有WWW服务器的通用解决方案,因为设置会根据您打算支持的服务器本身和HTTP谓词而有所不同。我鼓励您阅读这篇优秀的文章(http://www.html5rocks.com/en/tutorials/cors/),该文章详细介绍了服务器需要发送的确切标题。

#2


65  

For Angular 1.2.0rc1+ you need to add a resourceUrlWhitelist.

对于角1.2.0rc1+,您需要添加resourceUrlWhitelist。

1.2: release version they added a escapeForRegexp function so you no longer have to escape the strings. You can just add the url directly

他们添加了一个escapeForRegexp函数,这样您就不必转义字符串了。你可以直接添加url

'http://sub*.assets.example.com/**' 

make sure to add ** for sub folders. Here is a working jsbin for 1.2: http://jsbin.com/olavok/145/edit

确保为子文件夹添加**。下面是1.2的一个工作jsbin: http://jsbin.com/olavok/145/edit


1.2.0rc: If you are still on a rc version, the Angular 1.2.0rc1 the solution looks like:

1.2.0rc:如果你仍然使用rc版本,角度为1.2.0rc1,那么解是这样的:

.config(['$sceDelegateProvider', function($sceDelegateProvider) {
     $sceDelegateProvider.resourceUrlWhitelist(['self', /^https?:\/\/(cdn\.)?yourdomain.com/]);
 }])

Here is a jsbin example where it works for 1.2.0rc1: http://jsbin.com/olavok/144/edit

下面是一个jsbin示例,它适用于1.2.0rc1: http://jsbin.com/olavok/144/edit


Pre 1.2: For older versions (ref http://better-inter.net/enabling-cors-in-angular-js/) you need to add the following 2 lines to your config:

Pre 1.2:对于旧版本(ref http://better-inter.net/enabling-cors-in angular-js/),您需要在配置中添加以下两行:

$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

Here is a jsbin example where it works for pre 1.2 versions: http://jsbin.com/olavok/11/edit

下面是一个jsbin示例,它适用于pre 1.2版本:http://jsbin.com/olavok/11/edit

#3


58  

NOTE: Not sure it works with the latest version of Angular.

注意:不确定它是否适用于最新版本的角度。

ORIGINAL:

原:

It's also possible to override the OPTIONS request (was only tested in Chrome):

也可以覆盖选项请求(仅在Chrome中测试):

app.config(['$httpProvider', function ($httpProvider) {
  //Reset headers to avoid OPTIONS request (aka preflight)
  $httpProvider.defaults.headers.common = {};
  $httpProvider.defaults.headers.post = {};
  $httpProvider.defaults.headers.put = {};
  $httpProvider.defaults.headers.patch = {};
}]);

#4


32  

Your service must answer an OPTIONS request with headers like these:

您的服务必须以以下标题回答选项请求:

Access-Control-Allow-Origin: [the same origin from the request]
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: [the same ACCESS-CONTROL-REQUEST-HEADERS from request]

Here is a good doc: http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server

这里有一个很好的文档:http://www.html5rocks.com/en/tutorials/cors/#toc- adding-cors-supportto- to-the-server

#5


20  

The same document says

相同的文件说

Unlike simple requests (discussed above), "preflighted" requests first send an HTTP OPTIONS request header to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:

与上面讨论的简单请求不同,“预置”请求首先向另一个域中的资源发送一个HTTP选项请求头,以确定实际的请求是否安全。跨站点请求是这样的,因为它们可能对用户数据有影响。特别是,如果:

It uses methods other than GET or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.

它使用的方法不是GET或POST。另外,如果POST用于发送除application/ www-form- urlencodes、multipart/form-data或text/plain之外的内容类型的请求数据,例如,如果POST请求使用application/ XML或text/ XML向服务器发送XML有效负载,那么该请求是预先完成的。

It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)

它在请求中设置自定义头(例如,请求使用一个头,如X-PINGOTHER)

When the original request is Get with no custom headers, the browser should not make Options request which it does now. The problem is it generates a header X-Requested-With which forces the Options request. See https://github.com/angular/angular.js/pull/1454 on how to remove this header

当原始请求没有自定义标头时,浏览器就不应该做出现在做的选项请求。问题是它会生成一个x - requestee头,从而强制执行选项请求。请参阅https://github.com/angular/angular/angular.js/pull/1454如何删除该标题。

#6


10  

This fixed my problem:

这固定我的问题:

$http.defaults.headers.post["Content-Type"] = "text/plain";

#7


10  

If you are using a nodeJS server, you can use this library, it worked fine for me https://github.com/expressjs/cors

如果您正在使用一个nodeJS服务器,您可以使用这个库,它对我来说运行良好:https://github.com/expressjs/cors

var express = require('express')
  , cors = require('cors')
  , app = express();

app.use(cors());

and after you can do an npm update.

在你可以进行npm更新之后。

#8


4  

Here is the way I fixed this issue on ASP.NET

这是我在ASP.NET中解决这个问题的方法。

  • First, you should add the nuget package Microsoft.AspNet.WebApi.Cors

    首先,您应该添加nuget包microsoft.aspnet . webap . cors

  • Then modify the file App_Start\WebApiConfig.cs

    然后修改文件App_Start\WebApiConfig.cs

    public static class WebApiConfig    
    {
       public static void Register(HttpConfiguration config)
       {
          config.EnableCors();
    
          ...
       }    
    }
    
  • Add this attribute on your controller class

    在控制器类中添加此属性

    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class MyController : ApiController
    {  
        [AcceptVerbs("POST")]
        public IHttpActionResult Post([FromBody]YourDataType data)
        {
             ...
             return Ok(result);
        }
    }
    
  • I was able to send json to the action by this way

    我可以通过这种方式向action发送json

    $http({
            method: 'POST',
            data: JSON.stringify(data),
            url: 'actionurl',
            headers: {
                'Content-Type': 'application/json; charset=UTF-8'
            }
        }).then(...)
    

Reference : Enabling Cross-Origin Requests in ASP.NET Web API 2

引用:在ASP中启用跨源请求。净Web API 2

#9


1  

Somehow I fixed it by changing

我改变了它

Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"

访问-控制-允许-标题"来源,x -请求-与,内容类型,接受,授权"

to

Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization"

“来源、内容类型、接受、授权”

#10


0  

Perfectly described in pkozlowski's comment. I had working solution with AngularJS 1.2.6 and ASP.NET Web Api but when I had upgraded AngularJS to 1.3.3 then requests failed.

pkozlowski的评论完美地描述了这一点。我有AngularJS 1.2.6和ASP的工作解决方案。NET Web Api,但是当我将AngularJS升级到1.3.3时,请求就失败了。

  • Solution for Web Api server was to add handling of the OPTIONS requests at the beginning of configuration method (more info in this blog post):

    Web Api服务器的解决方案是在配置方法开始时添加对选项请求的处理(本文将提供更多信息):

    app.Use(async (context, next) =>
    {
        IOwinRequest req = context.Request;
        IOwinResponse res = context.Response;
        if (req.Path.StartsWithSegments(new PathString("/Token")))
        {
            var origin = req.Headers.Get("Origin");
            if (!string.IsNullOrEmpty(origin))
            {
                res.Headers.Set("Access-Control-Allow-Origin", origin);
            }
            if (req.Method == "OPTIONS")
            {
                res.StatusCode = 200;
                res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET", "POST");
                res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "authorization", "content-type");
                return;
            }
        }
        await next();
    });
    

#11


0  

If you are using Jersey for REST API's you can do as below

如果您使用Jersey的REST API,您可以做到如下所示。

You don't have to change your webservices implementation.

您不必更改webservices实现。

I will explain for Jersey 2.x

我会为新泽西2。x解释

1) First add a ResponseFilter as shown below

1)首先添加一个ResponseFilter,如下所示

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

public class CorsResponseFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext,   ContainerResponseContext responseContext)
    throws IOException {
        responseContext.getHeaders().add("Access-Control-Allow-Origin","*");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");

  }
}

2) then in the web.xml , in the jersey servlet declaration add the below

2)然后在网络上。在jersey servlet声明中添加下面的xml

    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>YOUR PACKAGE.CorsResponseFilter</param-value>
    </init-param>

#12


0  

I gave up trying to fix this issue.

我放弃了解决这个问题的尝试。

My IIS web.config had the relevant "Access-Control-Allow-Methods" in it, I experimented adding config settings to my Angular code, but after burning a few hours trying to get Chrome to call a cross-domain JSON web service, I gave up miserably.

我的IIS web。配置中有相关的“访问控制允许的方法”,我尝试在我的角代码中添加配置设置,但是在花了几个小时让Chrome调用跨域JSON web服务之后,我痛苦地放弃了。

In the end, I added a dumb ASP.Net handler webpage, got that to call my JSON web service, and return the results. It was up and running in 2 minutes.

最后,我添加了一个哑ASP。Net handler页面,调用JSON web服务,返回结果。它在两分钟内就跑起来了。

Here's the code I used:

下面是我使用的代码:

public class LoadJSONData : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";

        string URL = "......";

        using (var client = new HttpClient())
        {
            // New code:
            client.BaseAddress = new Uri(URL);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("Authorization", "Basic AUTHORIZATION_STRING");

            HttpResponseMessage response = client.GetAsync(URL).Result;
            if (response.IsSuccessStatusCode)
            {
                var content = response.Content.ReadAsStringAsync().Result;
                context.Response.Write("Success: " + content);
            }
            else
            {
                context.Response.Write(response.StatusCode + " : Message - " + response.ReasonPhrase);
            }
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

And in my Angular controller...

在我的角度控制器中。

$http.get("/Handlers/LoadJSONData.ashx")
   .success(function (data) {
      ....
   });

I'm sure there's a simpler/more generic way of doing this, but life's too short...

我相信有一种更简单/更通用的方法可以做到这一点,但是生命太短暂了……

This worked for me, and I can get on with doing normal work now !!

这对我很有效,我现在可以继续做正常的工作了!!