九種跨域方式實(shí)現(xiàn)原理_第1頁
九種跨域方式實(shí)現(xiàn)原理_第2頁
九種跨域方式實(shí)現(xiàn)原理_第3頁
九種跨域方式實(shí)現(xiàn)原理_第4頁
九種跨域方式實(shí)現(xiàn)原理_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

刖百

前后端數(shù)據(jù)交互經(jīng)常會碰到請求跨域,什么是跨域,以及有哪幾種跨域方式,這

是本文要探討的內(nèi)容。

本文完整的源代碼請猛戳github博客,紙上得來終覺淺,建議動手敲敲代碼

一、什么是跨域?

1.什么是同源策略及其限制內(nèi)容?

同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源

策略,瀏覽器很容易受到XSS、CSRF等攻擊。所謂同源是指"協(xié)議+域名+端口"三

者相同,即便兩個(gè)不同的域名指向同一個(gè)ip地址,也非同源。

一個(gè)域名地址的組成:

http://WWW:8080/scripts/jquery

協(xié)議子域名主域名端口號請求資源地打

同源策略限制內(nèi)容有:

?CookieLocalstorage>IndexedDB等存儲性內(nèi)容

?DOM節(jié)點(diǎn)

?AJAX請求發(fā)送后,結(jié)果被瀏覽器攔截了

但是有三個(gè)標(biāo)簽是允許跨域加載資源:

?〈即gsrc=XXX>

?<(mkhref=XXX〉

?scriptsrc=XXX>

2.常見跨域場景

當(dāng)協(xié)議、子域名、主域名、端口號中任意一個(gè)不相同時(shí),都算作不同域。不同

域之間相互請求資源,就算作“跨域"。常見跨域場景如下圖所示:

URL說明是否允許通信

/a.js

同一域名下允許

http:///b.js

http:/A/lab/a.js

同一域名卜不同文件夾

http:///script/b.js

http://:8000/a.js

同一域名,不同端口許

http:///b.js

/a.js

同一域名,不同協(xié)議不允許

https:///b.js

http:///a.js

域名和域名對應(yīng)ip許

4/b.js

http:///a.js

iWS同,子許

/b.js

http:///a.js所域名,不^二級域名洞

不允許(cookie這種情況下也不允話

http:///b.js上)

blogs.8m/aj

s不fmg名不允許

http:///b.js

特別說明兩點(diǎn):

第一:如果是協(xié)議和端口造成的跨域問題“前臺”是無能為力的。

第二:在跨域問題上,僅僅是通過"URL的首部”來識別而不會根據(jù)域名對應(yīng)的IP

地址是否相同來判斷?!癠RL的首部”可以理解為“協(xié)議,域名和端口必須匹配”。

這里你或許有個(gè)疑問:請求跨域了,那么請求到底發(fā)出去沒有?

跨域并不是請求發(fā)不出去,請求能發(fā)出去,服務(wù)端能收到請求并正常返回結(jié)果,

只是結(jié)果被瀏覽器攔截了。你可能會疑問明明通過表單的方式可以發(fā)起跨域請求,

為什么Ajax就不會?因?yàn)闅w根結(jié)底,跨域是為了阻止用戶讀取到另一個(gè)域名下

的內(nèi)容,Ajax可以獲取響應(yīng),瀏覽器認(rèn)為這不安全,所以攔截了響應(yīng)。但是表

單并不會獲取新的內(nèi)容,所以可以發(fā)起跨域請求。同時(shí)也說明了跨域并不能完全

阻止CSRF,因?yàn)檎埱螽吘故前l(fā)出去了。

二、跨域解決方案

1.jsonp

1)JSONP原理

利用標(biāo)簽沒有跨域限制的漏洞,網(wǎng)頁可以得到從其他來源動態(tài)產(chǎn)生的

JSON數(shù)據(jù)。JSONP請求一定需要對方的服務(wù)器做支持才可以。

2)JSONP和AJAX對比

JSONP和AJAX相同,都是客戶端向服務(wù)器端發(fā)送請求,從服務(wù)器端獲取數(shù)據(jù)的

方式。但AJAX屬于同源策略,JSONP屬于非同源策略(跨域請求)

3)JSONP優(yōu)缺點(diǎn)

JSONP優(yōu)點(diǎn)是簡單兼容性好,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。缺

點(diǎn)是僅支持get方法具有局限性,不安全可能會遭受XSS攻擊。

