国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Cors跨域(四):解決方案對(duì)決JSONP vs CORS

開發(fā) 前端
當(dāng)被瀏覽器半信半疑的腳本運(yùn)行在沙箱時(shí),它們應(yīng)該只被允許訪問來自同一站點(diǎn)的資源,而不是那些來自其它站點(diǎn)可能懷有惡意的資源。但是呢,在現(xiàn)在的互聯(lián)網(wǎng)場景中,跨域訪問是一種必須,所以才有了解決跨域問題的方案。

[[407226]]

前言

你好,我是YourBatman。

挖掘機(jī)技術(shù)哪家強(qiáng),山東技校找藍(lán)翔;跨域問題怎么解,CORS還是JSONP?

關(guān)于瀏覽器跨域問題的解決方案,坊間一直“傳聞”著兩種解決方案:JSONP和CORS。由于文章的歷史背景不同,作者偏好不一樣,搞得好些同學(xué)迷惑得很,去谷歌里百度搜尋答案時(shí)經(jīng)常就是這種趕腳。

作為一家負(fù)責(zé)任的“技校”(負(fù)責(zé)人的技術(shù)專欄),今天通過此文徹底給你解釋清楚并給出確定的答案,助你快速選擇正確的道路解決問題。

所屬專欄

  • 點(diǎn)撥-Cors跨域

本文提綱

版本約定

  • JDK:8
  • Servlet:4.x
  • tomcat:9.x

正文

同源策略是瀏覽器最核心也最基本的安全功能。當(dāng)被瀏覽器半信半疑的腳本運(yùn)行在沙箱時(shí),它們應(yīng)該只被允許訪問來自同一站點(diǎn)的資源,而不是那些來自其它站點(diǎn)可能懷有惡意的資源。但是呢,在現(xiàn)在的互聯(lián)網(wǎng)場景中,跨域訪問是一種必須,所以才有了解決跨域問題的方案。

兩大方案:JSONP和CORS

對(duì)于跨域共享資源,一共有兩大解決方案

  • JSONP:老一代瀏覽器解決方案
  • CORS:全新一套標(biāo)準(zhǔn)的解決方案

JSONP方案

和iPhone 7和iPhone 7P不一樣,JSONP 不等于 JSON Plus,全稱是JSON with Padding。JSON是一種基于文本的數(shù)據(jù)交換格式,而JSONP是一種使用模式,可以讓網(wǎng)頁從別的域訪問資源,從而完成跨域資源共享。

本系列第一篇文章就說到:<script>標(biāo)簽的src是沒有跨域這么一說的,可以基于這一點(diǎn)實(shí)現(xiàn)Get請(qǐng)求的跨域。

JSONP的實(shí)現(xiàn)跨域的基本原理是:利用script標(biāo)簽的src沒有跨域限制 + 回調(diào)的方式來完成跨域訪問。

代碼實(shí)現(xiàn)示例

前端頁面:托管在63342端口

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3. <head> 
  4.     <meta charset="UTF-8"
  5.     <title>JSONP跨域請(qǐng)求</title> 
  6.     <!--導(dǎo)入Jquery--> 
  7.     <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> 
  8. </head> 
  9. <body> 
  10. <script> 
  11.     // 請(qǐng)求完成后會(huì)回調(diào)此函數(shù) 
  12.     function jsonpCallback(result) { 
  13.         console.log("這是JSONP請(qǐng)求的響應(yīng)結(jié)果:" + result); 
  14.     } 
  15. </script> 
  16. <!--注:這個(gè)script必須放在上面function的下面--> 
  17. <script type="text/javascript" src="http://localhost:8080/jsonp?callback=jsonpCallback"></script> 
  18. </body> 
  19. </html> 

說明:利用script的src發(fā)送http請(qǐng)求到服務(wù)端,因此此script標(biāo)簽務(wù)必放在function的下面(因?yàn)闉g覽器是從上至下渲染)

