简单来说,如果以下三项:同一协议、同一域名、同一端口,有一点不满足,服务器就会报错。
跨域问题可以说在前端方面不可避免,但同源策略毕竟在保护网络信息安全方面起到很大的作用。试想如果没有同源策略,别的网页可以轻松窃取你的cookie,而假如你的cookie中存有你的个人信息…太可怕了,不过话说回来同源策略带来的跨域问题也很头疼,幸好现在已经有多种方式能够解决
jsonp原理
浏览器只对XHR(XMLHttpRequest)请求有同源请求限制,而对script标签src属性、link标签ref属性和img标签src属性没有这这种限制,利用这个“漏洞”就可以很好的解决跨域请求。JSONP就是利用了script标签无同源限制的特点来实现的,当向第三方站点请求时,我们可以将此请求放在
<script src="http://www.b.com/request?para1=1"></script>
JSONP的优缺点
优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
JSONP前端请求实现
script标签设置src属性为请求的地址,并判断回调函数作为参数
服务端构建JS脚本,传递返回给客户端的数据
客户端在回调函数中解析服务器生成的数据
代码写完后看自己页面的路径地址,有没有实现跨域,第三个也一样
index.html页面
<body>
<iframe src="http://127.0.0.1:8080/message.html" id="frm"></iframe>
<input type="button" value="ok" onclick="run()">
<!-- 绑定点击事件,模拟传输数据 -->
<script>
function run(){
let frm =document.getElementById("frm");
//contentWindow.postMessage,这个属性可以传递数据
frm.contentWindow.postMessage({name:"张三李四"},"http://127.0.0.1:8080")//name:"张三李四",第一个参是数据,第二个是跨域的地址
}
</script>
</body>
message.html页面
<body>
<script>
//接收index.html的数据
window.addEventListener("message",function(e){
console.log(e.data);
})
</script>
</body>
server.js页面
let express= require("express");
let app = express();
// 解析静态资源文件的;
app.use(express.static(__dirname));
app.listen(8080,function(){//8080启动的端口号
console.log("启动成功");
})
index.html页面
<body>
<script src="../node_modules/axios/dist/axios.min.js"></script>
<script>
// 从5501向8080发送请求,被阻断了,跨域;
axios.get("http://127.0.0.1:8080/getData").then(function(data){
console.log(data.data);
})
</script>
</body>
server.js页面
let express = require("express");
let app = express();
// 利用cros解决跨域
app.use(function(req,res,next){
// http://127.0.0.1:5501:设置允许的请求地址, * : 代表所有的路径
// Origin 字段,表示本次请求来自哪个源(协议 + 域名 + 端口),服务端会获取到这个值,然后判断是否同意这次请求并返回。
// res.header 设置响应头
res.header("Access-Control-Allow-Origin","http://127.0.0.1:5501");
// 设置允许的跨域请求方式
res.header("Access-Control-Allow-Methods","GET,POST")
next();
});
// 路由
app.get("/getData",function(req,res){///getData这个路由在a.html用到了
res.send("你很帅");
});
//想启动项目首先要下载express,有这个才能运行server
//在安装一个生产依赖axios
app.listen(8080);//listen,监听的端口
module.exports = {
lintOnSave: false,
publicPath:"./",//./是公共路径,基础路径,跟src是同级的在这可以实现跨域devServer
devServer:{
// proxy代理;实现跨域;前端项目部署在本地的8080端口,向知乎域名请求数据,是跨域,需要配置proxy;在前端看似访问8080,实际在node环境下会将访问的地址代理到知乎的服务器上;
proxy:'https://www.zhihu.com/api'
}
}
// 当期这个文件是vue/cli的生成的项目的配置文件;因为这个项目没有webpack.config.js文件,你所想要的所有的配置都在这个文件中配置就可以了
module.exports = {
publicPath: './',//这个值也可以被设置为空字符串 ('') 或是相对路径 ('./'),这样所有的资源都会被链接为相对路径,这样打出来的包可以被部署在任意路径,
lintOnSave:false, // 如果是false,那么eslint代码校验就不在抛出警告
devServer:{ // 配置代理
proxy: 'http://localhost:3000' // 后台项目的跑的端口号
},
// 会将这个对象和内置的配置文件进行合并
// configureWebpack:{
// modules:{
// rules:[
// {
// test:/\.(png|jpg|gif|)$/,
// use:['url-loader']
// }
// ]
// }
// }
}
具体可以参照VUE CLI官网:https://cli.vuejs.org/zh/config/#devserver-proxy
有空会给每一个加上详细讲解