摘要:注為頂級(jí)域名,為二級(jí)域名,為三級(jí)域名跨域并非瀏覽器限制了發(fā)起跨站請(qǐng)求,而是跨站請(qǐng)求可以正常發(fā)起,但返回結(jié)果被瀏覽器攔截了。四總結(jié)首先在客戶端注冊(cè)一個(gè),然后把的名字傳給服務(wù)器。
前言
博主博客:Stillwater的博客
知乎專欄:前端汪汪
本文為作者原創(chuàng)轉(zhuǎn)載請(qǐng)注明出處:http://hiztx.top/2017/01/15/j...
??本文介紹了什么是跨域,為什么要跨域,以及跨域的一種常用方法JSONP的原理。
一、什么是跨域?為什么要跨域? 什么是跨域???既然是跨域,那么肯定是從一個(gè)域到另一個(gè)域。那么首先要知道滿足什么條件才是同一個(gè)域。如果兩個(gè)頁(yè)面擁有相同的協(xié)議,端口和域名,那么這兩個(gè)頁(yè)面就屬于同一個(gè)源(origin),JavaScript允許這種同源頁(yè)面的數(shù)據(jù)互相通信。例如你要訪問(wèn)百度首頁(yè)。
https://www.baidu.com
https是協(xié)議
https協(xié)議的默認(rèn)端口為443(不顯示)
www.baidu.com為域名
注:一般端口默認(rèn)為不顯示,但是你可以嘗試輸入以下網(wǎng)址,發(fā)現(xiàn)無(wú)法訪問(wèn)。因?yàn)?0端口默認(rèn)為http協(xié)議端口。
https://www.baidu.com:80
??現(xiàn)在知道了什么是同一個(gè)域,那么就可以解釋什么是跨域。只要協(xié)議、域名、端口有任何一個(gè)不同,都被當(dāng)作是不同的域,之間的請(qǐng)求就是跨域操作。
為什么要跨域???相信很多人都聽過(guò),同源策略。出于安全考慮,瀏覽器對(duì)JavaScript的很多功能進(jìn)行了限制,其中一條就是,不同域之間不予許進(jìn)行數(shù)據(jù)通信。雖然補(bǔ)全了安全漏洞,但是這個(gè)限制給前端開發(fā)帶來(lái)了許多不便。例如:
zhidao.baidu.com
wenku.baidu.com
??百度知道和百度文庫(kù)大家都不陌生,都是百度開發(fā)的web服務(wù)。雖然這兩個(gè)都是李彥宏的,但是現(xiàn)在告訴他,由于你這兩個(gè)域名的三級(jí)域名不一樣,不允許相互數(shù)據(jù)通信。你說(shuō)不行就不行?于是就有像李彥宏這樣的大牛搞出一些黑科技專門用來(lái)跨域通信。JSONP就是其中之一。
二、什么是JSONP?注:
1.com為頂級(jí)域名,baidu為二級(jí)域名,zhidao/wenku為三級(jí)域名
2.跨域并非瀏覽器限制了發(fā)起跨站請(qǐng)求,而是跨站請(qǐng)求可以正常發(fā)起,但返回結(jié)果被瀏覽器攔截了。
顧名思義:
JSONP = JSON + P
??JSONP(JSON with Padding),JSON是一種輕量級(jí)的數(shù)據(jù)交換格式。而Padding在這里可以翻譯為填充。那么JSONP的意思就是,填充的JSON。是數(shù)據(jù)格式JSON的一種使用模式,可以讓網(wǎng)頁(yè)從別的網(wǎng)域要數(shù)據(jù)。
三、JSONP原理JSONP的核心原理就是,HTML的script標(biāo)簽可以加載并執(zhí)行其他域JS文件。
??這里區(qū)分兩個(gè)概念,當(dāng)我們用瀏覽器打開百度知道首頁(yè)的時(shí)候,是向百度知道服務(wù)器發(fā)送了一個(gè)Https請(qǐng)求,獲取到百度知道首頁(yè)的index.html。如果在這個(gè)index.html里面用XMLHttpRequest對(duì)象向百度文庫(kù)服務(wù)器發(fā)送Https請(qǐng)求,那么就屬于跨域,是不允許的。但是如果在百度知道首頁(yè)的index.html中加入一個(gè)script標(biāo)簽,其src屬性指向百度文庫(kù)中的一個(gè).json文件,是允許的。
??為了理解這種模式的原理,先想像有一個(gè)回傳JSON文件的URL,而JavaScript 程序可以用XMLHttpRequest跟這個(gè)URL要數(shù)據(jù)。假設(shè)我們的URL是 http://server2.example.com/Re... 。假設(shè)小明的UserId 是1823,且當(dāng)瀏覽器通過(guò)URL傳小明的UserId,也就是抓取 http://server2.example.com/Re... 。得到:
{"Name": "小明", "Id": 1823, "Rank": 7 }
??這個(gè)JSON數(shù)據(jù)可能是依據(jù)傳過(guò)去URL的查詢參數(shù)動(dòng)態(tài)產(chǎn)生的。這個(gè)時(shí)候,把 script元素的src屬性設(shè)成一個(gè)回傳JSON的URL是可以想像的,這也代表從HTML頁(yè)面通過(guò)script元素抓取JSON是可能的。然而,一份JSON文件并不是一個(gè)JavaScript程序。為了讓瀏覽器可以在 script元素運(yùn)行,從src里URL回傳的必須是可運(yùn)行的JavaScript。在JSONP的使用模式里,該URL回傳的是由函數(shù)調(diào)用包起來(lái)的動(dòng)態(tài)生成JSON,這就是JSONP的“填充(padding)”或是“前輟(prefix)”的由來(lái)。
??服務(wù)器會(huì)在傳給瀏覽器前將JSON數(shù)據(jù)填充到回調(diào)函數(shù)(parseResponse)中。瀏覽器得到的回應(yīng)已不是單純的數(shù)據(jù)敘述而是一個(gè)腳本。在本例中,瀏覽器得到的是:
{ parseResponse( { "Name": "小明", "Id": 1823, "Rank": 7 }) }
??也就是說(shuō),一般情況下瀏覽器向服務(wù)器發(fā)送請(qǐng)求得到的都是數(shù)據(jù)(文本,XML,JSON),但是當(dāng)采用JSONP技術(shù)時(shí)候,瀏覽器向跨域服務(wù)器發(fā)送請(qǐng)求,得到的是回調(diào)函數(shù)包住的JSON。此處JSON作為參數(shù)傳入回調(diào)函數(shù),然后再返回給瀏覽器。
再舉個(gè)例子:瀏覽器端:
服務(wù)器端:
服務(wù)器返回瀏覽器:
jsonpcallback( { "name": "Stillwater", "age": 12 } )
??在這個(gè)例子中,瀏覽器向服務(wù)器發(fā)出跨域請(qǐng)求 http://localhost:8080/test.ph... 。請(qǐng)求一個(gè)json數(shù)據(jù), {"name": "Stillwater","age": 12} 。并且告訴了服務(wù)器回調(diào)函數(shù)的名字。服務(wù)器接收到請(qǐng)求后,就將json數(shù)據(jù)作為參數(shù)填充到回調(diào)函數(shù)中,返回給瀏覽器。最終返回一個(gè)填充了json數(shù)據(jù)的回調(diào)函數(shù)。
四、總結(jié)首先在客戶端注冊(cè)一個(gè)callback,然后把callback的名字傳給服務(wù)器。
服務(wù)器先生成json數(shù)據(jù)。然后以Javascript語(yǔ)法的方式,生成一個(gè)function ,function名字就是傳遞上來(lái)的參數(shù)callback。 最后將json數(shù)據(jù)直接以入?yún)⒌姆绞剑胖玫絝unction中,這樣就生成了一段 js 語(yǔ)法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標(biāo)簽,并執(zhí)行返回的Javascript 文檔,此時(shí)數(shù)據(jù)作為參數(shù),傳入到了客戶端預(yù)先定義好的callback 函數(shù)里。(動(dòng)態(tài)執(zhí)行回調(diào)函數(shù))
參考鏈接:
https://zh.wikipedia.org/wiki...
http://www.cnblogs.com/zichi/...
http://tech.jandou.com/cross-...
https://segmentfault.com/a/11...
http://wearejq.github.io/2015...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81226.html
摘要:瀏覽器端需要設(shè)置響應(yīng)頭的,,等字段,指定允許的方法,頭部,源等信息。可以通過(guò)前后端約定一個(gè)字段名,比如,來(lái)傳遞一個(gè)函數(shù)名,從而使得前端可以使用對(duì)應(yīng)的函數(shù),拿到數(shù)據(jù),處理數(shù)據(jù)。 原文地址:https://github.com/HolyZheng/... 了解幾個(gè)跨域的方案,并且通過(guò)簡(jiǎn)單實(shí)踐進(jìn)行體會(huì)。 如何實(shí)踐? 但是,我們?nèi)绾芜M(jìn)行實(shí)踐呢?在哪發(fā)請(qǐng)求?向什么服務(wù)器發(fā)請(qǐng)求?很簡(jiǎn)單,就在當(dāng)前...
摘要:比如域的頁(yè)面通過(guò)嵌入了一個(gè)域的頁(yè)面,可以通過(guò)以下方法實(shí)現(xiàn)和的通信通過(guò)跨域以上幾種都是雙向通信的,即兩個(gè),頁(yè)面與或是頁(yè)面與頁(yè)面之間的,下面說(shuō)幾種單項(xiàng)跨域的一般用來(lái)獲取數(shù)據(jù),因?yàn)橥ㄟ^(guò)標(biāo)簽引入的是不受同源策略的限制的。 跨域整理@(前端筆記) 跨域 只要協(xié)議、域名、端口有任何一個(gè)不同,都被當(dāng)作是不同的域。由于瀏覽器的同源策略,其限制之一是不能通過(guò)ajax的方法情趣請(qǐng)求不同源的文檔。第二個(gè)限制...
摘要:是的,方法被調(diào)用時(shí),會(huì)在所有頁(yè)面腳本執(zhí)行完畢之后向目標(biāo)窗口派發(fā)一個(gè)消息。該消息有四個(gè)屬性需要注意屬性表示該的類型屬性為的第一個(gè)參數(shù)屬性表示調(diào)用方法時(shí)調(diào)用頁(yè)面的當(dāng)前狀態(tài)屬性記錄調(diào)用方法的窗口信息。 1.為什么要跨域 同源策略限制一個(gè)源加載的文檔或文檔與來(lái)自另一個(gè)源的資源進(jìn)行交互。這是一個(gè)用于隔離潛在惡意文件的安全機(jī)制。什么是同源呢? 如果協(xié)議,端口(如果指定了一個(gè))和域名對(duì)于兩個(gè)頁(yè)面是相...
摘要:同源策略做了很嚴(yán)格的限制,但是在實(shí)際的場(chǎng)景中,又確實(shí)有很多地方需要突破同源策略的限制,也就是我們常說(shuō)的跨域。使用跨域由于同源策略,一般來(lái)說(shuō)位于的網(wǎng)頁(yè)無(wú)法與不是的服務(wù)器溝通,而的元素是一個(gè)例外。 本菜雞最近在寫某個(gè)頁(yè)面請(qǐng)求數(shù)據(jù)時(shí),報(bào)了如下的錯(cuò)誤。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...
摘要:同源策略做了很嚴(yán)格的限制,但是在實(shí)際的場(chǎng)景中,又確實(shí)有很多地方需要突破同源策略的限制,也就是我們常說(shuō)的跨域。使用跨域由于同源策略,一般來(lái)說(shuō)位于的網(wǎng)頁(yè)無(wú)法與不是的服務(wù)器溝通,而的元素是一個(gè)例外。 本菜雞最近在寫某個(gè)頁(yè)面請(qǐng)求數(shù)據(jù)時(shí),報(bào)了如下的錯(cuò)誤。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...
閱讀 2735·2021-11-22 15:22
閱讀 1643·2021-11-22 14:56
閱讀 3620·2021-09-22 15:12
閱讀 2408·2021-09-02 15:41
閱讀 2128·2021-08-27 16:26
閱讀 1118·2019-08-30 15:55
閱讀 2144·2019-08-29 17:30
閱讀 672·2019-08-29 16:26