當(dāng)把開發(fā)好的 WebApi 接口,部署到 Windows 服務(wù)器 IIS 后,postman 可以直接訪問到接口并正確返回,這并不意味著任務(wù)完成,畢竟接口嘛是要有交互的,最常見的問題莫過于跨域了。
【資料圖】
若前端文件是在當(dāng)前接口文件下的 wwwroot 文件夾下,那么接口的訪問就沒問題,因?yàn)槭?strong>同協(xié)議(http、https)、同地址(域名)、同端口,不存在跨域問題。
但是,若前端和接口不是部署在一起的,那么一般都會(huì)存在跨域問題,本文將通過兩種方式介紹如何使接口允許跨域請求。
一、IIS 配置實(shí)現(xiàn)1、生效范圍如下圖:
1 位置為 IIS 根目錄,在此屬性中配置“HTTP響應(yīng)標(biāo)頭”時(shí),作用域?yàn)椤熬W(wǎng)站”下級目錄中的全部應(yīng)用。若后面修改了單個(gè)應(yīng)用的 Headers,當(dāng)更新應(yīng)用文件后,修改會(huì)被還原。
2 位置是指定某一網(wǎng)站,在此屬性中配置“HTTP響應(yīng)標(biāo)頭”時(shí),作用域?yàn)楫?dāng)前應(yīng)用,不對其他同級應(yīng)用有影響。
2、常用的配置項(xiàng)共有四個(gè)HTTP 響應(yīng)標(biāo)頭 | 是否必含 | 值 | 解釋 |
Access-Control-Allow-Origin | 是 | * 或 http://IP:Port | 允許跨域請求的地址,* 代表允許全部,若指定地址則僅支持填入一個(gè) |
Access-Control-Allow-Headers | 否 | Content-Type | 當(dāng)接口僅提供 Get 請求時(shí),可省略;另外客戶端添加的自定義請求頭,需再次進(jìn)行允許配置 |
Access-Control-Allow-Methods | 是 | POST, GET, OPTIONS, PUT, DELETE, UPDATE | 此處列出了全部常用的方法名,可根據(jù)需要可適當(dāng)刪除個(gè)別值 |
Access-Control-Allow-Credentials | 否 | 默認(rèn)為 false,可配置為 true | 允許客戶端攜帶驗(yàn)證信息,例如 cookie 之類的。為 true 時(shí),不允許 Origin 設(shè)置為“*” |
主要是通過在 Startup.cs 文件中的 ConfigureServices() 方法添加跨域服務(wù)策略(services.AddCors()),然后在 Configure() 方法中將跨域策略加入到 HTTP 請求管道(HTTP request pipeline)中。
先列舉一個(gè)實(shí)例,.Net 5.0 配置兼容預(yù)檢請求,如下代碼:
public void ConfigureServices(IServiceCollection services){ // ... // 添加跨域策略 services.AddCors(options => { // 配置默認(rèn)策略和中間件:options.AddDefaultPolicy(policy =>{policy.WithOrigins("");});app.UseCors(); // 將自動(dòng)應(yīng)用于所有控制器終結(jié)點(diǎn) options.AddPolicy("CorsPolicyName0519", policy => { policy //.AllowAnyOrigin() // AllowAnyOrigin 允許任何源地址的訪問 .WithOrigins("http://IP:Port") // 僅允許一個(gè)地址訪問 //.WithOrigins(new string[]{"http://IP1:Port1","http://IP2:Port2","http://IP3:Port3"}) // 支持同時(shí)允許多個(gè)指定地址的訪問 //.AllowAnyHeader() // 允許任何的Header頭部標(biāo)題 .WithHeaders("Account", "ClientType", "OrgId", "Token", "Department", "EntAuthVebr") // 自定義請求頭 //.AllowAnyMethod() // 允許任何方法 .WithMethods(HttpMethods.Options, HttpMethods.Get, HttpMethods.Post, HttpMethods.Put, HttpMethods.Delete) // 允許的謂詞方法 //.AllowCredentials() // 允許跨源請求發(fā)送憑據(jù) 允許時(shí) Origin 不允許為“*” .SetPreflightMaxAge(TimeSpan.FromHours(24)); // 設(shè)置預(yù)檢請求的最大緩存時(shí)間 }); });}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){ // ... app.UseCors("CorsPolicyName0519"); // 添加 CORS 中間件,允許跨域訪問 // ...}
跨域請求策略可以同時(shí)配置多個(gè)。
使用[EnableCors] 屬性可以有針對性的啟用同一個(gè) CORS。也可以對需要 CORS 的終結(jié)點(diǎn)配置指定的策略名稱,來實(shí)現(xiàn)最佳控制。
[EnableCors] 指定默認(rèn)策略。[EnableCors("{Policy String}")] 指定命名策略。[EnableCors] 屬性可應(yīng)用于:控制器、控制器操作方法、Razor Page PageModel。
將 [EnableCors] 屬性應(yīng)用于控制器、操作方法或頁面模型,并將中間件加入到管道來啟用 CORS 時(shí), 將這兩種策略將同時(shí)生效。
與 [EnableCors] 相反的,[DisableCors] 屬性標(biāo)識禁用跨域策略。
通常,UseStaticFiles 在 之前 UseCors調(diào)用 。 使用 JavaScript 跨站點(diǎn)檢索靜態(tài)文件的應(yīng)用必須在 UseStaticFiles 之前調(diào)用 UseCors。
2、關(guān)于 設(shè)置允許的發(fā)送請求的源地址 WithOrigins().AllowAnyOrigin:允許具有任何協(xié)議(http 或 https)的所有源的 CORS 請求。也就是說任何網(wǎng)站都可以向應(yīng)用發(fā)出跨域請求,會(huì)導(dǎo)致跨網(wǎng)站請求偽造,因此并不安全。
.WithOrigins("http://IP1:Port1","http://IP2:Port2"):允許同時(shí)配置多個(gè)指定地址。(參數(shù)類型實(shí)際為:new string[]{ })
但是要配置具體的請求地址比較多時(shí),全部通過 string[] 列出的話很不優(yōu)雅,此時(shí)就需要通過通配符域來達(dá)到配置多地址的目的。
例如,當(dāng)需求為允許多個(gè)地址(例如:*.example.com、https://*.example.net 同一后綴的多個(gè)域名通配符)時(shí),就可以用到如下配置:
SetIsOriginAllowedToAllowWildcardSubdomains:將策略的 IsOriginAllowed 屬性設(shè)置為一個(gè)函數(shù),當(dāng)計(jì)算是否允許源時(shí),此函數(shù)允許源匹配已配置的通配符域。
services.AddCors(options =>{ options.AddPolicy(name: MyAllowSpecificOrigins, policy => { policy .WithOrigins("https://*.example.com","https://*.example.net") // 等效于:new string[]{"地址1","地址2"} .SetIsOriginAllowedToAllowWildcardSubdomains(); });});
3、關(guān)于 設(shè)置允許的 HTTP 方法 WithMethods()這個(gè)就沒啥好說的了,需要那種就配置進(jìn)去好了。
常用的就三種:Get、Post、Options。另外不常用的有六種:Put、Delete、Patch、Trace、Connect、Head。詳見:HTTP 請求方法
4、關(guān)于設(shè)置允許的請求頭 WithHeaders().AllowAnyHeader():允許任何名稱的 Header 屬性。這種情況下,很容易出現(xiàn)非默認(rèn)的請求頭,導(dǎo)致觸發(fā)預(yù)檢請求 Options,影響系統(tǒng)性能,下文章節(jié)會(huì)著重介紹。
.WithHeaders(HeaderNames.ContentType, HeaderNames.UserAgent):指定允許多個(gè)請求頭。(參數(shù)類型實(shí)際為:new string[]{ })
當(dāng)客戶端需要添加指定的請求頭,需要在 WithHeaders() 方法中全部配置上。
5、關(guān)于設(shè)置允許的響應(yīng)頭 WithExposedHeaders()默認(rèn)情況下,瀏覽器不會(huì)向應(yīng)用公開所有響應(yīng)頭。默認(rèn)可用的響應(yīng)頭包括:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。
.WithExposedHeaders(HeaderNames.Server,HeaderNames.Status):允許同時(shí)配置多個(gè)響應(yīng)頭。(參數(shù)類型實(shí)際為:new string[]{ })
6、設(shè)置允許跨源域請求發(fā)送憑據(jù) AllowCredentials()憑據(jù)需要在 CORS 請求中進(jìn)行特殊處理。 默認(rèn)情況下,瀏覽器不會(huì)使用跨源域請求發(fā)送憑據(jù)。 憑據(jù)包括 cookie 和 HTTP 身份驗(yàn)證方案。 要使用跨源請求發(fā)送憑據(jù),客戶端必須將 Credentials 設(shè)置為 true,默認(rèn)情況下為 false。
.AllowCredentials():允許跨源請求發(fā)送憑據(jù)。
HTTP 響應(yīng)包含一個(gè) Access-Control-Allow-Credentials 頭,它告訴瀏覽器服務(wù)器允許跨源請求的憑據(jù)。
如果瀏覽器發(fā)送憑據(jù),但響應(yīng)不包含有效的 Access-Control-Allow-Credentials 頭,則瀏覽器不會(huì)向應(yīng)用公開響應(yīng),而且跨源請求會(huì)失敗。
允許跨源憑據(jù)會(huì)帶來安全風(fēng)險(xiǎn)。另一個(gè)域中的網(wǎng)站可以在用戶不知情的情況下代表用戶將登錄用戶的憑據(jù)發(fā)送到應(yīng)用。
CORS 規(guī)范還指出,如果存在 Access-Control-Allow-Credentials 頭,則將源 Origins 設(shè)置為“*”(所有源)是無效的,如下圖報(bào)錯(cuò)提示:
參考: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
三、關(guān)于預(yù)檢請求 Options1、什么是預(yù)檢請求?即“發(fā)送非簡單跨域請求前的預(yù)檢請求”,若該請求未正常返回,瀏覽器會(huì)阻止后續(xù)的請求發(fā)送。
注:Chrome 和 Microsoft Edge 瀏覽器不會(huì)在 F12 工具的 Network 選項(xiàng)卡上顯示 OPTIONS 請求,需要額外配置,打開地址:chrome://flags/#out-of-blink-cors 或 edge://flags/#out-of-blink-cors,禁用,重啟生效;Firefox 瀏覽器默認(rèn)顯示 OPTIONS 請求。
如下圖,是一個(gè)預(yù)檢請求的 headers 信息:
2、什么情況下會(huì)觸發(fā)預(yù)檢請求預(yù)檢請求(Options)屬于實(shí)際請求(Get、Post 等)之外的操作,僅在部分情況下觸發(fā)。
想達(dá)到不觸發(fā) Options 方法的目的,需同時(shí)滿足下面三個(gè)條件:
請求方法為 GET、POST 或 HEAD。應(yīng)用不會(huì)設(shè)置 Content-Type、Content-Language、Accept、Accept-Language 或 Last-Event-ID 以外的請求頭。Content-Type 頭(如果已設(shè)置)具有以下三個(gè)值之一:application/x-www-form-urlencoded、multipart/form-data、text/plain。預(yù)檢請求可能包含以下 Headers:
Access-Control-Request-Method/Methods:將用于實(shí)際請求的 HTTP 方法。Access-Control-Request-Headers:應(yīng)用在實(shí)際請求上設(shè)置的請求頭的列表。 如前文所述,這不包含瀏覽器設(shè)置的標(biāo)頭,如 User-Agent、Host、Content-Length 等。如果預(yù)檢請求被拒絕,應(yīng)用將返回 200 OK 響應(yīng),但不會(huì)設(shè)置 CORS 頭,瀏覽器后續(xù)也就不會(huì)嘗試跨源請求。
3、預(yù)檢請求的 [HttpOptions] 屬性當(dāng)使用適當(dāng)?shù)牟呗詥⒂?CORS 時(shí),ASP.NET Core 通常會(huì)自動(dòng)響應(yīng) CORS 預(yù)檢請求。 但在某些情況下, 例如通過終結(jié)點(diǎn)路由使用 CORS,是不會(huì)自動(dòng)響應(yīng)的。
以下是官網(wǎng)給出的實(shí)例,分別是帶參數(shù)的 Options 請求和不帶參數(shù)兩種:
詳見官網(wǎng):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、設(shè)置預(yù)檢過期時(shí)間 SetPreflightMaxAge()Access-Control-Max-Age 頭指定對預(yù)檢請求的響應(yīng)可以緩存多長時(shí)間。
此方法的目的是在第一次預(yù)檢請求成功后,將預(yù)檢結(jié)果緩存一段時(shí)間,從而避免重復(fù)的預(yù)檢請求,提升應(yīng)用性能。
代碼配置跨域策略時(shí),可通過 .SetPreflightMaxAge() 來實(shí)現(xiàn),如下代碼:
// 添加跨域策略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)) // 設(shè)置預(yù)檢請求的最大緩存時(shí)間 ; });});
參考:https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-6.0#tcer
標(biāo)簽:
- .NET Core 允許跨域的兩種方式實(shí)現(xiàn)(IIS 配置、C# 代碼實(shí)現(xiàn)) 環(huán)球看熱訊
- 全州抽水蓄能和光伏項(xiàng)目推介會(huì)在道孚成功舉辦
- 這些情況要警惕!教育部提示:高校招生錄取期間,謹(jǐn)防受騙
- 7月1日起“港車北上”正式實(shí)施,海關(guān)發(fā)布相關(guān)管理辦法 世界快播報(bào)
- 打擊整治“飆車炸街”,警方一個(gè)月查處相關(guān)案件6500余起|最資訊
- 中國足協(xié)連開5張罰單!多名球隊(duì)官員、隊(duì)員被罰-焦點(diǎn)熱文
- 全球資訊:中興通訊總裁徐子陽:構(gòu)建螺旋DNA 加速數(shù)智新生長
- 新舊生活代際碰撞——《阿爾卡拉斯》|天天快報(bào)
- 拳皇2002加強(qiáng)版八神出招表_2002拳皇八神出招表_全球最資訊
- 思科瑞最新公告:選舉張亞為董事長
- 瑞銀計(jì)劃下月起裁減過半原瑞信員工-天天熱文
- 不死少女 Undead Girl·Murder Farce 第一集 殺鬼 預(yù)告
- 喬喬的奇妙冒險(xiǎn)之小西撒的復(fù)仇之路,二喬戰(zhàn)友的報(bào)仇!revenge of caesar!_當(dāng)前觀察
- 每日消息!【美麗的二次元少女誰不喜歡呢?】第二彈(237)
- 前鋒必看佳作
- 中間難受,結(jié)尾感動(dòng)_天天消息
- V觀財(cái)報(bào)|年報(bào)存虛假記載,宜通世紀(jì)被警告、罰款30萬_新消息
- 雙流區(qū)行政審批局:開展政務(wù)服務(wù)領(lǐng)域問題專項(xiàng)治理 推動(dòng)服務(wù)效能提升
- 雙流區(qū)政務(wù)服務(wù)大廳:“‘政’能量 微服務(wù) 迎大運(yùn)”主題活動(dòng)開展
- 河南開展創(chuàng)新管理知識產(chǎn)權(quán)國際標(biāo)準(zhǔn)實(shí)施試點(diǎn)_環(huán)球熱資訊
- 保險(xiǎn)業(yè)前5月累計(jì)原保費(fèi)收入約2.68萬億元 同比增長10.68% 每日動(dòng)態(tài)
- 世界快訊:王剛主持召開全旗經(jīng)濟(jì)運(yùn)行調(diào)度會(huì)議
- 沉淪過后,他們的人生這樣按下“重啟鍵”
- 家居要聞|索菲亞持股,圖特五金沖刺上市;618家居行業(yè)集體復(fù)蘇,各平臺(tái)銷量增長
- 金藝琳出演新劇《BITCH X RICH》,傳達(dá)劇終感想“是新的挑戰(zhàn)”! 世界熱訊
- 新卡霍夫卡水庫被曬干了,烏軍即將投入9個(gè)旅,想“渡河”強(qiáng)攻?-快消息
- 動(dòng)態(tài):賣房買房中介費(fèi)怎么收費(fèi)
- 中國女籃小組賽三連勝,小組第一晉級半決賽
- 北京:2023年第二次普通高中學(xué)考合格考6月30日開考_天天速遞
- 《新華字典》將“倭寇”一詞刪除?記者探訪:網(wǎng)傳說法不實(shí)|當(dāng)前資訊
- 1 全州抽水蓄能和光伏項(xiàng)目推介會(huì)在道孚成功舉辦
- 2 這些情況要警惕!教育部提示:高校招生錄取期間,謹(jǐn)防受騙
- 3 7月1日起“港車北上”正式實(shí)施,海關(guān)發(fā)布相關(guān)管理辦法 世界快播報(bào)
- 4 打擊整治“飆車炸街”,警方一個(gè)月查處相關(guān)案件6500余起|最資訊
- 5 中國足協(xié)連開5張罰單!多名球隊(duì)官員、隊(duì)員被罰-焦點(diǎn)熱文
- 6 瑞銀計(jì)劃下月起裁減過半原瑞信員工-天天熱文
- 7 不死少女 Undead Girl·Murder Farce 第一集 殺鬼 預(yù)告
- 8 喬喬的奇妙冒險(xiǎn)之小西撒的復(fù)仇之路,二喬戰(zhàn)友的報(bào)仇!revenge of caesar!_當(dāng)前觀察
- 9 每日消息!【美麗的二次元少女誰不喜歡呢?】第二彈(237)
- 10 前鋒必看佳作