2016-02-04 65 views
17

我正在使用angular2前端和WebApi后端。 的是的WebAPI启用CORSAngular2到REST WebApi CORS问题

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

和它的作品,因为我有不同的网站(jQuery的/ JavaScript)的使用这个API。但是使用angular2它不会。我收到以下消息:

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

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

+0

我阅读了“在ASP.NET Web API中启用跨域请求”的文档,您应该在响应中包含此标头。请参阅此页面中的“CORS如何工作”部分:http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#how-it-works。 –

+1

***我正在关闭它,因为它只是每个OP的打印错误。*** – Win

+0

我认为这个问题在服务器属性中见: http://stackoverflow.com/questions/36825429/angular-2-no -access-control-allow-origin-header-is-present-on-the-requested –

回答

5

您的错误消息表明您的电话回复中没有Access-Control-Allow-Origin。这是为此请求启用CORS所必需的。这与Angular2没有关系。

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

  • 简单请求。这个用例适用于我们使用HTTP GET,HEAD和POST方法的情况。对于POST方法,仅支持具有以下值的内容类型:text/plain,application/x-www-form-urlencodedmultipart/form-data
  • 预照明请求。当“简单请求”用例不适用时,首先请求(使用HTTP OPTIONS方法)检查​​在跨域请求的上下文中可以做什么。

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

什么会感兴趣的是告诉我们哪些请求发生错误:选项一或目标请求。你可以看看在DevTools的网络标签...

请参见以下链接如需详细了解CORS是如何工作的:

希望它帮助你, Thierry

+1

+1给我正确的方向,因为我在客户端挣扎着,但是飞行前错误是因为服务器阻塞了Cors请求与一些标题。所以必须允许我的方案中的所有标题。 – Nexus23

+0

@Thierry Templier你可以看看这个[问题](https://stackoverflow.com/questions/45444625/angular-2-httppost-to-oauth2/45444912?noredirect=1#comment77860961_45444912)? –

1

你有任何选项设置到您的cors的web.config文件?即类似<add name="Access-Control-Allow-Origin" value="*"/>

如果是确保删除它,并通过代码只控制Cors。

答案here会帮助你。

8

我在我的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

你把这些线放在哪里? –

+0

在路线声明之前。 –

+0

它工作,谢谢。 我使用了[CORS中间件](https://www.npmjs.com/package/cors),但没有奏效。为什么?这段代码不是在做同样的事吗? –

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; 
} 

或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; 
    } 

记住任何其他你发送你必须添加到服务器头接入控制允许头名单。

0

我与角2工作的前端和的NodeJS(Expressjs)到API

角2是工作在本地主机:3000,并表示正在努力在localhost:8000

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

要解决此问题,您应该告诉节点js接受来自localhost:3000 server ...

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