什么是跨域
首先来了解同源和非同源:
协议、域名、端口号都相同的为同源;任意一个不同的则为非同源。
如:1.http://127.0.0.1:3000
和http://127.0.0.1:8080
这两个端口号不同,为非同源
2.http://127.0.0.1:3000
和 http://127.0.0.1:3000/list
这两个为同源
3.http://baidu.com
和http://127.0.0.1:3000
这两为非同源
同源策略是浏览器的一个安全限制,从一个源加载的文档或者脚本默认不能访问另一个源的资源。
而跨域就是去请求非同源端的数据。
方法一:JSONP
原理
这主要是利用一些没有同源限定的标签(如:script
、img
、link
、iframe
)来请求其他地方的数据。
方法
用<script src="xxxxx?callback=func"></script>
的形式来请求一些外部文件,如图:
$.ajax({
url:'http://127.0.0.1:8080/list',
method:'get',
dataType:'jsonp',//用JSONP形式,浏览器会自动创建script请求,并自动生成全局函数加在请求地址后面,全局函数执行时,会调用success方法
success:res =>{
console.log(res)
}
})
//服务端
app.get('/list',(req,res)=>{
let {callback = Function.prototype}=req.query;
let data = {
code:0,
message:"hi,i am from 8080"
};
res.send(`${callback}(${JSON.stringify(data)})`)
})
问题
只支持get
请求方式,且存在安全隐患(例如服务器返回并不安全的代码,浏览器收到后照样会执行)
方法二:CORS跨域资源共享
方法
//这里利用了一个简单插件发送请求(这是为了简化请求和结果而已)
axios.get('http:://127.0.0.1:8080/list')
.then(result =>{
console.log(result);
})
app.use((req,res,next)=>{
const{
ALLOW_ORIGIN:'http://127.0.0.1:3000', //设置一个允许访问的源
ALLOW_METHODS:'PUT,POST,GET,DELETE,OPTIONS,HEAD',//设置允许的方法
HEADERS:'Content-type,Content-length,Authorization,Accept',//设置允许的请求头
CREDENTIALS:true //是否允许携带参数
}
res.header("Access-Control-Allow-Origin",ALLOW_ORIGIN);
res.header("Access-Control-Allow-Credentials",CREDENTIALS);
res.header("Access-Control-Allow-Headers",HEADERS);
res.header("Access-Control-Allow-Methods",ALLOW_METHODS);
if(req.method==='OPTIONS'){//在发送跨域请求之前,先发一个试探性请求,检测是否能建立连接,然后再发送真实请求。
res.send('OK');
return
}
客户端的配置:
问题
只有支持单源或所有源(*)两种,且支持所有源时不能携带cookie
方法三:proxy代理
方法
在webpack
的dev-Server
中配置即可
decServer:{
port:3000, //启动的端口
progress:true,
//...
proxy:{
'/':{
target:'http://127.0.0.1:8080', //当收到'/'请求时,全部转为去8080端口范文
changeOrigin:true
}
}
}