4)JSONP的實(shí)現(xiàn)流程

?聲明一個(gè)回調(diào)函數(shù),其函數(shù)名(如Show)當(dāng)做參數(shù)值,要傳遞給跨域請求數(shù)據(jù)的服務(wù)

器,函數(shù)形參為要獲取目標(biāo)數(shù)據(jù)(服務(wù)器返回的data)。

?創(chuàng)建一個(gè)標(biāo)簽,把那個(gè)跨域的API數(shù)據(jù)接口地址,賦值給script的src,還要

在這個(gè)地址中向服務(wù)器傳遞該函數(shù)名(可以通過問號傳參:?callback=show)。

?服務(wù)器接收到請求后,需要進(jìn)行特殊的處理:把傳遞進(jìn)來的函數(shù)名和它需要給你的

數(shù)據(jù)拼接成一個(gè)字符串,例如:傳遞進(jìn)去的函數(shù)名是show,它準(zhǔn)備好的數(shù)據(jù)是showC

我不愛你')。

?最后服務(wù)器把準(zhǔn)備的數(shù)據(jù)通過HTTP協(xié)議返回給客戶端,客戶端再調(diào)用執(zhí)行之前聲

明的回調(diào)函數(shù)(show),對返回的數(shù)據(jù)進(jìn)行操作。

在開發(fā)中可能會遇到多個(gè)JSONP請求的回調(diào)函數(shù)名是相同的,這時(shí)候就需要自

己封裝一個(gè)JSONP函數(shù)。

//i八dex.htmlhmctio八jsocp({params,callback)){

returnMWProm/seffresole,reject)=>{

letscript=dociA^eiat.createElei^ei^t(,scnpt,)

wi^dow[callback]=functioi^(data){

resolve(datd)

docu^Mt.body.rei^oveCkild(scnpt)

}

params={...params,callback}//wd二b&c"/他ack=show

letarrs=[]

for(letkeyMparams){

arrs.piA$kC${key}=${para^[key]y)

}

scHpt.s%=、${“r'G?${〃rv*sJoin(,&')}、

docui^ei^t.body.appei^dCkild(scnpt')

!)

眇。呻&

〃“:lkttp://locallaost:3000/say,,

params:{wd:'lloveyou1},

callback:^kow1

}).thev\(data=>{

co^so(e.log(datd)

})

上面這段代碼相當(dāng)于向http://localhost:3000/say?wd=lloveyou&rcal(back=show這個(gè)地

址請求數(shù)據(jù),然后后臺返回沙。儂,我不愛你,),最后會運(yùn)行show()這個(gè)函數(shù),打印出

‘我不愛你’

//serverjs/etexpress=vequi必expKCSS)Ietapp=expressf)

app.get('/sagLfunctionreqres){

let{wd,callback)=req.qaery

coi^sole.log(\A/d)//Iloveyou

coiasole.log(callback)//show

%s.eM(、${c〃他枇k}('我不愛你')、)

1)

app.(iste^.(3ooo)

5)jQuery的jsonp形式

JSONP都是GET和異步請求的,不存在其他的請求方式和同步請求,且jQuery

默認(rèn)就會給JSONP的請求清除緩存。

$.ajax({u^l:"http://crossdol^ai^.co^v\/jsoK\Ser/eirR.espo^e,,,dataType:,,jsol^p,,jtype^get",//^\

以省略“。*小他牝匕〃6人。卬〃,〃-〉自定義傳遞給服務(wù)器的函數(shù)名,而不是使用jQuery門動生成的,可

「js。八p:"cH傷〃ck〃,//->把仕'%callhack,可省略success.fuMtioi^(data){

co^sole.tog(datd);^);

2.cors

CORS需要瀏覽器和后端同時(shí)支持。IE8和9需要通過XDomainRequest來實(shí)

現(xiàn)。

瀏覽器會自動進(jìn)行CORS通信,實(shí)現(xiàn)CORS通信的關(guān)鍵是后端。只要后端實(shí)現(xiàn)

了CORS,就實(shí)現(xiàn)了跨域。

服務(wù)端設(shè)置Access-Control-Allow-Origin就可以開啟CORS。該屬性表示哪些域

名可以訪問資源,如果設(shè)置通配符則表示所有網(wǎng)站都可以訪問資源。

雖然設(shè)置CORS和前端沒什么關(guān)系,但是通過這種方式解決跨域問題的話,會

在發(fā)送請求時(shí)出現(xiàn)兩種情況,分別為簡單請求和復(fù)雜請求。

1)簡單請求