服務(wù)端代碼:托管在8080端口

  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. <a href=mailto:yourbatman@aliyun.com>Send email to me</a> 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/6/9 10:36 
  7.  * @since 0.0.1 
  8.  */ 
  9. @Slf4j 
  10. @WebServlet(urlPatterns = "/jsonp"
  11. public class JSONPServlet extends HttpServlet { 
  12.  
  13.     @Override 
  14.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  15.         String callback = req.getParameter("callback"); 
  16.         resp.getWriter().write(callback + "('hello jsonp...')"); 
  17.     } 

說明:可以看到服務(wù)端的代碼非常的清爽,不涉及到任何請(qǐng)求頭/響應(yīng)頭

打開頁面,發(fā)送JSONP請(qǐng)求,結(jié)果如下:

請(qǐng)求的響應(yīng)體:

瀏覽器控制臺(tái)輸出:

完美。通過JSONP我們實(shí)現(xiàn)了訪問不同域的資源,實(shí)現(xiàn)了跨域。

用jQuery的ajax發(fā)送異步JSONP請(qǐng)求

上例是使用<script>標(biāo)簽的src屬性發(fā)送同步跨域請(qǐng)求,在實(shí)際開發(fā)中(特別是前后端分離)大多數(shù)情況下發(fā)送的均為Ajax異步請(qǐng)求,下面來試試。

說明:異步請(qǐng)求用原生XMLHttpRequest還是Ajax或者Promis方式發(fā)出,底層原理都?xì)w一是相同的

使用jQuery發(fā)送異步JSONP請(qǐng)求非常的簡單,連<script>和函數(shù)都不用寫:

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3. <head> 
  4.     <meta charset="UTF-8"
  5.     <title>JSONP跨域請(qǐng)求</title> 
  6.     <!--導(dǎo)入Jquery--> 
  7.     <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> 
  8. </head> 
  9. <body> 
  10. <!--<script>--> 
  11. <!--    // 請(qǐng)求完成后會(huì)回調(diào)此函數(shù)--> 
  12. <!--    function jsonpCallback(result) {--> 
  13. <!--        console.log("這是JSONP請(qǐng)求的響應(yīng)結(jié)果:" + result);--> 
  14. <!--    }--> 
  15. <!--</script>--> 
  16. <!--&lt;!&ndash;注:這個(gè)script必須放在上面function的下面&ndash;&gt;--> 
  17. <!--<script type="text/javascript" src="http://localhost:8080/jsonp?callback=jsonpCallback"></script>--> 
  18. <script> 
  19.     $.ajax({ 
  20.         // type: "get", // 不用寫方法,因?yàn)镴SONP只支持GET請(qǐng)求 
  21.         url: "http://localhost:8080/jsonp", // 使用jQuery的Ajax后面是沒有參數(shù) 
  22.         dataType: 'jsonp'
  23.         success: function (data) { 
  24.             console.log("這是JSONP請(qǐng)求的響應(yīng)結(jié)果(jQuery Ajax):" + data); 
  25.         }, 
  26.     }); 
  27. </script> 
  28. </body> 
  29. </html> 

通過jQuery大大改善了js代碼的書寫方式,使得結(jié)構(gòu)更加優(yōu)雅、直觀。這就是jQuery最厲害的語法糖能力~

說明:JsonP only works with type: GET。也就說type即使你寫成post,jQuery也會(huì)給你轉(zhuǎn)成get

服務(wù)端不變,發(fā)送異步請(qǐng)求,結(jié)果如下: 

關(guān)注點(diǎn):

  1. Ajax的callback回調(diào)函數(shù)名是動(dòng)態(tài)生成的,并且確保了唯一性
  2. 由于服務(wù)端并不關(guān)心回調(diào)的函數(shù)名名稱,因此回調(diào)函數(shù)名的長短沒有關(guān)系(瀏覽器自己能識(shí)別就成)

影響體如下:

瀏覽器控制臺(tái)打印:

完美。對(duì)于有技術(shù)敏感性的你來講,應(yīng)該能發(fā)現(xiàn)底層原理依舊還是script的src,只是寫法不一樣,僅此而已。

優(yōu)缺點(diǎn)

JSONP跨域方案作為一種“古老”方式,有如下優(yōu)缺點(diǎn):優(yōu)點(diǎn):

  • 對(duì)老瀏覽器(如IE8、7等)有非常好的兼容性
  • 書寫起來比較簡單,容易理解(畢竟沒有那么多的請(qǐng)求頭、響應(yīng)頭需要考慮嘛)

缺點(diǎn):

  • 只能發(fā)送get請(qǐng)求,不支持POST、PUT等請(qǐng)求方式,這是硬傷
  • 安全度不高。因?yàn)镴SONP是利用函數(shù)回調(diào)來由瀏覽器執(zhí)行目標(biāo)函數(shù),這樣宿主web其實(shí)是比較容易受到各類攻擊的

