大家好痴昧,我是IT修真院深圳分院第04期學員稽穆,一枚正直善良的web程序員。
今天給大家分享一下赶撰,修真院官網(wǎng) js任務中可能會使用到的知識點:
前端跨域問題有哪些常用的解決方式舌镶?
1.背景介紹
理解跨域首先必須要了解同源策略。同源策略是瀏覽器上為安全性考慮實施的非常重要的安全策略豪娜。
什么是同源政策餐胀?
瀏覽器的同源策略,限制了來自不同源的"document"或腳本瘤载,對當前"document"讀取或設置某些屬性骂澄。
從一個域上加載的腳本不允許訪問另外一個域的文檔屬性。
舉個例子:
比如一個惡意網(wǎng)站的頁面通過iframe嵌入了銀行的登錄頁面(二者不同源)惕虑,如果沒有同源限制坟冲,惡意網(wǎng)頁上的javascript腳本就可以在用戶登錄銀行的時候獲取用戶名和密碼。
設想這樣一種情況:A網(wǎng)站是一家銀行溃蔫,用戶登錄以后健提,又去瀏覽其他網(wǎng)站。如果其他網(wǎng)站可以讀取A網(wǎng)站的 Cookie伟叛,會發(fā)生什么私痹?
很顯然,如果 Cookie 包含隱私(比如存款總額)统刮,這些信息就會泄漏紊遵。更可怕的是,Cookie 往往用來保存用戶的登錄狀態(tài)侥蒙,
如果用戶沒有退出登錄暗膜,其他網(wǎng)站就可以冒充用戶,為所欲為鞭衩。因為瀏覽器同時還規(guī)定学搜,提交表單不受同源政策的限制。
由此可見论衍,"同源政策"是必需的瑞佩,否則 Cookie 可以共享,互聯(lián)網(wǎng)就毫無安全可言了坯台。
1995年炬丸,網(wǎng)景公司將同源策略這一安全策略引入瀏覽器,規(guī)定不同的‘域’之間的數(shù)據(jù)相互不可訪問蜒蕾。
什么是同源政策稠炬?
瀏覽器的同源策略,限制了來自不同源的"document"或腳本滥搭,對當前"document"讀取或設置某些屬性酸纲。
從一個域上加載的腳本不允許訪問另外一個域的文檔屬性。
舉個例子:
比如一個惡意網(wǎng)站的頁面通過iframe嵌入了銀行的登錄頁面(二者不同源)瑟匆,如果沒有同源限制闽坡,惡意網(wǎng)頁上的javascript腳本就可以在用戶登錄銀行的時候獲取用戶名和密碼。
設想這樣一種情況:A網(wǎng)站是一家銀行愁溜,用戶登錄以后疾嗅,又去瀏覽其他網(wǎng)站。如果其他網(wǎng)站可以讀取A網(wǎng)站的 Cookie冕象,會發(fā)生什么代承?
很顯然,如果 Cookie 包含隱私(比如存款總額)渐扮,這些信息就會泄漏论悴。更可怕的是掖棉,Cookie 往往用來保存用戶的登錄狀態(tài),
如果用戶沒有退出登錄膀估,其他網(wǎng)站就可以冒充用戶幔亥,為所欲為。因為瀏覽器同時還規(guī)定察纯,提交表單不受同源政策的限制帕棉。
由此可見,"同源政策"是必需的饼记,否則 Cookie 可以共享香伴,互聯(lián)網(wǎng)就毫無安全可言了。
1995年具则,網(wǎng)景公司將同源策略這一安全策略引入瀏覽器即纲,規(guī)定不同的‘域’之間的數(shù)據(jù)相互不可訪問。
什么算是同源乡洼?
URL由協(xié)議崇裁、域名、端口和路徑組成束昵,如果兩個URL的協(xié)議拔稳、域名和端口相同,則表示他們同源锹雏。
舉例來說巴比,http://www.example.com/dir/page.html這個網(wǎng)址,協(xié)議是http://礁遵,
域名是www.example.com轻绞,端口是80(默認端口可以省略)。它的同源情況如下:
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
https://www.example.com/dir/other.html:不同源(協(xié)議不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
請求不同‘源’的數(shù)據(jù)就算是跨域佣耐。
2.知識剖析
實現(xiàn)跨域的常見方法有以下幾種
1.JSONP跨域
JSON(JavaScript Object Notation)和JSONP(JSON withPadding)雖然只有一個字母的差別政勃,其實他們根本不是一回事兒:
JSON是一種數(shù)據(jù)交換格式,而JSONP是一種依靠開發(fā)人員的聰明才智創(chuàng)造出的一種非官方跨域數(shù)據(jù)交互協(xié)議兼砖。
我們拿諜戰(zhàn)片來打個比方蹈集,JSON是地下黨們用來書寫和交換情報的“暗號”蟹肘,而JSONP則是把用暗號書寫的情報傳遞給自己同志時使用的接頭方式冒窍。
一個是描述信息的格式烦租,一個是信息傳遞雙方約定的方法。
1耽梅、一個眾所周知的問題薛窥,Ajax直接請求普通文件存在跨域無權限訪問的問題,不管你是靜態(tài)頁面眼姐、動態(tài)網(wǎng)頁诅迷、web服務佩番、WCF,只要是跨域請求竟贯,一律不準答捕;
2、不過我們又發(fā)現(xiàn)屑那,Web頁面上調用js文件時則不受是否跨域的影響(不僅如此,我們還發(fā)現(xiàn)凡是擁有”src”這個屬性的標簽都擁有跨域的能力艘款,比如持际、、)哗咆;
3蜘欲、恰巧我們已經(jīng)知道有一種叫做JSON的純字符數(shù)據(jù)格式可以簡潔的描述復雜數(shù)據(jù),更妙的是JSON還被js原生支持晌柬,所以在客戶端幾乎可以隨心所欲的處理這種格式的數(shù)據(jù)姥份;
4、這樣子解決方案就呼之欲出了年碘,web客戶端通過與調用腳本一模一樣的方式澈歉,來調用跨域服務器上動態(tài)生成的js格式文件(一般以JSON為后綴),顯而易見屿衅,服務器之所以要動態(tài)生成JSON文件埃难,目的就在于把客戶端需要的數(shù)據(jù)裝入進去。
5涤久、客戶端在對JSON文件調用成功之后涡尘,也就獲得了自己所需的數(shù)據(jù),剩下的就是按照自己需求進行處理和展現(xiàn)了响迂,這種獲取遠程數(shù)據(jù)的方式看起來非常像AJAX考抄,但其實并不一樣。
6蔗彤、為了便于客戶端使用數(shù)據(jù)川梅,逐漸形成了一種非正式傳輸協(xié)議,人們把它稱作JSONP幕与,該協(xié)議的一個要點就是允許用戶傳遞一個callback參數(shù)給服務端挑势,然后服務端返回數(shù)據(jù)時會將這個callback參數(shù)作為函數(shù)名來包裹住JSON數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來自動處理返回數(shù)據(jù)了啦鸣。
2.nginx反向反向代理
Nginx是一個HTTP服務器潮饱,可以將服務器上的靜態(tài)文件(如HTML、圖片)通過HTTP協(xié)議展現(xiàn)給客戶端诫给。
反向代理服務器:客戶端本來可以直接通過HTTP協(xié)議訪問某網(wǎng)站應用服務器香拉,網(wǎng)站管理員可以在中間加上一個Nginx啦扬,客戶端請求Nginx,Nginx請求應用服務器凫碌,然后將結果返回給客戶端扑毡,此時Nginx就是反向代理服務器。
負載均衡:當網(wǎng)站訪問量非常大盛险,一臺服務器已經(jīng)不夠用了瞄摊。于是將同一個應用部署在多臺服務器上,將大量用戶的請求分配給多臺機器處理苦掘。Nginx可以通過反向代理來實現(xiàn)負載均衡换帜。
3.常見問題
JSONP實現(xiàn)跨域原理
nginx反向代理
代碼中如何實現(xiàn)?
4.解決方案
1.JSONP實現(xiàn)跨域
2.nginx反向代理
5.編碼實戰(zhàn)
6.擴展思考
其他實現(xiàn)跨域的方法有以下幾種
CORS是跨源資源分享;
WebSocket通信協(xié)議鹤啡;
window.name惯驼;
window.postMessage跨文檔通信 API(Cross-document messaging);
location.hash
...
7.參考文獻
8.更多討論
怎么選擇跨域的方法祟牲?
跨域的方法很多,不同的應用場景我們都可以找到一個最合適的解決方案抖部。
比如單向的數(shù)據(jù)請求说贝,我們應該優(yōu)先選擇JSONP或者window.name,
雙向通信優(yōu)先采取location.hash您朽,