今天學了跨域覆致,迫不及待想跟大家分享侄旬!不妥之處希望大家指正。
首先來明確一下“跨域”這個概念煌妈。
跨域指的是儡羔,到外域去取數(shù)據(jù)。那什么是“外域”呢声旺?我們先來了解同域笔链。同域指的是,同協(xié)議腮猖、同域名鉴扫、同端口。如果兩個URL澈缺,協(xié)議相同坪创,域名相同,端口號相同姐赡,那么這兩個URL就屬于同域莱预。那么外域就是,協(xié)議不同项滑,或者域名不同依沮,或者端口號不同。注意枪狂,這三者只要其中一個不同危喉,就不屬于同域。
我們看看例子:
http://www.reibang.com/a.html
http://www.reibang.com/b.html
//同域州疾。協(xié)議相同辜限,域名相同,端口號相同(默認80端口)
http://a.jianshu.com
http://b.jianshu.com
//不同域严蓖。域名不同
http://www.reibang.com
http://www.reibang.com
//不同域薄嫡。協(xié)議不同
舉例完畢,接下來將會講講以下三種跨域的方式颗胡。
- CORS
- 降域
- JSONP
CORS
CORS全稱是跨域資源共享(Cross-Origin Resource Sharing)毫深,是一種Ajax跨域請求資源的方式。實現(xiàn)方式很簡單杭措,當你使用XMLHttpRequest發(fā)送請求時费什,如果該請求不符合同源策略,瀏覽器會給該請求加一個請求頭:Origin手素,而后臺會在返回結(jié)果中加一個響應頭:Access-Control-Allow-Origin,瀏覽器判斷該響應頭是否包含Origin的值鸳址,如果包含,瀏覽器就會處理響應泉懦,我們就可以拿到數(shù)據(jù)稿黍;如果不包含,瀏覽器就會直接駁回崩哩,我們就拿不到數(shù)據(jù)巡球。
那么怎么做才能讓我們跨域拿到數(shù)據(jù)呢?很簡單邓嘹,我們只需在遠程文件中加上這一行代碼:
header("Access-Control-Allow-Origin","允許請求的URL酣栈,*為允許全部")
比如,header("Access-Control-Allow-Origin","http://www.reibang.com")
會允許來自 http://www.reibang.com 的請求汹押,而header("Access-Control-Allow-Origin","*")
會允來自任何域的請求矿筝。
降域
如果我們從 a.jianshu.com 請求 b.jianshu.com 的數(shù)據(jù),像這種子頁面不相同的情況就是適合利用降域來跨域了棚贾。實現(xiàn)起來也很簡單窖维,只需在本地文件和遠程文件都加上這句代碼:
document.domain="jianshu.com"
也就是說,直接把主網(wǎng)頁的域名寫上就可以了,這樣就實現(xiàn)了利用降域來跨域妙痹。
JSONP
好了铸史,重點來了,JSONP是非常常用的跨域方法怯伊,它通過動態(tài)創(chuàng)建script標簽來實現(xiàn)跨域琳轿。
眾所周知,通過script來加載外部文件是不存在同源策略的限制的耿芹,我們可以請求任何域的文件而不需要跨域崭篡。確切的說,任何含有src或者href屬性的標簽都不存在同源策略的限制猩系。利用這個特點媚送,我們把遠程文件的URL放到script標簽的src中,這樣就得到了遠程文件中的數(shù)據(jù)寇甸,然后把這些數(shù)據(jù)作為參數(shù)傳入一個函數(shù)塘偎,就可以按自己需求處理和呈現(xiàn)了。我們看看具體怎么實現(xiàn):
//遠程數(shù)據(jù)地址
var url="http://api.jirengu.com/fm/getSong.php?callback=handler";
//創(chuàng)建script標簽
var script=document.createElement('script');
//把script標簽src設為遠程數(shù)據(jù)地址
script.setAttribute('src',url);
//把script標簽加到head中
document.getElementsByTagName('head')[0].appendChild(script);
//回調(diào)處理函數(shù)
function handler(data){
//some code here...
}
注意拿霉,要在遠程數(shù)據(jù)地址尾部加上回調(diào)函數(shù)名吟秩, 服務器會動態(tài)用這個函數(shù)名包裹住數(shù)據(jù),也就是將數(shù)據(jù)作為這個函數(shù)的參數(shù)绽淘,這樣返回到本地之后就可以執(zhí)行相應函數(shù)了涵防。
舉個栗子,當我們以callback為getCity請求數(shù)據(jù)沪铭,服務器返回了的數(shù)據(jù)是這樣的:
getCity(
{"city":
[
{
"name":"廣州",
"cid":"578"
},
{
"name":"廈門",
"cid":"586"
}
]
}
)
我們的getCity函數(shù)是這樣的:
function getCity(data){
console.log(data.city[0].name);
}
這樣我們就log出了廣州壮池,跨域成功偏瓤!是不是很簡單啊椰憋!
好了厅克,跨域就講這么多。歡迎交流橙依,歡迎指正证舟!
原創(chuàng)文章,轉(zhuǎn)載請注明出處窗骑!