今天學了跨域,迫不及待想跟大家分享!不妥之處希望大家指正。 首先來明確一下“跨域”這個概念。 跨域指的是,到外域去取數據。那什麼是“外域”呢?我們先來瞭解同域。同域指的是,同協議、同功能變數名稱、同埠。如果兩個URL,協議相同,功能變數名稱相同,埠號相同,那麼這兩個URL就屬於同域。那麼外域就是,協議不同,或者 ...
今天學了跨域,迫不及待想跟大家分享!不妥之處希望大家指正。
首先來明確一下“跨域”這個概念。
跨域指的是,到外域去取數據。那什麼是“外域”呢?我們先來瞭解同域。同域指的是,同協議、同功能變數名稱、同埠。如果兩個URL,協議相同,功能變數名稱相同,埠號相同,那麼這兩個URL就屬於同域。那麼外域就是,協議不同,或者功能變數名稱不同,或者埠號不同。註意,這三者只要其中一個不同,就不屬於同域。
我們看看例子:
http://www.jianshu.com/a.html
http://www.jianshu.com/b.html
//同域。協議相同,功能變數名稱相同,埠號相同(預設80埠)
http://a.jianshu.com
http://b.jianshu.com
//不同域。功能變數名稱不同
https://www.jianshu.com
http://www.jianshu.com
//不同域。協議不同
舉例完畢,接下來將會講講以下三種跨域的方式。
- CORS
- 降域
- JSONP
CORS
CORS全稱是跨域資源共用(Cross-Origin Resource Sharing),是一種Ajax跨域請求資源的方式。實現方式很簡單,當你使用XMLHttpRequest發送請求時,如果該請求不符合同源策略,瀏覽器會給該請求加一個請求頭:Origin,而後臺會在返回結果中加一個響應頭:Access-Control-Allow-Origin,瀏覽器判斷該響應頭是否包含Origin的值,如果包含,瀏覽器就會處理響應,我們就可以拿到數據;如果不包含,瀏覽器就會直接駁回,我們就拿不到數據。
那麼怎麼做才能讓我們跨域拿到數據呢?很簡單,我們只需在遠程文件中加上這一行代碼:
header("Access-Control-Allow-Origin","允許請求的URL,*為允許全部")
比如,header("Access-Control-Allow-Origin","http://www.jianshu.com")
會允許來自 http://www.jianshu.com 的請求,而header("Access-Control-Allow-Origin","*")
會允來自任何域的請求。
降域
如果我們從 a.jianshu.com 請求 b.jianshu.com 的數據,像這種子頁面不相同的情況就是適合利用降域來跨域了。實現起來也很簡單,只需在本地文件和遠程文件都加上這句代碼:
document.domain="jianshu.com"
也就是說,直接把主網頁的功能變數名稱寫上就可以了,這樣就實現了利用降域來跨域。
JSONP
好了,重點來了,JSONP是非常常用的跨域方法,它通過動態創建script標簽來實現跨域。
眾所周知,通過script來載入外部文件是不存在同源策略的限制的,我們可以請求任何域的文件而不需要跨域。確切的說,任何含有src或者href屬性的標簽都不存在同源策略的限制。利用這個特點,我們把遠程文件的URL放到script標簽的src中,這樣就得到了遠程文件中的數據,然後把這些數據作為參數傳入一個函數,就可以按自己需求處理和呈現了。我們看看具體怎麼實現:
//遠程數據地址
var url="http://api.jirengu.com/fm/getSong.php?callback=handler";
//創建script標簽
var script=document.createElement('script');
//把script標簽src設為遠程數據地址
script.setAttribute('src',url);
//把script標簽加到head中
document.getElementsByTagName('head')[0].appendChild(script);
//回調處理函數
function handler(data){
//some code here...
}
註意,要在遠程數據地址尾部加上回調函數名, 伺服器會動態用這個函數名包裹住數據,也就是將數據作為這個函數的參數,這樣返回到本地之後就可以執行相應函數了。
舉個慄子,當我們以callback為getCity請求數據,伺服器返回了的數據是這樣的:
getCity(
{"city":
[
{
"name":"廣州",
"cid":"578"
},
{
"name":"廈門",
"cid":"586"
}
]
}
)
我們的getCity函數是這樣的:
function getCity(data){
console.log(data.city[0].name);
}
這樣我們就log出了廣州,跨域成功!是不是很簡單啊!
好了,跨域就講這麼多。歡迎交流,歡迎指正!
原創文章,轉載請註明出處!