瀏覽器出于安全方面的考慮,只允許與本域下的接口交互峦筒。不同源的客戶端腳本在沒有明確授權(quán)情況下凉夯,不能讀寫對方的資源。為了實(shí)現(xiàn)跨域獲取數(shù)據(jù)有一下幾種方法
1.JSONP
利用script標(biāo)簽可以引入其他域下的js特性财搁,可實(shí)現(xiàn)跨域訪問接口,需要后端的支持躬络;實(shí)現(xiàn)跨域的整個過程:
1.定義數(shù)據(jù)處理函數(shù)_fun
2.創(chuàng)建script標(biāo)簽尖奔,src的地址執(zhí)行后端接口,最后加個參數(shù)callback=_fun
3.服務(wù)端在收到請求后穷当,解析參數(shù)提茁,計(jì)算返還數(shù)據(jù),輸出 fun(data) 字符串馁菜。
4.fun(data)會放到script標(biāo)簽做為js執(zhí)行茴扁。此時會調(diào)用fun函數(shù),將data做為
前端JS
$('.change').addEventListener('click',function() {
var script = document.createElement('script')
script.src = 'http://localhost:8080/getNews?callback=showNews'
//創(chuàng)建script標(biāo)簽汪疮,把callback=showNews作為參數(shù)加進(jìn)去
document.head.appendChild(script)
document.head.removeChild(script)
})
//后端收到請求處理后返回showNews(data)
function showNews(news) {
var html = ''
for (var i = 0; i < news.length; i++) {
html +='<li>' + news[i] + '</li>'
}
console.log(html)
$('.news').innerHTML = html
}
function $(id) {
return document.querySelector(id)
}
服務(wù)端要做個判斷
var cb = req.query.callback;
if (cb) {
res.send(cb + '('+ JSON.stringify(data) +')')
}else {
res.send(data)
}
2.CORS方法
CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing)峭火,發(fā)出XHLHttpRequest請求毁习,實(shí)現(xiàn)AJAX跨域使用。實(shí)現(xiàn)方式:
當(dāng)使用XHLHttpRequest發(fā)送請求時卖丸,該請求不符合同源策略纺且,這是瀏覽器會給該請求添加一個請求頭:Origin,后臺進(jìn)行處理,確定接收請求會在結(jié)果中加一個響應(yīng)頭:Access-Control-Allow-Origin; 瀏覽器判斷該相應(yīng)頭中是否包含 Origin 的值稍浆,如果有瀏覽器會處理響應(yīng)载碌,就可以拿到響應(yīng)數(shù)據(jù),如果不包含Origin的值粹湃,就無法拿到數(shù)據(jù)恐仑。cors的表象和同源的ajax請求沒啥區(qū)別泉坐,代碼一樣为鳄。
當(dāng)前JS代碼和ajax一樣
var xhr = new XMLHttpRequest()
xhr.onreadystate = function() {
if (state === 4) {
if (status === 200 || status === 304) {
appendChildHtml(JSON.parse(xhr.responsetext))
}
}
xhr.open('get','http://other.com/getNews',true)
xhr.send()
}
function appendChildHtml(news) {
}
其他域處理數(shù)據(jù)
router.get('/getNews',function(req,res){
var news = []
var data = []
for (var i = 0; i < 3; i++) {
var index = parseInt(Math.random()*news.length)
data.push(news[index])
news.splice(index,1)
}
res.header("Access-Control-Allow-Origin","http://example.com")
//允許指定域訪問
res.header("Access-Control-Allow-Origin","*")
//允許任意域訪問
res.send(data)
})
具體可參考
<a >HTTP訪問控制(CORS)</a>
3.降域
操作iframe之類的訪問其他域,可以用降域方法
一下a.html和b.html都降域處理后可以互相訪問了
a.html
<div>
<div class="main">
<input type="text" placeholder="http://b.jrg.com:8080/a.html">
</div>
<iframe src="http://b.jrg.com:8080/b.html" frameborder="0" ></iframe>
</div>
<script>
//URL: http://a.jrg.com:8080/a.html
//xxx
document.domain = "jrg.com" //降域處理
b.html
<div>
<input id="input" type="text" placeholder="http://b.jrg.com:8080/b.html">
<script>
// URL: http://b.jrg.com:8080/b.html
//xxx
document.domain = 'jrg.com'; //降域處理
4.postMessage
window.postMessage() 方法可以安全地實(shí)現(xiàn)跨源通信腕让。window.postMessage() 方法被調(diào)用時,會向目標(biāo)窗口發(fā)送信息孤钦,要接收其他窗口發(fā)來的消息時,要為message添加監(jiān)聽事件纯丸。
下面a.html和b.html可以互相訪問
a.html
<div class="ct">
<h1>使用postMessage實(shí)現(xiàn)跨域</h1>
<div class="main">
<input type="text" placeholder="http://a.jrg.com:8080/a.html">
</div>
<iframe src="http://localhost:8080/b.html" frameborder="0" ></iframe>
</div>
<script>
//URL: http://a.jrg.com:8080/a.html
$('.main input').addEventListener('input', function(){
console.log(this.value);
window.frames[0].postMessage(this.value,'*');
})
window.addEventListener('message',function(e) {
$('.main input').value = e.data
console.log(e.data);
});
function $(id){
return document.querySelector(id);
}
b.html
<input id="input" type="text" placeholder="http://b.jrg.com:8080/b.html">
<script>
// URL: http://b.jrg.com:8080/b.html
$('#input').addEventListener('input', function(){
window.parent.postMessage(this.value, '*');
})
window.addEventListener('message',function(e) {
$('#input').value = e.data
console.log(e.data);
});
function $(id){
return document.querySelector(id);
}
</script>