只要同時(shí)滿足以下兩大條件,就屬于簡單請求

條件1:使用下列方法之一:

GET

HEAD

POST

條件2:Content-Type的值僅限于下列三者之一:

text/plain

multipart/form-data

application/x-www-form-urlencoded

請求中的任意XMLHttpRequestUpload對象均沒有注冊任何事件監(jiān)聽器;

XMLHttpRequestUpload對象可以使用XMLHttpRequest.upload屬性訪問。

2)復(fù)雜請求

不符合以上條件的請求就肯定是復(fù)雜請求了。

復(fù)雜請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預(yù)

檢"請求,該請求是option方法的,通過該請求來知道服務(wù)端是否允許跨域請求。

我們用PUT向后臺請求時(shí),屬于復(fù)雜請求,后臺需做如下配置:

//允許哪個(gè)方法訪問我

re.sse.tHead.er('Access-Control-Allow-Methods','PUT)//預(yù)檢的存活時(shí)間

resse.tHeade.r('Access-Control-N\ax-A.ge',6)〃OPTIONS請求不做任何處理if(recj.Method===

'OPTIONS'){

八d()

}//定義后臺返回的內(nèi)容

app.putC/getData1j缶八戊缶心犯res){

c。八so/e」og(?eq.〃e〃deKS)

%s.e八d,我不愛你,)

!)

接下來我們看下一個(gè)完整復(fù)雜請求的例子,并且介紹下CORS請求相關(guān)的字段

//

letxhr=MWXMLHttpRe^uestO

docui^e^t.cookie=%4HAe//cookie不能跨域

xhr.witkCrede^tials=true//前端設(shè)位是否帶cookie

