成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端跨域

Coding01 / 2419人閱讀

摘要:在所有以上提到的跨域方法中,不得不說都是利用了大大小小的漏洞來繞過同源策略。對于開發(fā)者來說最大的好處就是,無需考慮以什么樣的方式繞過同源策略請求跨域資源,直接使用即可。

HTML跨域 傳統(tǒng)跨域方式 JSONP跨域

說到傳統(tǒng)跨域方式,JSONP是最廣泛為人所知的形式了。

對于JS來說,利用XMLHttpRequest無法請求非本域上的數(shù)據(jù),但是卻可以加載非本域的JS文件。
JSONP就是利用了這個所謂的“漏洞”。

試想當(dāng)我們在文檔中插入一個script標(biāo)簽,請求一個 JS 文件時,該JS文件的內(nèi)容是直接調(diào)用一個函數(shù),
同時傳入適當(dāng)?shù)臄?shù)據(jù)。則對于方法內(nèi)部,就已經(jīng)可以通過參數(shù)的形式獲取傳入的數(shù)據(jù)。如下所示:

此處的對象,就是傳入的數(shù)據(jù),而fun則是那個函數(shù)。該函數(shù)其實可以是任意函數(shù)名,只需在我們的window域下定義,也可以根據(jù)需求定義在其他地方。問題在于傳入的數(shù)據(jù)怎么來呢?其實這些對于前端來說完全不用管,只需讓后端處理好后拼接成如上形式返回給我們即可。而fun里面放什么,則取決于你要對返回的數(shù)據(jù)做什么樣的處理了。

另外,fun的函數(shù)名建議是隨同跨域接口一起傳輸給server,以讓server來進(jìn)行拼接出合適的執(zhí)行代碼。完整代碼如下:

document.domain

也許你會遇到這樣的情形:我的網(wǎng)頁內(nèi)嵌了一個iframe,該iframe所引用的頁面跟我本域不一樣,此時我想修改iframe中的內(nèi)容,該怎么辦呢?

或許你認(rèn)為可以通過contentWindow獲取iframe中的內(nèi)容,但很可惜的是我們拿到這個contentWindow,卻不能獲取到里面的屬性與方法(H5最新屬性postMessage除外,后面會提及)。

這是因為瀏覽器的同源策略禁止了我們這樣的操作,因為它們分屬不同的源。

此時就需要用到document.domain了,也就是我們只需將iframe中的document.domain設(shè)置成跟父頁面相同的值即可。

比如當(dāng) http://loliner.baidu.com/inde... 內(nèi)嵌了 http://baidu.com/example.html ,此時我們只需將 index.html 的 document.domain 修改成 baidu.com即可實現(xiàn)與example.html通信。

但是問題來了,瀏覽器對document.domain的設(shè)置是有限制的,其只能設(shè)置成比自身域更高一級的域名,包括自身域。

比如存在http://b.a.com/index.html,則該頁面 document.domain允許的值為

b.a.com

a.com

而c.b.a.com則是不允許的。且兩個頁面若要通訊,則兩者的主域必須相同。

上例中,主域就為 baidu.com。

window.name

在一個窗口(window)的生命周期內(nèi),窗口載入的所有的頁面都是共享一個window.name,每個頁面對window.name都有讀寫的權(quán)限。

以上是對window.name的定義。試想如果有兩個不同域的頁面順次被同一個窗口加載,那么對于這兩個頁面來說,兩者就能共享window.name,從而實現(xiàn)通信。

如何順次加載?利用window.location改變窗口的地址就可以辦到這一點。

比如,http://example.com/a.html 完全加載后,修改window.name為指定值。然后通過window.location將窗口定向到 http://loliner.com/b.html,此時b.html中window.name的值就為上一個頁面中設(shè)置的值。

window.name的值只能是一個字符串,最大2M,但對我們來說已經(jīng)夠用了。如果你要傳遞對象或數(shù)組,進(jìn)行JSON格式化即可。

但是,雖然這樣實現(xiàn)了數(shù)據(jù)通信,但是我們不能來回這樣切來切去,那怎么辦呢?這時候就可以利用 iframe + contentWindow 了。

