摘要:中的跨域請求應該也算是一個重點,具體什么叫跨域,在這里我就不展開了,可以查一下瀏覽器的同源策略和跨域的定義。再看后臺文件文件接收回調函數并把要返回的參數以參數注入的方式注入到回調函數中,再返回給客戶端。
js中的跨域請求應該也算是一個重點,具體什么叫跨域,在這里我就不展開了,可以查一下瀏覽器的同源策略和跨域的定義。原來只知道常用的jsonp和document.domain這兩種方式,這幾天學習了一下其他幾種跨域請求的方式,正好一起做個總結。
第一種方式:jsonp請求jsonp請求應該是大家最為熟悉的一種(至少是我知道的第一種跨域請求方式)。jsonp的原理是利用
文件底部的
文件接收回調函數并把要返回的參數以參數注入的方式注入到回調函數中,再返回給客戶端。
這樣的話瀏覽器解析script標簽,并執行返回的js文檔,此時服務器返回的數據作為參數,傳到頁面中定義好的 jsonpBack 函數里.(動態執行回調函數),就拿到了我們需要的跨域數據。
這里補充一點就是jquery對jsonp有著很好的支持,jquery中$.getJSON方法將jsonp的調用方式進行了封裝,用起來十分方便,使用的方式如下即可:
第二種方式:document.domain這種方式用在主域名相同子域名不同的跨域訪問中,舉個例子:http://a.frame.com和http://b.frame.com 他們的主域名都是frame.com 這兩個域名中的文件可以用這種方式進行訪問,通過在兩個域中具體的文件中設置document.domain="frame.com"就可達到跨域訪問的目的。
實際應用中常常用在iframe中窗口之間的訪問,根據瀏覽器的同源策略,瀏覽器中不同域的框架之間是不能進行js的交互操作的,所以一個窗口是不能拿到另一個窗口中的contentWindow對象的屬性和方法的(注意是能拿到contentWindow對象的,只是屬性和方法都不可用)。為了能拿到數據,只要在兩個iframe中分別寫入document.domain="主域名",這樣設置之后,就能拿到contentWindow對象的屬性和方法了。代碼就這么簡單的一行,我就不寫小例子了。
第三種方式:window.namewindow的name屬性有個特征:在一個窗口(window)的生命周期內,窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的所有頁面中的,并不會因新頁面的載入而進行重置。
這是什么意思呢?通俗來講,就是比如我在a.html這個頁面中設置了window.name="a";然后讓window重新加載b.html頁面,然后在b.html頁面中輸出window.name會發現window.name=“a”。所以就算a.html和b.html這兩個頁面不是在同一個域中的,也可以在b頁面中拿到a頁面設置的window.name的值,跨域的核心思路就是這個原理。
實際應用中也是常常用在兩個iframe之間(需要結合iframe的特性來用),先上一張從別人那邊借鑒過來的原理圖,我再按照自己的理解進行分析:
圖中有三個頁面,getDomainData.html是獲取數據的頁面,null.html是一個和getDomainData.html同域的空頁面,它的作用是作為一個中轉站,進行數據的過渡。data.html是要獲取數據的所在頁面,這里有著我們要的數據,它和getDomainData.html處于不同域中,所以取數據是跨域訪問。具體的過程是這樣的:在getDomainData.html中建立一個子頁面iframe,把這個iframe的src指向b.com/data.html,這樣當這個iframe加載完成后就可以訪問到data.html中的window.name的數據,之后再將iframe的src改為a.com/null.html,跳回getDomainData.html的同一個域,這樣根據同源策略,getDomainData.html就可以訪問到null.html中取得的data.html的數據了。獲取數據以后最好銷毀這個iframe,釋放掉內存,也保證了安全。下面附上代碼小例子:
getDomainData.html:
data.html:
最后的iframe銷毀:
第四種方式:window.postMessagewindow.postMessages是html5中實現跨域訪問的一種新方式,可以使用它來向其它的window對象發送消息,無論這個window對象是屬于同源或不同源。
該方式的使用還是十分簡單的,給要發送數據的頁面中的window對象調用一個postMessage(message,targetOrigin)方法即可,該方法的第一個參數message為要發送的消息,類型只能為字符串;第二個參數targetOrigin用來限定接收消息的那個window對象所在的域,如果不想限定域,直接使用通配符 * 。再讓接收數據頁面的window對象監聽自身的message事件來獲取傳過來的消息,消息內容儲存在該事件對象的data屬性中。簡單的小例子如下:
test.html(發送頁面):
test2.html(接收頁面)
測試結果如下
關于這個用法困擾了我好久,困擾1:因為最后彈出的消息是在test.html,而不是在test2.html中,我不確定是因為test.html包含了test2.html,所以瀏覽器渲染才彈出的alert,還是test2.html接收到消息的反饋。后來查閱了權威的文檔,才有了進一步的理解,應該是test2.html收到消息,以iframe在test.html中渲染加載出的。
困擾2:postMessage的調用對象是目標窗口還是發送窗口,是否能以window形式調用?
查閱文檔后得出結論:*postMessage的調用對象,是其他窗口的一個引用,即目標窗口,不是要發送的窗口,(這里比較出乎意料) 而且postMessage想要通信必須使得一個窗口以iframe的形式存在于另一個窗口,或者一個窗口是從另一個窗口通過window.open()或者超鏈接的形式打開的(同樣可以用window.opener獲取源窗口);換句話說,你要交換數據,必須能獲取目標窗口(target window)的引用,不然兩個窗口之間毫無聯系,想通信也無能為力,所以不能直接以主頁面window的形式調用。
具體的權威解釋請看這個鏈接: window.postMessage
第五種方式:CORSCORS(Corss-Origin-Resource Sharing,跨源資源共享),是一種網絡瀏覽器的技術規范,它為Web服務器定義了一種方式,允許網頁從不同的域訪問其資源,而這種訪問是被同源策略所禁止的。CORS系統定義了一種瀏覽器和服務器交互的方式來確定是否允許跨域請求。 它是一個妥協,有更大的靈活性,但比起簡單地允許所有這些的要求來說更加安全。
CORS背后的基本思想,就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求或響應是應該成功還是應該失敗。
CORS的使用還是十分簡便的,比如一個簡單的GET或者POST請求,在發送的時候給它附加一個額外的origin頭部,其中包含請求頁面的源信息(協議、域名和端口),以便服務器根據這個頭部信息來決定是否給以響應。下面是javascript高級程序設計書上的一個小例子:
Origin:http://www.nczonline.net
如果服務器認為這個請求可以接受,就在Access-Control-Allow-Origin頭部中回發相同的源消息(如果是公共資源,可以回發“ * ”)。例如:
Access-Control-Allow-Origin:http://www.nczonline.net
這樣設置之后,服務器與瀏覽器就可以進行跨域信息的交換了。具體的在不同瀏覽器上的支持和使用,我就不展開了,js高級程序設計書上提到了很多,網上查一下也有很多。
第六種方式:Web SocketsWeb Sockets是一種新瀏覽器API,能在一個多帶帶的持久連接上提供全雙工、雙向通信,使用ws(代替http://)或wss(代替https://)協議,可用于任意的客戶端和服務器程序。
web sockets原理:在JS創建了web socket之后,會有一個HTTP請求發送到瀏覽器以發起連接。取得服務器響應后,建立的連接會使用HTTP升級從HTTP協議交換為web sockt協議。
使用的小例子:
// 創建一個Socket實例 var socket = new WebSocket("ws://www.example.com/server.php"); // 打開Socket socket.onopen = function(event) { // 發送消息 socket.send("a secret"); // 監聽消息的接收 socket.onmessage = function(event) { var data=event.data; //處理data... }; // 監聽socket的關閉 socket.onclose = function(event) { console.log("socket has closed",event); }; // 關閉Socket //socket.close() };
同樣附上權威文檔供參考:Web Workers API
總結除此之外還有一些跨域訪問的方式:比如Comet、圖像Ping、SSE等,感興趣的可以直接查找這些內容。在這些跨域訪問方式上,各有各的適用訪問和相應的限制,需要結合實際來適用。我在這里有個疑問:我自己運用的比較多的就是jsonp這種方式,那么在實際開發中,比較推崇的跨域訪問方式是哪種呢?還有就是html5的postMessage是不是可以取代window.name(同樣都需要一個iframe作為中間媒介)這類訪問方式,這個新API方式是不是在實際中很有效呢?希望有經驗的大牛可以解答,不勝感激。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/81807.html
摘要:很簡單,在的模塊中配置這樣一個參數是什么意思呢顧名思義,他是設置安全性,如果參數設置為,它將禁用相同地方的規則通常測試服并且如果有個非用戶設置的參數,就設置和的值為。表示是否允許一個使用的界面來渲染由提交的,,。 很簡單,在Electron的BrowserWindow模塊中配置這樣一個參數: mainWindow = new BrowserWindow({ webPrefere...
摘要:通過跨域通過引入的不受同源策略的限制,所以我們可以通過標簽引入一個或者是一個其他后綴形式如,等的文件,此文件返回一個函數的調用。 1.跨域的定義 只要協議、域名、端口有任何一個不同,就會被當做為不同的域,如果從A域名訪問B域名上的資源就叫做跨域。 下面我們來看下幾種跨域的方法: 2.document.domain 瀏覽器的同源策略有一些限制,第一,不能通過ajax方法去請求不同源的資源...
閱讀 2812·2019-08-30 15:55
閱讀 2858·2019-08-30 15:53
閱讀 2296·2019-08-26 13:47
閱讀 2558·2019-08-26 13:43
閱讀 3157·2019-08-26 13:33
閱讀 2805·2019-08-26 11:53
閱讀 1798·2019-08-23 18:35
閱讀 801·2019-08-23 17:16