當把開發好的 WebApi 接口,部署到 Windows 服務器 IIS 后,postman 可以直接訪問到接口并正確返回,這并不意味著任務完成,畢竟接口嘛是要有交互的,最常見的問題莫過于跨域了。
【資料圖】
若前端文件是在當前接口文件下的 wwwroot 文件夾下,那么接口的訪問就沒問題,因為是同協議(http、https)、同地址(域名)、同端口,不存在跨域問題。
但是,若前端和接口不是部署在一起的,那么一般都會存在跨域問題,本文將通過兩種方式介紹如何使接口允許跨域請求。
一、IIS 配置實現1、生效范圍如下圖:
1 位置為 IIS 根目錄,在此屬性中配置“HTTP響應標頭”時,作用域為“網站”下級目錄中的全部應用。若后面修改了單個應用的 Headers,當更新應用文件后,修改會被還原。
2 位置是指定某一網站,在此屬性中配置“HTTP響應標頭”時,作用域為當前應用,不對其他同級應用有影響。
2、常用的配置項共有四個| HTTP 響應標頭 | 是否必含 | 值 | 解釋 |
| Access-Control-Allow-Origin | 是 | * 或 http://IP:Port | 允許跨域請求的地址,* 代表允許全部,若指定地址則僅支持填入一個 |
| Access-Control-Allow-Headers | 否 | Content-Type | 當接口僅提供 Get 請求時,可省略;另外客戶端添加的自定義請求頭,需再次進行允許配置 |
| Access-Control-Allow-Methods | 是 | POST, GET, OPTIONS, PUT, DELETE, UPDATE | 此處列出了全部常用的方法名,可根據需要可適當刪除個別值 |
| Access-Control-Allow-Credentials | 否 | 默認為 false,可配置為 true | 允許客戶端攜帶驗證信息,例如 cookie 之類的。為 true 時,不允許 Origin 設置為“*” |
主要是通過在 Startup.cs 文件中的 ConfigureServices() 方法添加跨域服務策略(services.AddCors()),然后在 Configure() 方法中將跨域策略加入到 HTTP 請求管道(HTTP request pipeline)中。
先列舉一個實例,.Net 5.0 配置兼容預檢請求,如下代碼:
public void ConfigureServices(IServiceCollection services){ // ... // 添加跨域策略 services.AddCors(options => { // 配置默認策略和中間件:options.AddDefaultPolicy(policy =>{policy.WithOrigins("");});app.UseCors(); // 將自動應用于所有控制器終結點 options.AddPolicy("CorsPolicyName0519", policy => { policy //.AllowAnyOrigin() // AllowAnyOrigin 允許任何源地址的訪問 .WithOrigins("http://IP:Port") // 僅允許一個地址訪問 //.WithOrigins(new string[]{"http://IP1:Port1","http://IP2:Port2","http://IP3:Port3"}) // 支持同時允許多個指定地址的訪問 //.AllowAnyHeader() // 允許任何的Header頭部標題 .WithHeaders("Account", "ClientType", "OrgId", "Token", "Department", "EntAuthVebr") // 自定義請求頭 //.AllowAnyMethod() // 允許任何方法 .WithMethods(HttpMethods.Options, HttpMethods.Get, HttpMethods.Post, HttpMethods.Put, HttpMethods.Delete) // 允許的謂詞方法 //.AllowCredentials() // 允許跨源請求發送憑據 允許時 Origin 不允許為“*” .SetPreflightMaxAge(TimeSpan.FromHours(24)); // 設置預檢請求的最大緩存時間 }); });}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){ // ... app.UseCors("CorsPolicyName0519"); // 添加 CORS 中間件,允許跨域訪問 // ...}跨域請求策略可以同時配置多個。
使用[EnableCors] 屬性可以有針對性的啟用同一個 CORS。也可以對需要 CORS 的終結點配置指定的策略名稱,來實現最佳控制。
[EnableCors] 指定默認策略。[EnableCors("{Policy String}")] 指定命名策略。[EnableCors] 屬性可應用于:控制器、控制器操作方法、Razor Page PageModel。
將 [EnableCors] 屬性應用于控制器、操作方法或頁面模型,并將中間件加入到管道來啟用 CORS 時, 將這兩種策略將同時生效。
與 [EnableCors] 相反的,[DisableCors] 屬性標識禁用跨域策略。
通常,UseStaticFiles 在 之前 UseCors調用 。 使用 JavaScript 跨站點檢索靜態文件的應用必須在 UseStaticFiles 之前調用 UseCors。
2、關于 設置允許的發送請求的源地址 WithOrigins().AllowAnyOrigin:允許具有任何協議(http 或 https)的所有源的 CORS 請求。也就是說任何網站都可以向應用發出跨域請求,會導致跨網站請求偽造,因此并不安全。
.WithOrigins("http://IP1:Port1","http://IP2:Port2"):允許同時配置多個指定地址。(參數類型實際為:new string[]{ })
但是要配置具體的請求地址比較多時,全部通過 string[] 列出的話很不優雅,此時就需要通過通配符域來達到配置多地址的目的。
例如,當需求為允許多個地址(例如:*.example.com、https://*.example.net 同一后綴的多個域名通配符)時,就可以用到如下配置:
SetIsOriginAllowedToAllowWildcardSubdomains:將策略的 IsOriginAllowed 屬性設置為一個函數,當計算是否允許源時,此函數允許源匹配已配置的通配符域。
services.AddCors(options =>{ options.AddPolicy(name: MyAllowSpecificOrigins, policy => { policy .WithOrigins("https://*.example.com","https://*.example.net") // 等效于:new string[]{"地址1","地址2"} .SetIsOriginAllowedToAllowWildcardSubdomains(); });});3、關于 設置允許的 HTTP 方法 WithMethods()這個就沒啥好說的了,需要那種就配置進去好了。
常用的就三種:Get、Post、Options。另外不常用的有六種:Put、Delete、Patch、Trace、Connect、Head。詳見:HTTP 請求方法
4、關于設置允許的請求頭 WithHeaders().AllowAnyHeader():允許任何名稱的 Header 屬性。這種情況下,很容易出現非默認的請求頭,導致觸發預檢請求 Options,影響系統性能,下文章節會著重介紹。
.WithHeaders(HeaderNames.ContentType, HeaderNames.UserAgent):指定允許多個請求頭。(參數類型實際為:new string[]{ })
當客戶端需要添加指定的請求頭,需要在 WithHeaders() 方法中全部配置上。
5、關于設置允許的響應頭 WithExposedHeaders()默認情況下,瀏覽器不會向應用公開所有響應頭。默認可用的響應頭包括:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。
.WithExposedHeaders(HeaderNames.Server,HeaderNames.Status):允許同時配置多個響應頭。(參數類型實際為:new string[]{ })
6、設置允許跨源域請求發送憑據 AllowCredentials()憑據需要在 CORS 請求中進行特殊處理。 默認情況下,瀏覽器不會使用跨源域請求發送憑據。 憑據包括 cookie 和 HTTP 身份驗證方案。 要使用跨源請求發送憑據,客戶端必須將 Credentials 設置為 true,默認情況下為 false。
.AllowCredentials():允許跨源請求發送憑據。
HTTP 響應包含一個 Access-Control-Allow-Credentials 頭,它告訴瀏覽器服務器允許跨源請求的憑據。
如果瀏覽器發送憑據,但響應不包含有效的 Access-Control-Allow-Credentials 頭,則瀏覽器不會向應用公開響應,而且跨源請求會失敗。
允許跨源憑據會帶來安全風險。另一個域中的網站可以在用戶不知情的情況下代表用戶將登錄用戶的憑據發送到應用。
CORS 規范還指出,如果存在 Access-Control-Allow-Credentials 頭,則將源 Origins 設置為“*”(所有源)是無效的,如下圖報錯提示:
參考:https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-6.0#cors-with-named-policy-and-middleware
https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-6.0#set-the-allowed-origins
三、關于預檢請求 Options1、什么是預檢請求?即“發送非簡單跨域請求前的預檢請求”,若該請求未正常返回,瀏覽器會阻止后續的請求發送。
注:Chrome 和 Microsoft Edge 瀏覽器不會在 F12 工具的 Network 選項卡上顯示 OPTIONS 請求,需要額外配置,打開地址:chrome://flags/#out-of-blink-cors 或 edge://flags/#out-of-blink-cors,禁用,重啟生效;Firefox 瀏覽器默認顯示 OPTIONS 請求。
如下圖,是一個預檢請求的 headers 信息:
2、什么情況下會觸發預檢請求預檢請求(Options)屬于實際請求(Get、Post 等)之外的操作,僅在部分情況下觸發。
想達到不觸發 Options 方法的目的,需同時滿足下面三個條件:
請求方法為 GET、POST 或 HEAD。應用不會設置 Content-Type、Content-Language、Accept、Accept-Language 或 Last-Event-ID 以外的請求頭。Content-Type 頭(如果已設置)具有以下三個值之一:application/x-www-form-urlencoded、multipart/form-data、text/plain。預檢請求可能包含以下 Headers:
Access-Control-Request-Method/Methods:將用于實際請求的 HTTP 方法。Access-Control-Request-Headers:應用在實際請求上設置的請求頭的列表。 如前文所述,這不包含瀏覽器設置的標頭,如 User-Agent、Host、Content-Length 等。如果預檢請求被拒絕,應用將返回 200 OK 響應,但不會設置 CORS 頭,瀏覽器后續也就不會嘗試跨源請求。
3、預檢請求的 [HttpOptions] 屬性當使用適當的策略啟用 CORS 時,ASP.NET Core 通常會自動響應 CORS 預檢請求。 但在某些情況下, 例如通過終結點路由使用 CORS,是不會自動響應的。
以下是官網給出的實例,分別是帶參數的 Options 請求和不帶參數兩種:
詳見官網:https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-6.0#tcer
[Route("api/[controller]")][ApiController]public class TodoItems2Controller : ControllerBase{ // OPTIONS: api/TodoItems2/5 [HttpOptions("{id}")] public IActionResult PreflightRoute(int id) { return NoContent(); } // OPTIONS: api/TodoItems2 [HttpOptions] public IActionResult PreflightRoute() { return NoContent(); }}4、設置預檢過期時間 SetPreflightMaxAge()Access-Control-Max-Age 頭指定對預檢請求的響應可以緩存多長時間。
此方法的目的是在第一次預檢請求成功后,將預檢結果緩存一段時間,從而避免重復的預檢請求,提升應用性能。
代碼配置跨域策略時,可通過 .SetPreflightMaxAge() 來實現,如下代碼:
// 添加跨域策略services.AddCors(options =>{ options.AddPolicy("CorsPolicyName007", policy => { policy .WithOrigins("http://127.0.0.1:7000" , "http://127.0.0.1:8000" ) .SetPreflightMaxAge(TimeSpan.FromHours(24)) // 設置預檢請求的最大緩存時間 ; });});參考:https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-6.0#tcer
標簽:
- 淮劇《小白楊》深情上演 致敬一代代援疆人的“精神豐碑”
- 寧德時代出資20億元在洛陽成立新公司 經營范圍含電池制造等業務_即時焦點
- 小法:我尊重圖多爾但他不尊重我,溫格觀戰是我給他買的票_今日快看
- 農發行湖南省分行違反金融統計規定被警告并罰款135.4萬元 速讀
- 黃曉明回應為新戲增肥30斤:這是我人生中最快樂的時光 觀速訊
- 每日動態!國家統計局:9月份社會消費品零售總額增長3.0%
- 中國之變|這五年,數字化點亮新生活-每日觀點
- 大行評級丨里昂:上調臺積電目標價至2000新臺幣 維持“高度確信跑贏大市”評級_每日時訊
- 熱消息:內蒙古赤峰農村牧區產權流轉服務中心完成首單交易
- 熱資訊!贛C支持湘C!宜春“老表”跨城應援
- 丹尼-格林:姚明如不傷難以想象,文班或能成為他本該成為的人
- 房產投資的風險與收益權衡?
- 鼎佳精密:10月17日獲融資買入291.41萬元_快資訊
- 財報速遞:達瑞電子2025年前三季度凈利潤2.31億元 每日動態
- 廣州湛建建材有限公司成立 注冊資本10萬人民幣|焦點快播
- 今日熱搜:時空科技擬“跨界”收購 切入半導體存儲賽道
- 當前聚焦:佑駕創新中標1185萬元車路云一體化城市交通融合感知項目
- 中原證券擬實施2025年半年度權益分派,共計派發現金紅利3714.31萬元-當前熱議
- 每日視點!主場戰三鎮賽前,大連英博為隊史首位外援羅伯森舉辦退役儀式
- 祥生醫療前三季度營業收入3.43億元,同比下降5.27%
- 江蘇最低工資標準公布
- 首佳科技于10月17日耗資56萬港元回購70萬股-每日消息
- 靳東:延安的變化讓人刮目相看_焦點簡訊
- 當前關注:凡人微光|這座城的精神,正年輕!
- 又見中小銀行密集調降存款利率-簡訊
- 前沿熱點:思源電氣前三季度凈利21.91億元,同比增長46.94%
- 今日快看!劉浩存談藝術的生命力
- 要聞:呂瑞浩公參會見上海市疾控局團組
- 光庭信息:2025年前三季度凈利潤4477.54萬元 同比增長308.53%_最新資訊
- 拿起手機就能免費聽講座、看展覽 “十四五”期間多彩文化點亮生活





