同源策略_如何支持跨域
歡迎大家閱讀《朝夕Net社區技術專刊》
我們致力于.NetCore的推廣和落地,為更好的幫助大家學習,方便分享干貨,特創此刊!很高興你能成為忠實讀者,文末福利不要錯過哦!
01
PART
CoreWebApi的調用
1.在Core MVC下建立WebApi—CrossDomainController控制器下的GetCrossDomainData api,如圖1所示;啟動后通過瀏覽器調用正常如圖2;
圖1
圖2
2.那么試試Ajax調用試試呢?如圖3,如果請求到,就把結果放到div 中去;那運行的時候,不僅沒有獲取到數據,而且還報錯了如圖4.
圖3
圖4
那么這里的問題就是瀏覽器的同源策略,引發的跨域問題;下面將把這個問題的根本緣由給大家做一下說明.
02
PART
瀏覽器同源策略
什么是同源策略?同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,請明確:他是瀏覽器的安全約定。所謂的同源,指的是協議,域名,端口相同。瀏覽器處于安全方面的考慮,只允許本域名下的接口交互,不同源的客戶端腳本,在沒有明確授權的情況下,不能讀寫對方的資源。
設想這樣一種情況:A網站是一家銀行,用戶登錄以后,又去瀏覽其他的網站,如果其他網站可以讀取A網站的Cookie,會發生什么?很顯然,如果Cookie包含隱私(比如存款總額),這些信息就會泄漏。更可怕的是Cookie往往用來保存用于的登錄狀態,如果用戶沒有退出登錄,其他網站就可以冒充用戶為所欲為,因為瀏覽器同時還規定,提交表單不受同源策略的限制。由此可見,同源策略是必須的。如果非同源,那么在請求數據時,瀏覽器會在控制臺中報一個異常,提示拒絕訪問;如圖5。
圖5
那么上面我們在調用的時候就是因為這個問題、Ajax的腳本,和Api非同源;Ajax請求Api的時候,違背了瀏覽器的這個約定,所以不能用;其實Ajax在請求的時候,是能夠請求到Api的,Api也返回了數據;卻因為瀏覽的同源要求,而報錯了;下面給大家證明一下:運行Api:Api打斷點:測試起來。。。如圖6 ?、圖7所示;
圖6???
斷點能進來
圖7??
但是就是報錯,瀏覽器限制了;不能用;
以上描述的就是瀏覽器的同源策略? ?在非同源的情況下使用腳本調用Api會報錯的;這就是所謂的跨域問題。
03
PART
如何解決跨域問題?
首先來分析一下出這個問題的原因;是因為瀏覽器的約定而出現的;那么如果我不使用非同源的腳本來調用呢?是可以的;定義一個Api 模擬Http請求去請求這個非同源的Api;
第一步:定義定義Api 模擬http請求:
我這里是另外又建立了一個項目:模擬http請求;調用這個Api,讓這個后臺的Api再去調用非同源的Api-- GetCrossDomainData
第二步:運行起來:
包括運行GetCrossDomainDataApi所在的項目;命令啟動:dotnet Zhaoxi.Core.WebApi.dll --urls="http://*:8004" -- ip="127.0.0.1" --port= 8004;監控的端口號為8004;
?
然后啟動調用GetCrossDomainDataApi的項目:試試看;如圖8 圖9
圖8
命令啟動了;監控的是8004端口
圖9
調用TestApi 方法;讓其執行InvokeApi方法,去調用
GetCrossDomainDataApi;
執行結果:如圖10
圖10??
結果拿到了;避開了跨域問題;
那就是解決跨域問題的第一種策略:通過后臺模擬Http請求,去調用Api,可以避開跨域問題;因為跨域是因為瀏覽器的同源引發的、不使用非同源的腳本去調用時Ok的;是不是很棒??
這是第一種策略:我們再往下分析;看看剛剛在調用的時候,報的錯是什么?
Access to XMLHttpRequest at 'http://localhost:64304/api/CrossDomain/GetCrossDomainData' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
其實這個提示也很明確哦:提示請求上下文不存在“Access-Control-Allow-origin” 頭信息;那是不是加上這個頭信息就Ok了呢?來試試看:請看下圖11;僅僅只是加了一段代碼。
圖11
再來試試。。。來運行起來!還是命令啟動:dotnet Zhaoxi.Core.WebApi.dll --urls="http://*:8004" --????? ??????? ???? ?????? ip="127.0.0.1" --port= 8004 如圖12
圖12
Ajax調用:如圖13 ?圖14
圖13
圖14
這其實也是解決跨域的常用方法;就是在瀏覽器直接標記告訴調用者,Ok,我這個Api是允許你跨域訪問的;僅此而已,是不是很簡單?
不過如果用這種方法來支持跨域,難道在每個方法中都標記:HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");這句話嗎?這很顯然很不爽;
還記不記得,前面的文章中寫了ActionFilter的使用?在這里是不是很適合?
OK 馬上給你實現一個,定義個Filter,標記在方法上,如果需要所有Api 都跨域的話,全局注冊即可;請看下圖15 ?圖16
圖15
圖16
測試結果如下:沒毛病,完美解決問題;如圖17
圖17
以上也是解決跨域問題的常用策略;是通過在服務器指定當前Api允許跨域訪問的方式;
下面我將繼續給大家分享一種解決跨域問題的方式:其實在AspNetCore 中已經有支持跨域的Api;聽我慢慢道來;
第一步:Nuget引入程序包:Microsoft.AspNetCore.Cors.dll
第二步:注冊跨域服務:如圖18
???
圖18
?
第三步:use 跨域中間件:如圖19
圖19
?
測試結果如下:圖20
圖20
這里一共介紹了三種支持跨域的方式:
1.???通過后臺模擬Http請求跨域
2.???服務器標記頭信息?context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
3.???通過定義ActionFilter支持跨域其實和第二種原理一樣;
4.???通過AspNetCore封裝好的Cors來支持跨域;
下期預告
【朝夕Net社區技術專刊】
論ORM框架—EntityFrameworkCore
總結
以上是生活随笔為你收集整理的同源策略_如何支持跨域的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 就喜欢用vSphere部署K8s集群,不
- 下一篇: 企业数字化转型解决方案