總的來講,隨著Cors規(guī)范在2014年的正式確定,現(xiàn)代的瀏覽器100%支持Cors規(guī)范。由于瀏覽器的更新?lián)Q代,JSONP的最大優(yōu)勢(shì)(兼容老瀏覽器)也就不復(fù)存在了,所以在實(shí)際開發(fā)中的使用建議是:不要使用JSONP,而應(yīng)擁抱CORS。

CORS方案

由于JSONP方案存在一些不足(比如只支持Get請(qǐng)求就是硬傷),并不能很好的滿足對(duì)跨域資源共享的需求,因此就出現(xiàn)了當(dāng)下主流的跨域規(guī)范:CORS(Cross-origin resource sharing)

不同于JSONP的方案,CORS方案更強(qiáng)大實(shí)用,但稍微復(fù)雜那么一丟丟。其背后的基本思想是:使用自定義的HTTP頭部和瀏覽器“溝通”,讓瀏覽器和服務(wù)器相互“了解”對(duì)方,從而決定請(qǐng)求或響應(yīng)成功與否。

說明:CORS 并不是為了解決服務(wù)端安全問題而出現(xiàn),而是為了解決如何跨域調(diào)用資源。至于如何設(shè)計(jì)出安全的、開放的API,這就是安全范疇了(如可加上token驗(yàn)證、請(qǐng)求有效期、ip來源驗(yàn)證等手段)

CORS的WD(工作草案)從2009-03-17開始,2014-01-16進(jìn)入REC(推薦標(biāo)準(zhǔn))階段,可謂正式畢業(yè)。起初CORS的推廣的主要障礙是當(dāng)時(shí)市面上的老瀏覽器并不支持它(比如當(dāng)時(shí)市場占有率極大的IE 6、7、8這種老家伙),畢竟這個(gè)規(guī)范是新的只有升級(jí)的新瀏覽器才會(huì)支持到。

