什么是同源策略
同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。
同源意味着协议相同、域名相同、端口相同。
不同源的话,有三种行为受到限制:1、Cookie、LocalStorage 和 IndexDB 无法读取。 2、DOM 无法获得。3、AJAX 请求不能发送。什么是跨域?跨域有几种实现形式
跨域是指从一个域名的网页去请求另一个域名的资源。跨域可以通过JSONP、CORS、降域、PostMessage等方式来实现JSONP 的原理是什么
HTML的<script>
标签是同源策略的例外,可以突破同源策略从其他来源获取数据,因此可以通过<script>
标签引入jsonp文件,然后通过一系列JS操作获取数据CORS是什么
CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。JSONP实现
前端代码:
<!doctype html>
<html>
<head>
<style>
.container {
width: 900px;
maring: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<ul class="news">
<li>第11日前瞻:中国冲击4金,博尔特再战</li>
<li>男双力争会师决赛</li>
<li>女排将死磕巴西</li>
</ul>
<button class="change">换一组</button>
</div>
<script>
$(".change").addEventListener("click", function(){
var script = document.createElement("script")
script.src = "http://127.0.0.1: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>"
}
$(".news").innerHTML = html
}
function $(id){
return document.querySelector(id);
}
</script>
</body>
</html>
后端代码:
//假设域名是localhost, 端口是8080
//更多详细使用方法参考 http://www.expressjs.com.cn/guide/routing.html
/**
* 当 http://localhost:8080/getInfo 的GET请求到来时被下面匹配到进行处理
* 发送JSON格式的响应数据 {name: 'ruoyu'}
*/
app.get("/getNews", function(req,res){
var news = [
"第11日前瞻:中国冲击4金,博尔特再战",
"正直播出战,男双力争会师决赛",
"女排将死磕巴西!郎平安排男陪练模仿对方核心",
"没有中国选手和巨星的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)
}
})
- CORS实现
前端代码:
<!doctype html>
<html>
<head>
<style>
.container {
width: 900px;
maring: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<ul class="news">
<li>第11日前瞻:中国冲击4金,博尔特再战</li>
<li>男双力争会师决赛</li>
<li>女排将死磕巴西</li>
</ul>
<button class="change">换一组</button>
</div>
<script>
$(".change").addEventListener("click", function(){
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 304)){
appendHTML(JSON.parse(xhr.responseText))
}
}
xhr.open("get", "http://b.jrg.com:8080/getNews", true)
xhr.send()
})
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);
}
</script>
</body>
</html>
后端代码:
app.get("/getNews", function(req,res){
var news = [
"第11日前瞻:中国冲击4金,博尔特再战",
"正直播出战,男双力争会师决赛",
"女排将死磕巴西!郎平安排男陪练模仿对方核心",
"没有中国选手和巨星的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)
}
res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080")
res.send(JSON.stringify(data))
})
- 降域实现:
前端a.html代码:
<!doctype html>
<html>
<head>
<style>
.ct {
width: 910px;
margin: auto;
}
.main {
float: left;
width: 450px;
height: 300px;
border: 1px solid #ccc;
}
.main input {
margin: 20px;
width: 200px;
}
iframe {
float: right;
width: 450px;
height: 300px;
border: 1px dashed #ccc;
}
</style>
</head>
<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>
document.querySelector(".main input").addEventListener("input", function(){
window.frames[0].document.querySelector("#input").value = this.value
})
document.domain = "jrg.com"
</script>
</body>
</html>
前端b.html代码:
<!doctype html>
<html>
<head>
<style>
html,body {
margin: 0;
}
input {
margin: 20px;
width: 200px;
}
</style>
</head>
<body>
<input type="text" id="input" placeholder="http://b.jrg.com:8080/b.html">
<script>
document.querySelector("#input").addEventListener("input", function(){
window.parent.document.querySelector("input").value = this.value;
})
document.domain = "jrg.com"
</script>
</body>
</html>
- PostMessage实现:
前端a.html代码:
<!doctype html>
<html>
<head>
<style>
.ct {
width: 910px;
margin: auto;
}
.main {
float: left;
width: 450px;
height: 300px;
border: 1px solid #ccc;
}
.main input {
margin: 20px;
width: 200px;
}
iframe {
float: right;
width: 450px;
height: 300px;
border: 1px dashed #ccc;
}
</style>
</head>
<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>
document.querySelector(".main input").addEventListener("input", function(){
window.frames[0].postMessage(this.value, "http://b.jrg.com:8080")
})
window.addEventListener("message", function(e){
document.querySelector(".main input").value = e.data
})
</script>
</body>
</html>
前端b.html代码:
<!doctype html>
<html>
<head>
<style>
html,body {
margin: 0;
}
input {
margin: 20px;
width: 200px;
}
</style>
</head>
<body>
<input type="text" id="input" placeholder="http://b.jrg.com:8080/b.html">
<script>
document.querySelector("#input").addEventListener("input", function(){
window.parent.postMessage(this.value, "http://a.jrg.com:8080")
})
window.addEventListener("message", function(e){
document.querySelector("#input").value = e.data
})
</script>
</body>
</html>