我們可以在 b.html 頁面添加一個隱藏的iframe,該iframe指向a.html,當(dāng)a.html完全加載并修改了window.name之后,我們將iframe重新指向與b.html在同一個域名下的c.html,此時就可以通過 iframe 的 contentWindow 獲取到 name 的值了。

完整代碼如下:

H5跨域方式 window.postMessage

我們知道在同一個頁面嵌入多個iframe,每個iframe的域都不一樣時,雖然我們可以獲取iframe的window對象,卻不能訪問其中的屬性和方法。但H5的最新屬性postMessage除外,那么我們是否可以在此利用這樣的一個“漏洞”來進(jìn)行跨域呢?

答案是可以的。

我們只需在iframe中設(shè)置onmessage監(jiān)聽,然后在父級頁面中獲取iframe的window對象,將父頁面所要傳遞的信息通過window.postMessage發(fā)出即可。

完整代碼如下:

首先要讓iframe監(jiān)聽onmessage事件。

接下來則是在父頁面中獲取iframe的window對象并調(diào)用postMessage傳遞信息。

注意,此處的postMessage所發(fā)送的消息在低版本瀏覽器下只能為字符串,若要傳遞對象或數(shù)組,只能JSON格式化。

另外,第二個參數(shù)指的是域,表示你要將信息發(fā)送到哪個域,參數(shù)格式為協(xié)議+主機+端口,其實跟上面所說document.domain的值是一回事。

CORS

在所有以上提到的跨域方法中,不得不說都是利用了大大小小的漏洞來繞過同源策略。而無論如何進(jìn)行繞過,有一點可以肯定的是,WEB開發(fā)當(dāng)中確實需要跨域獲取資源。

所以,W3C為我們制訂了 CORS 跨域訪問機制。CORS對于開發(fā)者來說最大的好處就是,無需考慮以什么樣的方式繞過同源策略請求跨域資源,直接使用ajax即可。

那么誰去負(fù)責(zé)跨域的安全性呢?答案是由Server進(jìn)行控制。

Server在接收到請求的時候,需判斷請求來源,如果該來源合法,返回正常數(shù)據(jù),同時需要在請求返回頭response header中添加必要 CORS 字段。

對于瀏覽器來說,若該請求的返回頭信息中,包含該 CORS 字段,那么瀏覽器就會正常讀取返回的信息,否則,就會拋出No "Access-Control-Allow-Origin" header is present on the requested resource.禁止跨域異常。

上面所說到的CORS字段,分為必須與可選:

Access-Control-Allow-Origin(必須)

該服務(wù)器所允許跨域的源,如果為 * ,則表示允許所有源對該服務(wù)器進(jìn)行請求。
發(fā)送請求的一方的域,必須包含在該值所指定的源內(nèi)。

Access-Control-Allow-Credentials(可選)

表示是否允許發(fā)送cookie,該值為一個布爾值,默認(rèn)為false。

Access-Control-Expose-Headers(可選)

獲取response header中其他字段的值。

所以,簡單的說,CORS 模式中的跨域請求其實與前端開發(fā)者已經(jīng)沒有太大的關(guān)系,只要Server端控制好接口數(shù)據(jù),并按需寫入CORS字段即可。

另外,CORS跨域請求可以分為簡單請求與復(fù)雜請求。

簡單請求

對于簡單請求,瀏覽器直接發(fā)送CORS請求即可,跟上面所說流程一致。

HEAD、GET、POST都屬于簡單請求。
復(fù)雜請求

對于復(fù)雜請求,則需要首先發(fā)出預(yù)檢請求,判斷是否可以跨域,然后再發(fā)送真實請求。

PUT和DELETE,或Content-Type字段類型為application/json的都屬于復(fù)雜請求。

就目前來說,JSONP 及 CORS 算是最常用的跨域形式了,也能滿足我們的絕大部分需求。

相對于JSONP,CORS W3C規(guī)定的標(biāo)準(zhǔn)跨域方式,功能更強大,安全性也更好。

JSONP只支持GET請求,而 CORS 支持多種請求。

JSONP 沒有域的概念,CORS 則有精確的指定哪些域可以獲取資源。

CORS 將域的安全性管理完全交給Server管理,更加安全。

Flash跨域

Flash跨域也有多種形式,此處只介紹最常用的 crossdomain.xml 策略文件 模式及allowDomain 權(quán)限授予。

corssdomain.xml 跨域策略文件