但歷史的巨輪永遠(yuǎn)是滾滾向前,現(xiàn)在已經(jīng)2021年了,現(xiàn)今市面上的瀏覽器對(duì)CORS規(guī)范的支持情況如下圖所示(數(shù)據(jù)來源于:http://caniuse.com):

看到這張圖,應(yīng)該可以毫不客氣的說:所有的瀏覽器(包括手機(jī)、PAD等瀏覽器)均已支持CORS規(guī)范

版本上拿Chrome瀏覽器舉例:我現(xiàn)在使用的版本是91.0.xxxx.xxx,完美支持:

當(dāng)下階段,已完全無需考慮瀏覽器兼容問題,所以JSONP的優(yōu)勢(shì)也就不復(fù)存在,可以放心的、積極的擁抱CORS。既然要用CORS,作為程序員不能只停留在概念上層面,接下來就來聊點(diǎn)干的,看看從實(shí)操層面有哪些具體做法落地CORS呢?

CORS的核心要義是和服務(wù)端和瀏覽器進(jìn)行溝通,服務(wù)端架構(gòu)一般是分層的,理論上可以在任意層次完成溝通。從負(fù)責(zé)完成溝通的層次上來講,一般分為這兩大類:

  1. 代理服務(wù)器/網(wǎng)關(guān)負(fù)責(zé)
  2. Web應(yīng)用自行負(fù)責(zé)

代理服務(wù)器/網(wǎng)關(guān)方

式眾所周知,一般的架構(gòu)不會(huì)是瀏覽器->后端服務(wù)點(diǎn)對(duì)點(diǎn), 而是會(huì)設(shè)計(jì)(很多)中間層,比如代理服務(wù)器、網(wǎng)關(guān)等。就像這樣:

既然如此,我們就多了一些手段來處理Cors。

從“距離”上看,我們可以在離瀏覽器最近的地方(流量入口處如Nginx,Gateway等)把Cors跨域問題搞定,這樣后端Web Server就無需再操心了,可謂十分方便。

下面以Nginx為例,看看如何落地?

  1.  
  2. # Wide-open CORS config for nginx ### 沒有保護(hù)的(潛臺(tái)詞:有安全風(fēng)險(xiǎn)的)NG Cors配置 
  3. location / { 
  4.   
  5.   ### 在Ng層就把Options請(qǐng)求全部攔截掉,不會(huì)下層到后面的web應(yīng)用 
  6.      if ($request_method = 'OPTIONS') { 
  7.       
  8.         ### 使用*通配符表示允許所有的Origin源 
  9.         add_header 'Access-Control-Allow-Origin' '*'
  10.         # 
  11.         # Om nom nom cookies 
  12.         # 
  13.         add_header 'Access-Control-Allow-Credentials' 'true'
  14.         add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; ### 若有需要,可增加PUT、DELETE等請(qǐng)求 
  15.  
  16.         # 
  17.         # Custom headers and headers various browsers *should* be OK with but aren't 
  18.         # 
  19.         ### 允許自定義的請(qǐng)求頭(根據(jù)需要,自行刪減哈) 
  20.         add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'
  21.  
  22.         # 
  23.         # Tell client that this pre-flight info is valid for 20 days 
  24.         # 
  25.         ### 允許預(yù)檢請(qǐng)求緩存20天之久(根據(jù)需要自行調(diào)整) 
  26.         add_header 'Access-Control-Max-Age' 1728000; 
  27.         add_header 'Content-Type' 'text/plain charset=UTF-8'
  28.         add_header 'Content-Length' 0; 
  29.         return 204; 
  30.      } 
  31.   
  32.   ### 因?yàn)樯厦鍻PTIONS只允許了GET/POST所以這里就只列出兩,根據(jù)需要自行增減哦 ### 
  33.      if ($request_method = 'POST') { 
  34.         add_header 'Access-Control-Allow-Origin' '*'
  35.         add_header 'Access-Control-Allow-Credentials' 'true'
  36.         add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'
  37.         add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'
  38.      } 
  39.      if ($request_method = 'GET') { 
  40.         add_header 'Access-Control-Allow-Origin' '*'
  41.         add_header 'Access-Control-Allow-Credentials' 'true'
  42.         add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'
  43.         add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'
  44.      } 

這是一段比較“著名”的、通用的Nginx解決Cors問題的配置。這段配置基本能夠解決絕大多數(shù)的跨域請(qǐng)求case,但也正是因?yàn)樗耐ㄓ眯裕瑤в腥缦虏蛔悖?/p>

  1. Access-Control-Allow-Origin為通配符*,表示所有的Origin都能訪問本站資源,安全性低
  2. Access-Control-Allow-Origin響應(yīng)頭只允許有一個(gè)(有多個(gè)就會(huì)報(bào)錯(cuò)),而把它寫進(jìn)了NG,導(dǎo)致后端Web應(yīng)用無法對(duì)它進(jìn)行精細(xì)化控制了
  3. Access-Control-Allow-Credentials的值恒定設(shè)置為true。在本系列第二篇文章提到:當(dāng)需要跨域請(qǐng)求攜帶cookie等驗(yàn)證信息時(shí),Access-Control-Allow-Origin頭的值是不允許為*的,而NG這一層對(duì)此又限制了

總而言之言而總之,在離瀏覽器最近的地方處理Cors有優(yōu)有劣。優(yōu)點(diǎn)是通用性很好、“體驗(yàn)”也最好(web server無需感知),但也應(yīng)當(dāng)知曉它的劣勢(shì),如安全性低、個(gè)性化性差(因?yàn)闊o法感知到業(yè)務(wù)需求嘛)。萬物具有兩面性,請(qǐng)勿一刀切,要因地制宜呀。

一般來講純前端靜態(tài)資源的跨域資源共享可用Ng形式統(tǒng)一處理,但對(duì)于服務(wù)端(后端)Web應(yīng)用的API接口資源管理,由于場景較為復(fù)雜,對(duì)安全性要求頗高,因此還是交給給應(yīng)用自行管理更為合適

Gateway網(wǎng)關(guān)方式

網(wǎng)關(guān)也可認(rèn)為是一種代理服務(wù)器,屬于中間層中的一層。不過相較于Nginx來講,它的可編程性更強(qiáng)一些,因此很多時(shí)候?qū)ors邏輯放到網(wǎng)關(guān)層具有更大的靈活性(特別是內(nèi)網(wǎng)網(wǎng)關(guān)),起到一個(gè)折中的效果。

Web應(yīng)用方式

Web應(yīng)用是離瀏覽器“最遠(yuǎn)”的地方,在這里解決Cors對(duì)應(yīng)用侵入性最大。但是呢,由于能感知到業(yè)務(wù)(如知道有哪些接口、哪些功能)的存在,所以就能做到精細(xì)化控制,安全性最高,個(gè)性化最強(qiáng),因此具體落地處理方式也有多種。

1. 硬編碼方式

