2016-02-04 105 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