xkr.opeia(fPUT,,lk\ttp://localk\ost:4000/getU>ata,,true)

xkrsetR.equestHeaderCnai^e',^iai^eia1)

xhr.oi^readystatecha^.ge=fu八ctio八(){

if(xhr.readyState===4){

if((xhr.status>=200&&xhr.status<300)||xhr.status===3(94){

console.!og(xhcresponse)

〃得到響應(yīng)頭,后臺需設(shè)置Access-C。八卅。/-Expose-Hende%

co^ole.log(xhr.getRespo^seHeader(,Mkv\e,))

}

]

}

X^K.SCnd()

//serveMjsIctexpress=scq認(rèn)i必exp七支);Ietapp=express。;

app.use(expKCSS.static(_dinaaMC));

〃叩」及e八(3000);

//servcrZjs

letexpress=%q〃"e('exp%ss')

letapp=express。

letwhitList=I1http.//localhost:3000']〃設(shè)置白名單

app.iA^(f(AMtioi^(req,res,next){

letorigin=夕eq.headers.oHgi八

if(whitList.Mcl認(rèn)des(oHgi心{

//設(shè)置哪個(gè)源可以訪問我

ressetHeader('Acce^-Co^t^ol-Allow-Origin,origin)

//允許攜帶哪個(gè)頭訪問我

ressetHeader('Access-Control-Atlow-Headers1,

//允許哪個(gè)方法訪問我

ressetHeaderCAccess-Control-Allow-Methods'j'PUT)

//允許攜帶cookie

^setHeaderCAccess-Co^trol-Allow-Credentials'jtrue)

//預(yù)檢的存活時(shí)間

ressetHeader('Acce^-Co^tKol-Max-Age1j6)

//允許返回的頭

ressetHeader('Acce^-Coi^trol-Expose-Headedj'taai^e1)

if(reqMethod---OPTIONS1){

%s.e八d()//OPTIONS請求不做任何處理

)

)

nextf)

1)

app.put(7getData,,缶八由0八(叱/res){

co八S0/eJog"eq.〃eqdeKS)

res.s況He〃We「(k〃儂e「Jw,)//返回一個(gè)響應(yīng)頭,后臺需設(shè)置

res.我不愛你)

1)

app.get(7getData1,F〃八cti。八(req,res){

c。八so/eJog(Keq.〃e〃ders)

%s.CKd[我不愛你)

1)

即p.use(cxp%ss,st岫Z(_d"八4kv\e))

app.IisteN4。。。)

上述代碼由http:〃localhost3000/index.htM1向http:〃/℃〃供。允:4。。。/跨域請求,正

如我們上面所說的,后端是實(shí)現(xiàn)CORS通信的關(guān)鍵。

3.postMessage

postMessage是HTML5XMLHttpRequestLevel2中的API,且是為數(shù)不多可以跨域

操作的window屬性之一,它可用于解決以下方面的問題:

?頁面和其打開的新窗口的數(shù)據(jù)傳遞

?多窗口之間消息傳遞

?頁面與嵌套的iframe消息傳遞

?上面三個(gè)場景的跨域數(shù)據(jù)傳遞

postMessage。方法允許來自不同源的腳本采用異步方式進(jìn)行有限的通信,可以

實(shí)現(xiàn)跨文本檔、多窗口、跨域消息傳遞。

otherWindow.postMessage(message,targetOrigin,

[transfer]);

?message:將要發(fā)送到其他window的數(shù)據(jù)。

?targetorigin:通過窗口的origin屬性來指定哪些窗口能接收到消息事件,其值可以是

字符串"*"(表示無限制)或者一個(gè)URI。在發(fā)送消息的時(shí)候,如果目標(biāo)窗口的協(xié)議、

主機(jī)地址或端口這三者的任意一項(xiàng)不匹配targetorigin提供的值,那么消息就不會被

發(fā)送;只有三者完全匹配,消息才會被發(fā)送。

?transfer(可選):是一串和message同時(shí)傳遞的Transferable對象.這些對象的所有

權(quán)將被轉(zhuǎn)移給消息的接收方,而發(fā)送一方將不再保有所有權(quán)。

接下來我們看個(gè)例子:http://localhost:300C>/a.hti^\l頁面向

kttp://localhost:4000/b.ht^l傳遞"我愛你",然后后者傳回"我不愛你"。

//

src="http://(oca(kost:4000/b.ht^v\lnfgMeboMeU。以="fsMe"

o^load="load0n></ifrai^\e>〃等它加載完觸發(fā)一個(gè)事件

//內(nèi)嵌在http://(ocalkost:3OOO/

<script>

Functionload(){

letfrakv\e=docu^e^.t.getElei^\entByld(,frai^\e,')

frai^e.co^te^t^i^dow.postMessageC^S,^','http://(ocalk\o^t:4000,)//發(fā)送數(shù)據(jù)

w/'八dow.o八message=八c力'。八(e){//接受返回?cái)?shù)據(jù)

co^ole.log(e.data)//我不愛你

)

}

〈/scHpt〉

//b.hti^l

wi八dow.o八儂css?gc=Functio八(e){

coi^sole.log(e.datd)//我愛你

c.souKce.postrMessageC我不愛你1e.origiia)

}

4.websocket

Websocket是HTML5的一個(gè)持久化的協(xié)議,它實(shí)現(xiàn)了瀏覽器與服務(wù)器的全雙工

通信,同時(shí)也是跨域的一種解決方案。WebSocket和HTTP都是應(yīng)用層協(xié)議,都

基于TCP協(xié)議。但是WebSocket是一種雙向通信協(xié)議,在建立連接之后,

WebSocket的server與client都能主動向?qū)Ψ桨l(fā)送或接收數(shù)據(jù)。同時(shí),

WebSocket在建立連接時(shí)需要借助HTTP協(xié)議,連接建立好了之后client與

server之間的雙向通信就與HTTP無關(guān)了。

原生WebSocketAPI使用起來不太方便,我們使用Socket.?它很好地封裝了

webSocket接口,提供了更簡單、靈活的接口,也對不支持WebSocket的瀏覽器

提供了向下兼容。

我們先來看個(gè)例子:本地文件socket.html向localhost:3000發(fā)生數(shù)據(jù)和接受數(shù)據(jù)

//$ocket.hti^l<script>

letsocket=MW\/JebSocket(,\A/^://localho^t:30001);

socket.onope八=Feme力'。八0(

socket.seed(俄愛你力//向服務(wù)器發(fā)送數(shù)據(jù)

]

sockct.oi^^cssage=fimcticm(e){

C。八6。/01。9(0以比〃);//接收服務(wù)器返回的數(shù)據(jù)

}<Acr/pt>

//serverjsletexpress=require('express*);(&tapp=express();letVJebSocket=%q〃i*Cws');//

記得安裝wsletwss=MWWcSSocket.ScrverfWortaoo。});

wss.OhCconncctio"/LmctioF\(ws){

ws.o八(如cssagc',fimcti。八(data){

co^ole.log(data);

wsse八砥我不愛你,)

));

1)

5.Node中間件代理(兩次跨域)

實(shí)現(xiàn)原理:同源策略是瀏覽器需要遵循的標(biāo)準(zhǔn),而如果是服務(wù)器向服務(wù)器請求

就無需遵循同源策略。

代理服務(wù)器,需要做以下幾個(gè)步驟:

?接受客戶端請求。

?將請求轉(zhuǎn)發(fā)給服務(wù)器。

?拿到服務(wù)器響應(yīng)數(shù)據(jù)。

?將響應(yīng)轉(zhuǎn)發(fā)給客戶端。

我們先來看個(gè)例子:本地文件index.html文件,通過代理服務(wù)器

kttp://localkost:3000向目標(biāo)服務(wù)器kttp://localhost.4000請求數(shù)據(jù)。

//iWex.htm【(http://。:550。)

Scriptsrc=,,https://cdk\.bootc^.cokv\/jquery/3.3.1/j6)uery.i^iia.js,,></script>

urf:'kttp://loca(host:3000,,

type:'post1,

data:{八ai/v\c:password:Z12.34S6Z],

coiate^tType:1application/jso^c^av'se.t-utfS,

success:fix八無,。八(憶6川土){

coMole.log(irewlt)//{"tit/e":"F。八te八建'/password":"工2345E"}

error:feme力'。八(knsg){

conso/e./og(HASg)

)

1)

</script>

//serverijs代理服務(wù)器

consthttp-^equireCkttp')//第步:接受客戶端清求

coiastserver=http.createServe^request,response)=>{

//代理服務(wù)器,直接和瀏覽器直接交互,需要設(shè)置CORS的首部字段

%sp0nse.WKit0He〃d(2OO,{

'Acce^-Co^trol-Allow-Origin1:

Access-Control-Allow-Methods':'巴

'Access-C。八tr。/-A"ow-Headers,:,Coiateiat-Type,

!)

//第二步:將請求轉(zhuǎn)發(fā)給服務(wù)器

constproxyRequest=http

.Keq〃es2(

(

host:427Q.O.”j

port:4-OOO,

url:7S

method:request.i^etkodj

headers:request.headers

)>

serv"Respo八se=>{

//第三步:收到服務(wù)器的響應(yīng)

varbody=〃

servcrRcsp。八sc.。八(以〃僅,chui^k=>{

body-+■=ckuiak

1)

servcHRcsponsc.oM'e八血()=>{

console.logCThedatais1+body)

//第四步:將響應(yīng)結(jié)果轉(zhuǎn)發(fā)給瀏覽器

wsponse.e八d(bodg)

!)

}

)

."d()

!)

server〃很八。=>{

co八sole.logCTheproxyServerisnx八八ingatk\ttp://localhost:'50001)

1)

//mw2.js(http://localhost:4000)co八sthttp=data-{title:YontendL

password:/i2.34S6/}co^tserver=http.CFeateSen/?《"cqiACSt,response)=>{