顧名思義,就是在實(shí)際處理請(qǐng)求的代碼前/中/后通過硬編碼的方式解決。本系列前面文章給出的代碼示例,為了便于理解均是這種硬編碼方式。

  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. <a href=mailto:yourbatman@aliyun.com>Send email to me</a> 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/6/9 10:36 
  7.  * @since 0.0.1 
  8.  */ 
  9. @Slf4j 
  10. @WebServlet(urlPatterns = "/cors"
  11. public class CorsServlet extends HttpServlet { 
  12.  
  13.     @Override 
  14.     protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  15.         super.doOptions(req, resp); 
  16.         setCrosHeader(resp); 
  17.     } 
  18.  
  19.     @Override 
  20.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  21.         String requestURI = req.getRequestURI(); 
  22.         String method = req.getMethod(); 
  23.         String originHeader = req.getHeader("Origin"); 
  24.         log.info("收到請(qǐng)求:{},方法:{}, Origin頭:{}", requestURI, method, originHeader); 
  25.  
  26.         resp.getWriter().write("hello cors..."); 
  27.         setCrosHeader(resp); 
  28.     } 
  29.  
  30.     private void setCrosHeader(HttpServletResponse resp) { 
  31.         resp.setHeader("Access-Control-Allow-Origin""http://localhost:63342"); 
  32.         resp.setHeader("Access-Control-Expose-Headers""token,secret"); 
  33.         resp.setHeader("Access-Control-Allow-Headers""token,secret"); // 一般來講,讓此頭的值是上面那個(gè)的【子集】(或相同) 
  34.     } 

優(yōu)點(diǎn):個(gè)性化極強(qiáng),可以針對(duì)接口級(jí)別給出不同的CORS邏輯,精細(xì)化控制缺點(diǎn):侵入性從應(yīng)用級(jí)別上升到了業(yè)務(wù)代碼級(jí)別,顯得十分臃腫,粒度太細(xì)后期維護(hù)成本高

2. 自定義Filter/Interceptor

既然是Filter那便屬于“批處理”方案:對(duì)整個(gè)應(yīng)用做Cors的統(tǒng)一邏輯處理

  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. <a href=mailto:yourbatman@aliyun.com>Send email to me</a> 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/6/14 09:50 
  7.  * @since 0.0.1 
  8.  */ 
  9. public class CORSFilter implements Filter { 
  10.  
  11.     @Override 
  12.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
  13.         HttpServletResponse resp = (HttpServletResponse) response; 
  14.         resp.addHeader("Access-Control-Allow-Credentials""true"); 
  15.         resp.addHeader("Access-Control-Allow-Origin""*"); 
  16.         resp.addHeader("Access-Control-Allow-Methods""GET, POST, DELETE, PUT"); 
  17.         resp.addHeader("Access-Control-Allow-Headers""Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN"); 
  18.         if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) { 
  19.             resp.getWriter().println("ok"); 
  20.             return
  21.         } 
  22.         chain.doFilter(request, resp); 
  23.     } 
  24.      

優(yōu)點(diǎn):應(yīng)用級(jí)別的統(tǒng)一處理,對(duì)業(yè)務(wù)代碼無侵入性。應(yīng)用內(nèi)集中化處理Cors邏輯,維護(hù)方便缺點(diǎn):無法做到接口級(jí)別的粒度,對(duì)于某些特殊要求的細(xì)粒度控制自然就無能為力

說到底,上例中的自定義Filter的方式仍屬于硬編碼方式(將影響Cors的相關(guān)頭信息寫死的),不夠靈活。其實(shí)可以再優(yōu)化一下,讓其更富彈性。為此,早在N年之前就有eBay開源的過濾器方案:cors-filter.java 供以參考。

  1. <dependency> 
  2.  <groupId>org.ebaysf.web</groupId> 
  3.  <artifactId>cors-filter</artifactId> 
  4.  <version>1.0.1</version> 
  5. </dependency> 

它可以讓允許的origins、methods、headers等都支持可配置化,更富彈性。

3. Spring Framework方式

調(diào)研一下:現(xiàn)在做Java(Web)開發(fā),應(yīng)該沒有不使用Spring Framework的吧?

Spring自4.2版本(2015-06)開始,就提供了對(duì)Cors的全面支持,大大簡化應(yīng)用級(jí)Cors問題的處理。其中面向開發(fā)者提供了兩個(gè)用于優(yōu)雅處理Cors問題的組件:

  • @CrossOrigin:借助此注解可以通過聲明式方式,對(duì)類級(jí)別、甚至接口級(jí)別進(jìn)行跨域的資源控制
  • CorsFilter:Spring也提供了用于“全局處理”的過濾器,兼具了普適性和靈活性

