摘要:實(shí)現(xiàn)跨域的原理通過(guò)方式請(qǐng)求載入并執(zhí)行一個(gè)文件,相當(dāng)于通過(guò)的形式的導(dǎo)入一個(gè)外部的方法語(yǔ)法該函數(shù)是簡(jiǎn)寫的函數(shù),等價(jià)于在中,您可以通過(guò)使用形式的回調(diào)函數(shù)來(lái)加載其他網(wǎng)域的數(shù)據(jù),如。將自動(dòng)替換為正確的函數(shù)名,以執(zhí)行回調(diào)函數(shù)。
更多詳情見http://blog.zhangbing.club/Ja...
最近在項(xiàng)目開發(fā)的過(guò)程中遇到一些Javascript 跨域請(qǐng)求的問題,今天抽空對(duì)其進(jìn)行總結(jié)一下,以備后用,也希望同學(xué)們?cè)谟龅筋愃茊栴}的時(shí)候可以有所幫助。
Javascript跨域問題是web開發(fā)人員最常碰到的一個(gè)問題之一。所謂Javascript跨域問題,是指在一個(gè)域下的頁(yè)面中通過(guò)js訪問另一個(gè)不同域下的數(shù)據(jù)對(duì)象,出于安全性考慮,幾乎所有瀏覽器都不允許這種跨域訪問,這就導(dǎo)致在一些ajax和iframe應(yīng)用中,使用跨域的web service會(huì)成為一個(gè)問題。
javascript跨域圖表那到底什么是跨域,簡(jiǎn)單地理解就是因?yàn)镴avaScript同源策略的限制,a.com 域名下的js無(wú)法操作b.com或是c.a.com域名下的對(duì)象。更詳細(xì)的說(shuō)明可以看下表:
特別注意兩點(diǎn):
第一,如果是協(xié)議和端口造成的跨域問題“前臺(tái)”是無(wú)能為力的,
第二:在跨域問題上,域僅僅是通過(guò)“URL的首部”來(lái)識(shí)別而不會(huì)去嘗試判斷相同的ip地址對(duì)應(yīng)著兩個(gè)域或兩個(gè)域是否在同一個(gè)ip上。
“URL的首部”指window.location.protocol +window.location.host,也可以理解為“Domains, protocols and ports must match”(本段來(lái)自網(wǎng)絡(luò),個(gè)人覺得這段對(duì)js跨域描述得在清晰不過(guò)了)。跨域請(qǐng)求無(wú)處不在,平時(shí)我們?cè)陂_發(fā)活動(dòng)過(guò)程中,活動(dòng)靜態(tài)頁(yè)面通過(guò)Javascript訪問前端CGI就是明顯的主域相同,子域不同的跨域例子,一般活動(dòng)靜態(tài)頁(yè)面都是類似這樣的(http://業(yè)務(wù)名.xx.com/act/活動(dòng)...,前端CGI 是這樣的(http://www.xx.com/act/活動(dòng)目... 下面來(lái)看看我們都是如何處理跨域請(qǐng)求的:
動(dòng)態(tài)創(chuàng)建script雖然瀏覽器默認(rèn)禁止了跨域訪問,但并不禁止在頁(yè)面中引用其他域的JS文件,script標(biāo)簽的src屬性引用指向接收方的一個(gè)處理地址(后臺(tái)),該地址返回的javascript方法會(huì)被執(zhí)行,另外URL中可以傳入一些參數(shù),該方法只支持GET方式提交參數(shù)。我們常用FloadJS方法用的就是這種跨域方式。
使用Jquery中g(shù)etScript和getJson方法實(shí)現(xiàn)跨域Jquery 的getScript 和 getJson方法都可以調(diào)用跨域的js或服務(wù)端腳本,但是它們的實(shí)現(xiàn)原理不一樣。
1.getScript 方法
語(yǔ)法:jQuery.getScript(url,success(response,status))
該函數(shù)是簡(jiǎn)寫的 Ajax 函數(shù),等價(jià)于:
$.ajax({ Type: get, url: url, dataType: "script", success: success });
jQuery 1.2 版本之前,getScript 只能調(diào)用同域 JS 文件。 1.2中,您可以跨域調(diào)用 JavaScript 文件。注意:Safari 2 或更早的版本不能在全局作用域中同步執(zhí)行腳本。如果通過(guò) getScript 加入腳本,請(qǐng)加入延時(shí)函數(shù)。
實(shí)現(xiàn)跨域的原理:通過(guò) GET 方式請(qǐng)求載入并執(zhí)行一個(gè) JavaScript 文件, 相當(dāng)于通過(guò)src的形式的導(dǎo)入一個(gè)外部的js
2.getJson方法
語(yǔ)法:jQuery.getJSON(url,data,success(data,status,xhr))
該函數(shù)是簡(jiǎn)寫的 Ajax 函數(shù),等價(jià)于:
$.ajax({ url: url, data: data, success: callback, dataType: json });
在jQuery 1.2 中,您可以通過(guò)使用 JSONP 形式的回調(diào)函數(shù)來(lái)加載其他網(wǎng)域的 JSON 數(shù)據(jù),如 "myurl?callback=?"。jQuery 將自動(dòng)替換 ? 為正確的函數(shù)名,以執(zhí)行回調(diào)函數(shù)。
實(shí)現(xiàn)跨域的原理:采用Jsonp原理實(shí)現(xiàn)跨域
到這里大家有沒有發(fā)現(xiàn)一個(gè)問題,好像一直都在討論http get 請(qǐng)求方式的跨域問題,難道post 請(qǐng)求就不存在跨域問題嗎?其實(shí)原生態(tài)From 表單 POST 到一個(gè)后臺(tái)處理腳本是不存在跨域問題,因?yàn)樘峤贿^(guò)程不牽涉到JS操作其它域名的對(duì)象,可是POST表單后,頁(yè)面會(huì)刷新,給用戶帶來(lái)的體驗(yàn)不佳,這時(shí)我們經(jīng)常會(huì)想到用jquery ajax post 方法來(lái)提交表單, 雖然這種方式不會(huì)刷新頁(yè)面,但是會(huì)存在跨域問題。因?yàn)閍jax本身實(shí)際上是通過(guò)XMLHttpRequest對(duì)象來(lái)進(jìn)行數(shù)據(jù)的交互,而瀏覽器出于安全考慮,是不允許js代碼進(jìn)行跨域操作,進(jìn)而會(huì)發(fā)警告,所以jquery ajax post 是行不通的,可能這時(shí)有人會(huì)說(shuō),用jsonp數(shù)據(jù)類型啊,但是jsonp目前只支持get請(qǐng)求方式,對(duì)post請(qǐng)求不支持。我們?cè)谄綍r(shí)開發(fā)過(guò)程又不得不用post方式,因?yàn)間et方式對(duì)請(qǐng)求的數(shù)量有大小限制,那在這種情況下如何保證用戶良好的頁(yè)面體驗(yàn),又能解決跨域問題呢? 其實(shí)這時(shí)我們可以用最常見的document.domain + iframe 方式來(lái)實(shí)現(xiàn)。
document.domain + iframe這種方式只適用主域名相同,子域名不同的情形,在我們項(xiàng)目開發(fā)過(guò)程,這種方式還是比較適用。
服務(wù)端代理從上面的說(shuō)明可以看到,客戶端的解決方案局存在一定的局限性,而且對(duì)于ajax跨域請(qǐng)求,無(wú)論兩個(gè)域是否屬于同個(gè)基礎(chǔ)域,都無(wú)法在客戶端加以解決,也就是說(shuō)如果我們要想在ajax請(qǐng)求中訪問其他域下的數(shù)據(jù),就只能通過(guò)服務(wù)端進(jìn)行處理了。服務(wù)端的解決方案的基本原理就是,由客戶端將請(qǐng)求發(fā)給本域服務(wù)器,再由本域服務(wù)器的代理來(lái)請(qǐng)求數(shù)據(jù)并將響應(yīng)返回給客戶端。
使用HTML 5 postMessage方式HTML5中最酷的新功能之一就是 跨文檔消息傳輸Cross Document Messaging。下一代瀏覽器都將支持這個(gè)功能:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。 Facebook已經(jīng)使用了這個(gè)功能,用postMessage支持基于web的實(shí)時(shí)消息傳遞。
otherWindow.postMessage(message, targetOrigin);
otherWindow: 對(duì)接收信息頁(yè)面的window的引用??梢允琼?yè)面中iframe的contentWindow屬性;window.open的返回值;通過(guò)name或下標(biāo)從window.frames取到的值。
message: 所要發(fā)送的數(shù)據(jù),string類型。
targetOrigin: 用于限制otherWindow,“*”表示不作限制
a.com/index.html中的代碼。
但是HTML5 在IE6, IE7瀏覽器下不兼容,目前移動(dòng)端解決跨域問題用得比較多, PC機(jī)上用得比較少。
如果你要讀取一個(gè)外部文件,比如swf,picture,mp3等等,那么就需要一個(gè)跨域策略文件,allow-access-from domain表示允許訪問的URl,如果有多個(gè)依次添加,如果允許所有就一個(gè) allow-access-from domain = "*"就可以了。
個(gè)人小結(jié)在項(xiàng)目開發(fā)過(guò)程如果能用get方式解決的就盡量使用它,畢竟get的性能也比post高,而且處理get跨域請(qǐng)求的方法也比較多,比如用jquery庫(kù)的 getScript和getJson方法。如果提交的數(shù)據(jù)比較大,一定用post方式提交,并且考慮用戶的功能體驗(yàn),可以用document.domain + iframe的方式來(lái)處理。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95577.html
摘要:之前我們講了一下四種跨域的方式四種跨域方式詳解。這四種方式是使用純來(lái)進(jìn)行跨域的。今天就介紹兩種有涉及到服務(wù)器的跨域技術(shù)。 之前我們講了一下四種 JavaScript 跨域的方式 - 「JavaScript」四種跨域方式詳解。這四種方式是使用純 JavaScript 來(lái)進(jìn)行跨域的。 今天就介紹兩種有涉及到服務(wù)器的跨域技術(shù)。 一、反向代理服務(wù)器 基礎(chǔ)思想很簡(jiǎn)單,將你的服務(wù)器配置成 需要跨域...
摘要:三原因分析瀏覽器在加載可以跨域資源時(shí),在將資源載入頁(yè)面時(shí)對(duì)其進(jìn)行識(shí)別與攔截等一系列處理。從而禁用了客戶端瀏覽器的類型嗅探行為即把不可執(zhí)行的類型轉(zhuǎn)變?yōu)榭蓤?zhí)行的類型。 一、jsonp的使用 jsonp是實(shí)現(xiàn)跨域請(qǐng)求數(shù)據(jù)的一種方式,解決了由于瀏覽器同源策略帶來(lái)的安全限制;雖然瀏覽器有同源策略的限制,但對(duì)于一些特殊的dom元素卻可引用非同源資源,例如 等,下面結(jié)合例子說(shuō)明: jquery直接發(fā)...
摘要:注為頂級(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... ??本文介紹了什么是跨域,為什么要跨域,以及跨域的一種...
摘要:產(chǎn)生跨域問題的原因跨域問題是瀏覽器同源策略限制,當(dāng)前域名的只能讀取同域下的窗口屬性。比如,其中是協(xié)議名,是子域名,是主域名,端口號(hào)是,當(dāng)在在頁(yè)面中從一個(gè)請(qǐng)求數(shù)據(jù)時(shí),如果這個(gè)的協(xié)議名子域名主域名端口號(hào)任意一個(gè)有一個(gè)不同,就會(huì)產(chǎn)生跨域問題。 產(chǎn)生跨域問題的原因 跨域問題是瀏覽器同源策略限制,當(dāng)前域名的js只能讀取同域下的窗口屬性。 跨域問題產(chǎn)生的場(chǎng)景 當(dāng)要在在頁(yè)面中使用js獲取其他網(wǎng)...
閱讀 3892·2021-09-27 13:36
閱讀 4625·2021-09-22 15:12
閱讀 3072·2021-09-13 10:29
閱讀 1840·2021-09-10 10:50
閱讀 2374·2021-09-03 10:43
閱讀 528·2019-08-29 17:10
閱讀 453·2019-08-26 13:52
閱讀 3265·2019-08-23 14:37