與 CORS 復(fù)雜請求一樣,F(xiàn)lash在進(jìn)行跨域請求時,默認(rèn)首先會發(fā)送預(yù)檢請求,判斷本域是否合法。該預(yù)檢請求會去跨域請求的根目錄獲取 corssdomain.xml 文件,該文件包含了跨域策略信息。比如最重要的一點,就是告訴Flash哪些域可以跨域請求該服務(wù)器。

舉個栗子,http://baidu.com/a.html下有某swf文件要向http://loliner.com/請求資源。此時會經(jīng)過如下步驟:

Flash發(fā)現(xiàn)請求需要跨域,則首先請求http://loliner.com/crossdomai...文件;

若crossdomain.xml文件能正常返回,則分析其中的策略,查看本域是否合法;

若本域合法,則發(fā)送跨域請求;若不合法,則直接封殺請求。

此處注意,如果本域非法,F(xiàn)lash就會直接封殺了請求,那么我們在瀏覽器控制臺是捕獲不到該請求的,因為就沒發(fā)出去。

那么Flash是怎么判斷本域是否合法的呢?我們先來看一下一個最簡單的corssdomain.xml文件結(jié)構(gòu)。

所有的 crossdomain.xml 都以 作為根節(jié)點,里面的每一個都為一個策略。

其中,鍵值 domain 表示允許跨域的源,此處就跟 CORS 的 Access-Control-Allow-Origin 字段一樣了。

而 secure ,則表示請求是否以加密進(jìn)行傳輸。如果 corssdomain.xml 文件是從 https 協(xié)議下加載的,那么 secure 默認(rèn)為 true。此時Flash若發(fā)現(xiàn)本域為非 https 協(xié)議,縱使 domain 合法,也會封殺請求。如果secure為false,則表明Flash可以發(fā)送非https加密過的請求。

Security.allowDomain 跨域權(quán)限授予

如果說介紹 crossdomain.xml 文件時我們是以 Client 端為角度的,那么介紹 Security.allowDomain 則必須以 Server 作為角度。

你可能會遇到如下情形,開發(fā)了多個swf,它們之間相互依賴,但以不同的域發(fā)布到網(wǎng)上。此時你只希望某些特定的域才有權(quán)限去修改或調(diào)用該swf中的屬性及方法。那么此時,你就需要用到allowDomain方法對你所允許的域進(jìn)行授權(quán)了。

以下是 allowDomain 的描述:

允許指定的域中的 SWF 文件訪問調(diào)用了此方法的 SWF 文件中的對象和變量。

再舉個栗子,http://a.com/a.swf 需要調(diào)用及修改 http://b.com/b.swf 中的屬性及方法。
那么,就必須在b.swf中調(diào)用 Security.allowDomain("a.com")以允許a.com域?qū)ψ约哼M(jìn)行訪問。

另外,要注意非常重要的一點,Security.allowDomain跨域權(quán)限授予是不對稱的。

也就是說,在上面的栗子中,只允許a.swf訪問b.swf,但b.swf卻不能夠訪問a.swf。
如果非要這樣做,那么就在a.swf中對b.com進(jìn)行權(quán)限授予。

其次,對于HTTPS來說,即使調(diào)用了該方法,若試圖利用在HTTP下的swf去修改HTTPS下的swf,此時也是非法的。因為這本身就不安全。

如果非要這樣做,可以讓HTTPS下的swf調(diào)用Security.allowInsecureDomain()對HTTP域進(jìn)行權(quán)限授予

跨域方式對比

反觀 Flash 跨域與H5 CORS 跨域,雖然兩者在形式上有所不同,但本質(zhì)上都向著以下兩個特點靠攏:

先詢問,后請求;

安全性靠Server端來維護(hù)。

對于 CORS 簡單請求來說,瀏覽器是不會進(jìn)行預(yù)檢請求發(fā)送的,這樣一個請求搞定所有的事,卻不一定完全合理。因為對于瀏覽器來說,我在沒有知道Server是否認(rèn)為我的請求合法前,就已經(jīng)拋出了大量的查詢數(shù)據(jù)。這就有可能造成數(shù)據(jù)傳輸?shù)娜哂唷?/p>

另外,如果由于開發(fā)過程不當(dāng),頻繁發(fā)送不合法的跨域請求,本身就是一個資源的浪費。

