跨域
2017-10-16 本文已影响0人
Lucien_d70a
JSONP跨域
- 原理:利用html标签script,来引用不同域名下的JS文件,用一个回掉函数,来获取后端数据,从而得到数据进行操作。
- 好处:方便,易理解,兼容性很好。
- 缺点:容易受到XML攻击,接受到恶意修改的数据。
//首先,我们创建一个script标签
$("#content").addEventListener("click",function(){
var script=document.createElement("script")
script.src="你想要获取不同域名的JS?callback=你的回调函数"
document.head.appendChild(script)
document.head.removeChild(script)
})
//创建一个回掉函数,处理你得到的数据
function appendHtml(news){
//你的代码
}
//把回调函数放到参数中
script.src="你想要获取不同域名的JS?callback=appendHtml"
首先我们开启一个mock
Paste_Image.png编写我们的代码,html
<div class="container">
<ul class="news">
<li>123456789</li>
<li>321654987</li>
<li>abckskkjlk</li>
</ul>
<button class="change">123456</button>
</div>
<script type="text/javascript">
//jsonp 跨域方法
$('.change').addEventListener('click', function(){
var script = document.createElement('script');
script.src = 'http://localhost:8080/getNews?callback=appendHtml';
document.head.appendChild(script);
document.head.removeChild(script);
})
function appendHtml(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);
}
</script>
后端
app.get('/getNews', function(req, res){
var news = [
"第11日前瞻:中国冲击4金 博尔特再战200米羽球",
"正直播柴飚/洪炜出战 男双力争会师决赛",
"女排将死磕巴西!郎平安排男陪练模仿对方核心",
"没有中国选手和巨星的110米栏 我们还看吗?",
"中英上演奥运金牌大战",
"博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
"最“出柜”奥运?同性之爱闪耀里约",
"下跪拜谢与洪荒之力一样 都是真情流露"
]
var data = [];
for(var i=0; i<3; i++){
var index = parseInt(Math.random()*news.length);
data.push(news[index]);
news.splice(index, 1);
}
var cb = req.query.callback;
if(cb){
res.send(cb + '('+ JSON.stringify(data) + ')');
}else{
res.send(data);
}
})
在浏览器打开html,输入mock的url
Paste_Image.png点击按钮,这时候我们发现成功了
Paste_Image.png因为我们用的script标签去请求,所以,并不会有浏览器的阻止,只是我们不知道接口的内容罢了,所以,即使我们在本地打开html,也能达到预想的效果(mock不能关闭。模拟的后端要有mock才能运行)
Paste_Image.pngCORS跨域
- 简单理解,就是在后端加上一个请求头,让规定的域名,可以跨域获取到你的数据。
header("Access-Control-Allow-Origin", "你指定可以访问的URL");
代码和上面一样
先修改两个域名
看代码
Paste_Image.png我请求zhihu2.com
但是我用zhihu.com打开html,那就跨域了
这时候在后端中加上上面的请求
Paste_Image.png成功了
Paste_Image.png降域
创建两个html
- a.html
<body>
<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>
//URL: http://a.jrg.com:8080/a.html
document.querySelector('.main input').addEventListener('input', function(){
console.log(this.value);
window.frames[0].document.querySelector('input').value = this.value;
})
</script>
b.html
<body>
<input id="input" type="text" placeholder="http://b.jrg.com:8080/b.html">
<script>
// URL: http://b.jrg.com:8080/b.html
document.querySelector('#input').addEventListener('input', function(){
window.parent.document.querySelector('input').value = this.value;
})
改写域名
Paste_Image.png打开a.html
Paste_Image.pnga输入的时候b不会发生变法,这时候对b和a都降域一下
- document.domain = 'jrg.com';//都降为jrg.com
刷新 输入
Paste_Image.png这时候a输入影响到b了。。