同源策略
- 浏览器出于安全考虑,只允许相同域之间的接口相互传输数据,不同源客户端脚本在没有授权允许的情况下不能访问对方资源
- 同源即:协议相同,域名相同,端口相同。(有一个不同即为跨域)
实现跨域的方法
1 jsonp
- HTML中的script标签具有访问其他域下js的能力,可以实现跨域访问,但也需要服务器端支持
- 具体实现方式:1 创建数据处理函数(function)2 在script标签中的请求路径后添加callback=function(url?callback=function)3服务器在接收到请求后返回 function(data)4 浏览器接受到数据后会执行script标签中的js,调用function,就达到处理数据的目的
- 后端实现代码(基于express框架)
var express = require('express');
var app = express();
app.get('/a',function(req,res){
var callback = req.query.callback;
if(callback){
res.send(callback+'("data")')
}else{
res.send("abc")
}
})
app.listen(3000)
console.log('success')
2 cores
- ORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 实现方式,当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以 CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。
- 后端代码实现
var express = require('express');
var app = express();
app.get('/a',function(req,res){
var callback = req.query.callback;
if(callback){
res.send(callback+'(data)')
}else{
res.header("Access-Control-Allow-Origin","*")
res.send("abc")
}
})
app.listen(3000)
console.log('success')
3 降域
a.html
<div class="ct">
<h1>使用降域实现跨域</h1>
<div class="main">
<input type="text" placeholder="http://a.ji.com:8080/a.html">
</div>
<iframe src="http://b.ji.com:8080/b.html" frameborder="0" ></iframe>
</div>
<script>
document.querySelector('.main input').addEventListener('input', function(){
window.frames[0].document.querySelector('input').value = this.value;
})
document.domain = "ji.com"
</script>
b.html
<body>
<input id="input" type="text" placeholder="http://b.ji.com:8080/b.html">
<script>
document.querySelector('#input').addEventListener('input', function(){
window.parent.document.querySelector('input').value = this.value;
})
document.domain = 'ji.com';
</script>
</body>
4 postMessage
a.html
<body>
<div class="ct">
<h1>使用postMessage实现跨域</h1>
<div class="main">
<input type="text" placeholder="http://a.ji.com:8080/a.html">
</div>
<iframe src="http://b.ji.com:8080/b.html" frameborder="0" ></iframe>
</div>
<script>
$('.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);
}
</script>
</body>
b.html
<body>
<input id="input" type="text" placeholder="http://b.ji.com:8080/b.html">
<script>
$('#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>
</body>
- 降域与postMessage主要是实现父子页面之间的通信