所以,才需要到復(fù)雜請求。

而對于 Flash crossdomain.xml 這種方式(與 CORS 復(fù)雜請求類似),就避免了頻繁發(fā)送不合法的跨域請求,因為在crossdomain.xml返回之前,F(xiàn)lash是不會發(fā)送任何跨域請求,直接在本地就將其封殺。同時crossdomain.xml并非每次跨域前都會請求,其有一個有效期。

但若我本身只需請求一次數(shù)據(jù),但Server由于業(yè)務(wù)繁重卻給我返回一個龐大的crossdomain.xml,這反而又顯得不合理了。

文章來源:http://mp.weixin.qq.com/s/_KA...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/82857.html

相關(guān)文章

  • 前端培訓(xùn)-中級階段(11、12)- 跨域請求原理以及實現(xiàn)(2019-08-22期)

    摘要:上節(jié)我們講了同源策略,這節(jié)我們講講如何跨域。當(dāng)這些從的腳本執(zhí)行出錯,因為違背了同源策略為了保證用戶信息不被泄露,錯誤信息不會顯示出來,取而代之只會返回一個。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識的中心思想,我們開課啦(每...

    binaryTree 評論0 收藏0
  • 徹底弄懂跨域問題

    摘要:用于告知瀏覽器可以將預(yù)先檢查請求返回結(jié)果緩存的時間,在緩存有效期內(nèi),瀏覽器會使用緩存的預(yù)先檢查結(jié)果判斷是否發(fā)送跨域請求。 跨域,老生常談的問題 簡述 作為一只前端菜鳥,跨域方面只懂得JSONP和CORS,并未曾深入了解。但隨著春招越來越近,就算是菜鳥也要猛振翅膀。近幾日仔細(xì)研究了跨域問題,寫下這篇文章,希望對開發(fā)者們有所幫助。在讀本文前,希望您對以下知識略有了解。 瀏覽器同源策略 n...

    rose 評論0 收藏0
  • 前端常見跨域解決方案(全)

    摘要:需注意的是由于同源策略的限制,所讀取的為跨域請求接口所在域的,而非當(dāng)前頁。目前,所有瀏覽器都支持該功能需要使用對象來支持,也已經(jīng)成為主流的跨域解決方案。反向代理接口跨域跨域原理同源策略是瀏覽器的安全策略,不是協(xié)議的一部分。 什么是跨域? 跨域是指一個域下的文檔或腳本試圖去請求另一個域下的資源,這里跨域是廣義的。 廣義的跨域: 1.) 資源跳轉(zhuǎn): A鏈接、重定向、表單提交 2.) 資源...

    canger 評論0 收藏0
  • 徹底弄懂跨域問題

    摘要:瀏覽器同源策略我們?yōu)楹我芯靠缬騿栴}因為瀏覽器的同源策略規(guī)定某域下的客戶端在沒明確授權(quán)的情況下,不能讀寫另一個域的資源。 跨域,老生常談的問題 簡述 作為一只前端菜鳥,跨域方面只懂得JSONP和CORS,并未曾深入了解。但隨著春招越來越近,就算是菜鳥也要猛振翅膀。近幾日仔細(xì)研究了跨域問題,寫下這篇文章,希望對開發(fā)者們有所幫助。在讀本文前,希望您對以下知識略有了解。 瀏覽器同源策略 n...

    CoorChice 評論0 收藏0
  • 20K前端大佬面試(關(guān)于如何回答ajax跨域問題)

    摘要:在接觸前端開發(fā)起,跨域這個詞就一直以很高的頻率在我們學(xué)習(xí)工作中重復(fù)出現(xiàn),最近在工作中遇到了跨域的相關(guān)問題,這里我把它總結(jié)記錄一下。 在接觸前端開發(fā)起,跨域這個詞就一直以很高的頻率在我們學(xué)習(xí)工作中重復(fù)出現(xiàn),最近在工作中遇到了跨域的相關(guān)問題,這里我把它總結(jié)記錄一下。關(guān)于跨域,有N種類型,現(xiàn)在我只專注于ajax請求跨域(ajax跨域只是屬于瀏覽器同源策略中的一部分,其它的這里不做介紹),內(nèi)容...

    Yangyang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<