WebMvcConfigurer:這是一種配置方式,嚴(yán)格來講不算一種解決方案而是一種落地方式而已

由于Java開發(fā)者一直和Spring打交道,因此深入理解此場景下的解決方案,打通其執(zhí)行原理方可使用起來得心應(yīng)手,所以這也是本系列關(guān)心的重中之重。關(guān)于此part本系列下文會(huì)單獨(dú)成篇解讀,包括使用姿勢(shì)到設(shè)計(jì)思想、源碼分析.....

4. Spring Boot方式

如你所知,Spring Boot是構(gòu)建在Spring Framework之上的。在Cors這塊Spring Boot并未對(duì)其做增強(qiáng)or擴(kuò)展,因此使用姿勢(shì)上同Spring Framework。

這是不是再一次驗(yàn)證了那句話:在Spring Boot上能走多遠(yuǎn)由你對(duì)Spring Framework的了解深度而決定

Cors安全漏洞

瀏覽器的同源策略(SOP)是一個(gè)安全基石。SOP是一個(gè)很好的策略,但是隨著Web應(yīng)用的發(fā)展,網(wǎng)站由于自身業(yè)務(wù)的需求,需要實(shí)現(xiàn)一些跨域的功能,能夠讓不同域的頁面之間能夠相互訪問各自頁面的內(nèi)容,這就導(dǎo)致SOP策略不是那么的湊效了。

Cors作為當(dāng)下解決瀏覽器跨域問題的標(biāo)準(zhǔn)方案,如若使用不當(dāng)是會(huì)帶來安全漏洞,造成隱患的。其中最常見的便是:Access-Control-Allow-Origin: *到底。殊不知,*用于表示允許任意域訪問,這種配置一般只用于共享公開資源。如果用于非公共資源的話,那就相當(dāng)于擊穿了瀏覽器的同源策略,給所有Origin授權(quán)。

其實(shí)這和授權(quán)授信有點(diǎn)像,當(dāng)授權(quán)范圍越大,方便的是操作/管理上,但這就容易被利用而被攻擊。因此在允許的情況下,能粒度小點(diǎn)就盡量精細(xì)化控制(特別是敏感資源、接口),畢竟安全無小事。

Access-Control-Allow-Origin既然不建議配置為*,那么如何允許多域名呢?本系列上篇文章有詳細(xì)分析,請(qǐng)參考:Access-Control-Allow-Origin

安全性這個(gè)東西是相對(duì)的,沒有絕對(duì)的安全,也做不到絕對(duì)的安全。我們能做的,就是盡量去解決已知的安全性問題,不要讓“入侵”來得很容易即可。

JSONP與CORS對(duì)比

JSONP與CORS的使用目的相同,并且都需要服務(wù)端和客戶端同時(shí)支持,雖然功能上講CORS更為強(qiáng)大,但......下面進(jìn)行對(duì)比下

1.JSONP的最主要優(yōu)勢(shì)是對(duì)(老)瀏覽器的支持很好,而CORS由于出現(xiàn)較晚(2014年確定)這方面稍差~

  • 不過,還是那句話:現(xiàn)在都2021年了,在瀏覽器支持方面可以幾乎不用再作考慮

2.JSONP 只能 用于Get請(qǐng)求,而CORS能用于所有的Http Method。這一點(diǎn)上JSONP被完虐

3.JSONP的錯(cuò)誤處理機(jī)制不完善(其實(shí)是沒有),當(dāng)發(fā)生錯(cuò)誤時(shí)開發(fā)者無法進(jìn)行處理。而CORS可以通過onerror監(jiān)聽到錯(cuò)誤事件,從而就可以看到錯(cuò)誤詳情方便排查問題

4.JSONP只會(huì)發(fā)送一次請(qǐng)求,而CORS的非簡單請(qǐng)求會(huì)發(fā)送兩次(大部分情況下的請(qǐng)求都會(huì)屬于非簡單請(qǐng)求)

  • 還不懂什么是簡單請(qǐng)求和非簡單請(qǐng)求,看本系列第一篇:Cors跨域(一):深入理解跨域請(qǐng)求概念及其根因

