同源策略
同源策略最早由netscape公司提出 ,是一种浏览器安全策略。
同源:协议、域名、端口号必须完全相同。
跨域:如果违背同源策略就是跨域。
注:ajax默认遵从同源策略。
解决跨域
1.jsonp
jsonp是一个非正式文档,是程序员自己想出来的,只支持GET请求。
jsonp工作:浏览器有些标签本身具有跨域的功能,如:link,iframe,script。jsonp就是利用script来实现跨域功能的。
jsonp的使用:
(1)动态的创建一个script标签
var script =document.createElement("script");
(2) 设置创建script标签的src属性,并设置回调函数
script.src='http://127.0.0.1:9000/checkname'
注:设置回调函数的原因是,script标签请求返回的是javascript语句,故创建一个全局函数,来达到我们处理返回数据的目的。
客户端
function hander(data){
input.style.border='red 1px solid'
p.innerHTML=data.msg
}
服务端
app.all('/checkname',(request,response)=>{
const data={
exit:1,
msg:'用户名已存在'
}
let str=JSON.stringify(data)
response.end(`hander(${str})`)
});
注:response.end使用的使``不是''。
''是强引用,里面的东西统统表示字面意思。
``是先执行里面的语句,然后可以给变量赋值。
(3)将script插入文档中
document.body.appendChild(script)
jquery实现jsonp
<!DOCTYPE html>
<html>
<head>
<title>jquery实现jsonp</title>
<style>
div{
width: 300px;
height: 300px;
border: brown solid 1px;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<button>点击发送jsonp请求</button>
<div></div>
<script>
$('button').eq(0).click(function(){
$.getJSON('http://127.0.0.1:9000/jquery-jsonp?callback=?',function(data){
$('div').html(`名称: ${data.name}<br>
家乡:${data.home}`
)
})
})
</script>
</body>
</html>
const express =require('express');
const app =express();
app.all('/jquery-jsonp',(request,response)=>{
const data={
name:'咸蛋超人',
home:'地球'
}
let str=JSON.stringify(data)
//接收callback 参数
let cb=request.query.callback
//返回结果
response.end(`${cb}(${str})`)
});
app.listen(9000,()=>{
console.log('服务启动了,9000')
});
2. CORS
cors(Cross-Origin Resource Sharing),跨域资源共享。Cors是官方的跨域解决方案。它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get、post请求,跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权访问哪些资源。
cors的工作:
cors是通过设置一个响应头来实现跨域。
cors的使用主要在服务端
response.set('Access-Control-Allow-Origin', '*');
// response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
response.setHeader('Access-Control-Allow-Method','*');
上面图中setHeader函数中第一个参数分别设置允许访问的请求源,请求头,请求方法,第二个参数则具体设置了是具体哪个请求源、请求头、请求方法。通常设为'*',全部请求源,请求头,请求方法都设置为可访问。
3.降域(前提主域名要一致)
http://a.nulia.com 调用http://b.nulia.com
<script>
document.domain = nulia.com;
</script>
//将两个域名都降域,此时就可以相互访问
4.postMessage
假设有两个域名(主域域名不一致),其中iframe页面是允许访问调用,那么就可以用postMessage实现。
原理:
a域名发送请求postMessage,b域名间听到了message事件,就处理并返回数据。
//b域名
<script>
window.frames[0].postMessage(this.value, '*');
//*号表示在任何域下都可以接收message
window.addEventListener('message', function(e){
console.log(e.data);
});
</script>