JSONP
JSONP(JSON with Padding)是資料格式JSON的一種“使用模式”,可以讓網(wǎng)頁從別的網(wǎng)域要資料蟋软。
由于同源策略踢代,一般來說位于server1.example.com的網(wǎng)頁無法與不是 server1.example.com的伺服器溝通钦扭,而HTML
的 <script>
元素是一個例外。利用 <script>
元素的這個開放策略君纫,網(wǎng)頁可以得到從其他來源動態(tài)產(chǎn)生的JSON資料驯遇,而這種使用模式就是所謂的 JSONP。用JSONP抓到的資料并不是JSON蓄髓,而是任意的JavaScript叉庐,用 JavaScript直譯器執(zhí)行而不是用JSON解析器解析。
index.html
<div class="container">
<ul class="news">
<li>習(xí)近平:堅(jiān)持中國特色社會主義社會治理之路</li>
<li>在組織生活會上普通黨員習(xí)近平說了啥 喜迎十九大</li>
<li>重訪習(xí)近平十八大以來國內(nèi)考察地 《輝煌中國》</li>
</ul>
<button id="btn">換一組</button>
</div>
<script>
$('#btn').addEventListener('click',function(){
// 為按鈕添加點(diǎn)擊事件
var script = document.createElement('script');
// 創(chuàng)建一個script標(biāo)簽
script.src='http://localhost:8080/getNews?callback=appendHtml'
// 為script標(biāo)簽設(shè)置地址
document.head.appendChild(script)
//在head里添加script標(biāo)簽
document.head.removeChild(script)
//移除head里的script標(biāo)簽
})
// 處理返回的數(shù)據(jù)appendHtml(["xxx","xxx","xxx"])
function appendHtml(news){
var html = ''
for(var i = 0;i<news.length;i++){
html += '<li>'+news[i]+'</li>'
// 把后臺傳遞過來的數(shù)據(jù)会喝,拆開加在<li></li>內(nèi)
}
$('.news').innerHTML = html;
//把<ul class="news"></ul>中的內(nèi)容替換為處理好的數(shù)據(jù)
}
function $(id){
return document.querySelector(id)
}
</script>
router.js
app.get('/getNews',function(req,res){
var news = [
"<strong>習(xí)近平:堅(jiān)持中國特色社會主義社會治理之路</strong>",
"在組織生活會上普通黨員習(xí)近平說了啥 喜迎十九大",
"重訪習(xí)近平十八大以來國內(nèi)考察地 《輝煌中國》",
"李克強(qiáng)同李顯龍會談 張德江主持會議 劉云山訪越",
"大國網(wǎng)信安全護(hù)航 2017年國家網(wǎng)絡(luò)安全宣傳周",
"俠客島:李顯龍時隔近4年為何“突然”訪華?",
"<strong>墨西哥地震致一學(xué)校教學(xué)樓倒塌 約百名學(xué)生失蹤<stong>",
"深圳一小學(xué)65名學(xué)生現(xiàn)身體不適 官方:已停用操場",
"媒體:想知道中國海軍有多強(qiáng)陡叠?僅需一個細(xì)節(jié)",
"特朗普演講:朝鮮半島無核化是唯一可接受的未來",
"外媒:中國高鐵網(wǎng)絡(luò)預(yù)示著“高流動性時代”的到來",
"外國專家:北斗已超越歐盟、俄羅斯衛(wèi)星導(dǎo)航系統(tǒng)"
]
// 內(nèi)容庫
var data = []
for(var i = 0;i<3;i++){
var index = parseInt(Math.random()*news.length)
// parseInt取整肢执,抽取內(nèi)容庫的隨機(jī)數(shù)字
data.push(news[index])
// 把這條隨機(jī)的新聞枉阵,傳給data數(shù)組
news.splice(index,1)
//移除這條新聞,避免重復(fù)
}
var cb = req.query.callback;
// 獲取傳遞的callback值
if(cb){
res.send(cb+'('+JSON.stringify(data)+')');
//JSON.stringify 將JavaScript的值轉(zhuǎn)化為JSON
//如果有callback的值预茄,返回callback值+(["xxx","xxx","xxx"])
}else{
res.send(data);
//如果沒有兴溜,返回["xxx","xxx","xxx"]
}
})
CORS
CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing)侦厚,是一種ajax 跨域請求資源的方式,支持現(xiàn)代瀏覽器拙徽,IE支持10以上刨沦。 實(shí)現(xiàn)方式很簡單,當(dāng)你使用 XMLHttpRequest 發(fā)送請求時膘怕,瀏覽器發(fā)現(xiàn)該請求不符合同源策略想诅,會給該請求加一個請求頭:Origin,后臺進(jìn)行一系列處理岛心,如果確定接受請求則在返回結(jié)果中加入一個響應(yīng)頭:Access-Control-Allow-Origin; 瀏覽器判斷該相應(yīng)頭中是否包含 Origin 的值来破,如果有則瀏覽器會處理響應(yīng),我們就可以拿到響應(yīng)數(shù)據(jù)忘古,如果不包含瀏覽器直接駁回徘禁,這時我們無法拿到響應(yīng)數(shù)據(jù)。所以 CORS 的表象是讓你覺得它與同源的 ajax 請求沒啥區(qū)別存皂,代碼完全一樣晌坤。
例:http://a.jrg.com:8080網(wǎng)站向http://b.jrg.com:8080/getNews獲取數(shù)據(jù)
html
<div class="container">
<ul class="news">
<li>習(xí)近平:堅(jiān)持中國特色社會主義社會治理之路</li>
<li>在組織生活會上普通黨員習(xí)近平說了啥 喜迎十九大</li>
<li>重訪習(xí)近平十八大以來國內(nèi)考察地 《輝煌中國》</li>
</ul>
<button id="btn">換一組</button>
</div>
script
$('#btn').addEventListener('click',function(){
var xhr = new XMLHttpRequest();
xhr.open('get','http://b.jrg.com:8080/getNews',true)
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState===4 && xhr.status===200){
appendHtml( JSON.parse(xhr.responseText) )
}
}
})
function appendHtml(news){
var html = '';
for(var i = 0;i<news.length;i++){
html += '<li>'+news[i]+'</li>'
}
$('.news').innerHTML = html;
}
function $(id){
return document.querySelector(id);
}
router.js
app.get('/getNews',function(req,res){
var news = [
"<strong>習(xí)近平:堅(jiān)持中國特色社會主義社會治理之路</strong>",
"在組織生活會上普通黨員習(xí)近平說了啥 喜迎十九大",
"重訪習(xí)近平十八大以來國內(nèi)考察地 《輝煌中國》",
"李克強(qiáng)同李顯龍會談 張德江主持會議 劉云山訪越",
"大國網(wǎng)信安全護(hù)航 2017年國家網(wǎng)絡(luò)安全宣傳周",
"俠客島:李顯龍時隔近4年為何“突然”訪華?",
"<strong>墨西哥地震致一學(xué)校教學(xué)樓倒塌 約百名學(xué)生失蹤<stong>",
"深圳一小學(xué)65名學(xué)生現(xiàn)身體不適 官方:已停用操場",
"媒體:想知道中國海軍有多強(qiáng)逢艘?僅需一個細(xì)節(jié)",
"特朗普演講:朝鮮半島無核化是唯一可接受的未來",
"外媒:中國高鐵網(wǎng)絡(luò)預(yù)示著“高流動性時代”的到來",
"外國專家:北斗已超越歐盟旦袋、俄羅斯衛(wèi)星導(dǎo)航系統(tǒng)"
]
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://a.jrg.com:8080")
// 返回來自http://a.jrg.com:8080的數(shù)據(jù)請求
//res.header("Access-Control-Allow-Origin","*")
//返回所有網(wǎng)站的數(shù)據(jù)請求
res.send(data);
})
降域
a.html
<div class="ct">
<h1>降域</h1>
<div class="main">
<input type="text" placeholder="http://a.jrg.com:8080/a.html">
</div>
<iframe src="http://b.jrg.com:8080/b.html" frameborder="0"></iframe>
</div>
<script>
document.querySelector('.main input').addEventListener('input',function(){
//給當(dāng)前窗口的input綁定一個輸入事件
window.frames[0].document.querySelector('input').value = this.value;
//把當(dāng)前輸入input的值,賦給第一個frames的input的值
})
document.domain = "jrg.com"
//降域
</script>
b.html
<input id="input" type="text" placeholder="http://b.jrg.com:8080/b.html">
<script>
document.querySelector('#input').addEventListener('input',function(){
//獲取頁面上的input它改,添加輸入事件
window.parent.document.querySelector('input').value = this.value;
//把當(dāng)前frame的input的值疤孕,賦給父級頁面的input的值
})
document.domain = "jrg.com"
//降域
</script>
postMessage
postMessage對于不同的域下,可以向他發(fā)送一個數(shù)據(jù)央拖,如果對方接受認(rèn)可這個數(shù)據(jù)祭阀,那就可以去使用,如果對象沒有去監(jiān)控這個數(shù)據(jù)鲜戒,就沒有任何作用专控。
a.html
<div class="ct">
<h1>postMessage</h1>
<div class="main">
<input type="text" placeholder="http://a.jrg.com:8080/a.html">
<iframe src="http://b.jrg.com:8080/b.html" frameborder="0"></iframe>
</div>
<script>
$('.main input').addEventListener('input',function(){
window.frames[0].postMessage(this.value,"*");
})
window.addEventListener('message',function(e){
$('.main input').value = e.data
})
function $(id){
return document.querySelector(id)
}
</script>
b.html
<input id="input" type="text" placeholder="http://b.jrg.com:8080/b.html">
<script>
$('#input').addEventListener('input',function(){
window.parent.postMessage(this.value,"*")
})
window.addEventListener('message',function(e){
$('#input').value = e.data
})
function $(id){
return document.querySelector(id)
}
</script>
其他跨域方式
用到的函數(shù)
- JSON.stringify()方法將一個 JavaScript 值轉(zhuǎn)換為一個 JSON 字符串,如果指定了一個 replacer 函數(shù)遏餐,則可以替換值伦腐,或者如果指定了一個 replacer 數(shù)組,可選地僅包括指定的屬性失都。
- parseInt() 函數(shù)可解析一個字符串柏蘑,并返回一個整數(shù)。
- JSON.parse()方法用于將一個 JSON 字符串轉(zhuǎn)換為對象粹庞。