5.安全問題上,二者也有較大差異:

  • JSONP不是跨域的規(guī)范,它存在明顯的安全漏洞。表現(xiàn)在:callback參數(shù)注入(這是由于這些元素都是裸露的),以及資源授權(quán)方面無法限制(也就說他能接受所有Origin的請(qǐng)求從而也不太安全)
  • CORS是跨域的規(guī)范,并且能夠?qū)Y源授權(quán)方面做控制。Access-Control-Allow-Origin響應(yīng)頭就是最重要的一個(gè)響應(yīng)頭,當(dāng)然嘍若你把它恒定設(shè)為*,那它的安全性就大大退化

總的來講,CORS相較于JSONP 優(yōu)勢(shì)明顯 ,在實(shí)際生產(chǎn)使用上,忘了JSONP吧

總結(jié)

JSONP作為解決跨域問題的曾經(jīng)的唯一方案,立下汗馬功勞,現(xiàn)在是該退役了。但我們有理由記得它,畢竟英雄遲暮也希望不被遺忘(扯淡了,主要是這個(gè)名詞在很多新/老文章中還經(jīng)常被提起,注意分辨不要被弄迷糊啦)。

總而言之,作為新時(shí)代的開發(fā)人員,心里可認(rèn)為跨域問題的解決方案只有一種:那便是Cors。下一篇將是“激動(dòng)人心”的內(nèi)容:講述Cors在Spring環(huán)境中的實(shí)施,見識(shí)下那有多優(yōu)雅吧

本文轉(zhuǎn)載自微信公眾號(hào)「BAT的烏托邦」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系BAT的烏托邦公眾號(hào)。

責(zé)任編輯:姜華 來源: BAT的烏托邦
相關(guān)推薦

2014-08-19 10:36:02

AngularCORS

2019-04-10 10:32:16

CORSNginx反向代理

2022-03-21 07:35:34

處理方式跨域

2020-08-13 07:04:45

跨域CORS瀏覽器

2022-04-29 09:11:14

CORS瀏覽器

2023-12-20 14:42:59

2021-06-15 07:32:59

Cookie和Sess實(shí)現(xiàn)跨域

2020-08-31 19:20:33

瀏覽器CORS跨域

2013-11-27 10:23:23

2021-06-10 18:11:02

Cors跨域Web開發(fā)Cors

2018-01-26 08:39:03

2018-12-12 15:50:13

2023-05-06 15:32:04

2024-05-22 19:10:18

跨域Web開發(fā)

2020-12-18 09:36:01

JSONP跨域面試官

2021-06-17 07:15:36

Cors跨域多域名

2019-03-13 14:15:25

CORS跨域資源前端

2019-11-11 17:34:16

前端開發(fā)技術(shù)

2024-12-02 14:30:20

2024-05-20 09:28:44

Spring客戶端瀏覽器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