if(request.url===71){

uesponse.c八d(JSON.stHngifg(data))

1

1)

servcH./kte八(4000,0=>{

ccmsoElogCTheserverisruiaiaiiagathttp://loca(host:4000')

1)

上述代碼經(jīng)過兩次跨域,值得注意的是瀏覽器向代理服務(wù)器發(fā)送請求,也遵循同

源策略,最后在index.html文件打印出{〃比也":叩。八死八d〃W〃sswoKd":"i2345G〃}

6.nginx反向代理

實(shí)現(xiàn)原理類似于Node中間件代理,需要你搭建一個(gè)中轉(zhuǎn)nginx服務(wù)器,用于轉(zhuǎn)

發(fā)請求。

使用nginx反向代理實(shí)現(xiàn)跨域,是最簡單的跨域方式。只需要修改nginx的配置

即可解決跨域問題,支持所有瀏覽器,支持session,不需要修改任何代碼,并

且不會影響服務(wù)器性能。

實(shí)現(xiàn)思路:通過nginx配置一個(gè)代理服務(wù)器(域名與domainl相同,端口不同)

做跳板機(jī),反向代理訪問domain2接口,并且可以順便修改cookie中domain信

息,方便當(dāng)前域cookie寫入,實(shí)現(xiàn)跨域登錄。

先下載nginx,然后將nginx目錄下的nginx.conf修改如下:

//proxy服務(wù)器

server(

listen

servewww.donA川認(rèn)工.COM;

location/{

kttp://www.don/uuh2.C0M:8O8O;#反向代理

proxy_cookie_doi^aii^www.do^vuu?八2.COMwww.dokvuu'八工(。出;#修改cookie里域名

index/Wex.htm/

#當(dāng)用webpack-de—server等中間件代理接口訪問八匕nx時(shí),此時(shí)無瀏覽器參與,故沒

有同源限制,下面的跨域配置可不啟用

add_keaderAccess-Control-Allow-OriginMttp://;#”'i前端只

跨域不帶cookie時(shí),可為*

add_headerAccess-Control-Allow-Credentialstrue;

]

}

最后通過命令行nginx-$reload啟動nginx

//hadex.kt^lvarxtir=MWXMLHttpReq〃estO;〃吊j■端開關(guān):瀏覽器是否讀寫cookie

xhr.witkCredeiatials=true;//訪問ng/Mx中的代理服務(wù)器

xknopc八('get—,Attp://www.doHA〃iKL.C0M:21/?〃ser=〃Wkvu'n。true);

xkr.se八(d);

//serverjsv^rhttp=requireCktlp'^varserver=http.c^eateServer();varqs=

力八g');

request1,八c力'。八(「eq,res){

vav'params=qs.parse(req.urlsubstn^5(2.));

//向前臺寫cookie

Kcs.w力teHe〃d(2。。,(

'Set-Cookie':'仁al2345G;Pa仍=/;DOFVUU'八二www.dok〃i八2.com;Http。八?//

Http。八腳本無法讀取

));

ues.wKite(JSON.stH八gifg(pa^aMS));

res."4);

1);

server.〃steK('8080');conso/e」ogCServerisHX八八以gatport8080...');

7.window,name+iframe

屬性的獨(dú)特之處:name值在不同的頁面(甚至不同域名)加載后

依舊存在,并且可以支持非常長的name值(2MB)。

其中a.html和b.html是同域的,都是kttp://localhost:3000;ffijc.html是

http://localhost:400C>

//a.kti^l(kttp://localhost:3000/b.htiAA.I)

<ifrakv\esrc="http://localhost:4000/c.ht^lnfr〃儂地?!ā?"O〃o^load-'loadO1'

id-"if^aHAC"〉</ifsme>

<script>

letfirst=true

//onload事件會觸發(fā)2次,第1次加載跨域頁,并留存數(shù)據(jù)于w以dowma3e

functionload(){

//第2次。八/。彰(跨域頁)成功后,切換到同域代理頁面

let/frame=doc(Ai^\e^t.getElekv\e^tByld(,ifrakv\ef);

ifrai^esrc=,http://localkost:3000/b.hti^ll;

first=Fake;

〃第2次。八load(同域頁)成功后,讀取同域wi八dow.八〃出0中數(shù)據(jù)

c。八os/e./og(,F(xiàn)r口期c.c。八八tW/認(rèn)Wow.八

)

)

</scnpt>

b.html為中間代理頁,與a.html同域,內(nèi)容為空。

//c.kti^((kttp://localkost:4000/c.kti^l)

<scnpt>

wii^dow.iaai^e='我不愛你,

〈/script》

總結(jié):通過iframe的src屬性由外域轉(zhuǎn)向本地域,跨域數(shù)據(jù)即由iframe的

從外域傳遞到本地域。這個(gè)就巧妙地繞過了瀏覽器的跨域訪問限制,

但同時(shí)它又是安全操作。

8.location,hash+iframe

實(shí)現(xiàn)原理:a.html欲與c.html跨域相互通信,通過中間頁b.html來實(shí)現(xiàn)。三個(gè)

頁面,不同域之間利用iframe的location.hash傳值,相同域之間直接js訪問來

通信。

具體實(shí)現(xiàn)步驟:一開始a.html給c.html傳一個(gè)hash值,然后c.html收到hash

值后,再把hash值傳遞給b.html,最后b.html將結(jié)果放到a.html的hash值中。

同樣的,a.html和b.html是同域的,都是http:〃/oca以ost:308;而c.html是

kttp://localhost:4000

//a.html

src-"http://localkost:4000/c.hti^l^Hoveyou"></if

<sciript>

w/認(rèn)dow.on4nge=fuMtion

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論