国产精品免费一区二区三区观看| 天天做天天爱天天爽综合网| 99久久综合国产精品| 亚洲在线视频观看| 高清亚洲高清| 午夜一区二区三区不卡视频| 一个人www欧美| 国产小视频免费在线网址| 成人三级在线视频| 欧美在线短视频| 日本一区二区三区视频在线播放 | 啪啪免费视频一区| 亚洲欧洲日韩在线| 欧美中文字幕在线视频| 精品欧美国产| 成人av一级片| 成人精品视频.| 一区二区国产日产| 日本欧洲一区二区| 欧美日韩一区综合| 91久久综合| 韩国精品久久久| 最近中文字幕免费mv| 久久精品国产久精国产爱| 久久久久久99| 国产成人在线观看| 男人天堂999| 国产精品麻豆一区二区| 热久久精品免费视频| 韩国三级成人在线| xx视频.9999.com| 日韩有码一区| a级国产乱理论片在线观看99| sese一区| 毛片.com| 一区二区不卡在线播放| 黄色av免费在线观看| 91久久线看在观草草青青| 免费在线超碰| 亚洲深夜福利视频| 亚洲黑人在线| 色婷婷综合久色| 一级香蕉视频在线观看| 精品美女在线播放| 国产福利亚洲| 国产精品白嫩美女在线观看| 欧美jizz| 26uuuu精品一区二区| 久久99久久| 久久香蕉国产线看观看网| 久久成人国产| 日本wwwwwwwzzzzz视频| 91精品国产综合久久国产大片| 青青在线视频| 日韩免费av片在线观看| www.久久艹| 国产精品99久久免费| 97在线电影| 国产jizzjizz一区二区| 午夜视频国产| 久久先锋影音av| 国产男女爽爽爽| 亚洲精品一区二区三区精华液| 韩国三级大全久久网站| 亚洲精品日韩在线观看| 欧美日韩精品一区二区三区蜜桃 | 郴州新闻综合频道在线直播| 97超碰免费观看| 欧美最猛性xxxxx直播| 欧美交a欧美精品喷水| 国产人妻互换一区二区| 欧美一区午夜视频在线观看| 欧美裸身视频免费观看| 污黄网站在线观看| 久久影院免费观看| www.99精品| 成人在线高清| 热99这里只有精品| 在线观看国产精品淫| 成年人国产精品| 精品免费av一区二区三区| 久久99久久99精品| 久久精品国产亚洲aⅴ| 在线h片观看| 精品网站在线看| 欧美日韩黄视频| 国产视频亚洲| 久久久久久九九| 欧美视频免费在线观看| 欧美一区不卡| 在线免费看黄| 日韩高清国产精品| 一区二区三区久久精品| www.亚洲色图.com| 国产欧美亚洲日本| 国产一区 二区 三区一级| 亚洲欧洲日产国码无码久久99 | 国产精品12345| 日韩亚洲一区二区| 亚洲伦理一区二区| 久久久久无码国产精品一区| 亚洲精品av在线播放| 成人免费毛片嘿嘿连载视频| 日韩深夜影院| 成人日韩在线观看| 超碰网在线观看| 青青久久av北条麻妃海外网| 日韩欧美aⅴ综合网站发布| 亚洲视频三区| 亚洲夜晚福利在线观看| 日韩av一二三| 九色精品91| 欧美三级电影一区二区三区| 欧美日韩二三区| 五月天av在线| 亚洲最大在线视频| 久久品道一品道久久精品| 中文字幕不卡三区视频| 中文字幕一区在线观看视频| 欧美精品一区二区三区中文字幕| 在线观看h网址| 亚洲一区中文字幕在线观看| 日韩欧美高清在线| 豆花视频一区| 欧美精品少妇| 欧美色图另类小说| 欧美精品尤物在线| 欧美极品欧美精品欧美视频 | 日本大片免费看| 国内精品久久久久| 91久久国产综合久久| 69视频在线观看| 国产精品电影观看| 国产一区二区三区在线看 | 欧美影院一区二区| 中日韩免费视频中文字幕| 蜜臀国产一区二区三区在线播放 | 国产精品高清一区二区| 制服丝袜中文字幕在线| 超碰在线免费| 久久久精品有限公司| 国产精品久久久999| 久久国产精彩视频| 亚洲国产成人91精品| 亚洲精品视频网上网址在线观看| 欧美日韩国产三级| 欧美日韩另类在线| 亚洲男人的天堂网| 国产精品久久久久影院色老大| 污视频在线观看免费| 亚洲一区二区三区四区中文| 亚洲999一在线观看www| 国产精品69久久| 国产精品视频一| 国产精品日韩在线播放| 国产精品久久久亚洲| 国产伦精品一区二区三区| 国产精品三区四区| 久久国产主播精品| 男女裸体影院高潮| 中文字幕の友人北条麻妃| 欧美一二三不卡| av无码久久久久久不卡网站| 久久无码高潮喷水| 香蕉av一区| 人人澡人人添人人爽一区二区| 亚洲人成在线网站| 天堂√8在线中文| 亚洲黄色网址在线观看| 神马影院一区二区三区| 亚洲欧美激情网| 黄色av网址在线免费观看| 91视频-88av| 亚洲国产精品久久一线不卡| 首页欧美精品中文字幕| 久久性天堂网| 99re热这里只有精品免费视频| 成人欧美一区二区三区在线播放| 亚洲婷婷在线视频| 日韩成人在线播放| 日韩av免费看| 国产一区二区三区四区hd| 人妻无码久久一区二区三区免费| 黄色一级影院| 中文字幕在线高清| 一本久久青青| 国产高清精品久久久久| 精品久久久久久国产| 久久久999国产| 91手机视频在线观看| 凹凸日日摸日日碰夜夜爽1| 国产h在线观看| 爱情电影网av一区二区| 日韩电影在线观看电影| 国产精品美女久久久久久| 日韩精品亚洲元码| 精选一区二区三区四区五区| 满满都是荷尔蒙韩剧在线观看| 国产97免费视| 亚洲国产高清国产精品|