一.前后端如何通信:
1.ajax
2.WebSocket
3.CORS
二.跨域的几种方式:
1.JSONP(只能使用get请求)
2.CORS(现在项目里主要用)
3.Hash:就是url中#号后面的东西,hash改变,页面是不刷新的;search是url中?号后面的东西,search的改变,页面是刷新的;
4.postMessage(h5)(有域的限制)
5.WebSocket(不受同源策略限制)
6.基于http proxy实现跨域请求
1. JSONP的原理:
原理:利用<script>标签的src属性,给它传入地址,<script>就能把对应的内容请求回来。把当前页面的某个函数作为参数,通过问号传参的方式传给url(如’?callback=fn’)。对方服务器接收到你的请求后,会进行特殊的处理,把你传进来的函数和它需要给你的数据拼接成一个字符串(如’fn({‘code’:0})’)。最后,服务器会把准备好的数据通过HTTP协议返回给客户端。客户端发现其实就是让fn执行,而且服务器还给fn传递了一堆数据,由fn的参数接收,这些数据就是我们想要的。可以通过控制台的Network的Response选项里查看(如fn({‘code’:0}))。
如:
<script>
function fn(data){
console.log(data);
}
</script>
<script src='http://matchweb.sports.qq.com/kbs/calendar?callback=fn'> <script>//src只要写了网址后,轮到它执行就是发送一个网络请求;
2.CORS的原理:
支持跨域通信的ajax,浏览器在识别你用ajax发送一个跨域请求的时候,它自动会在你的http头中加一个origin,来允许跨域通信,服务器会返回一个HTTP响应,如果浏览器发现这个响应的头信息没有包含Access-Control-Allow-Origin字段,就知道出错了,会抛出一个错误。
服务器端设置:Access-Control-Allow-Origin:’允许访问的网址’,或者服务器端设置:
npm i cors
app.use(require(‘cors’)())
前端通过fetch发送ajax:
fetch(‘网址’,{
method:’get’
}).then(res=>{
res.json()
}).catch(err=>{
});
3.hash的原理:
利用hash向跨域网站发送信息:
如:在当前页面A,通过iframe/frame嵌入了跨域的页面B,现在页面A,向页面B发送信息:
A页面中:
var B=document.getElementByTagName(‘iframe’);
B.src= B.src+’#’+’data’;
B页面中:
window.onhashchange=function(){
var data=window.location.hash;(hash是包含#的内容)
};
4.postMessage的原理:
窗口A向跨域的窗口B(通过iframe嵌入)发送信息:
在窗口A中,先获取iframe的window引用:
let iframe= document.getElementById(‘myIframe’).contentWindow;
iframe.postMessage(‘data’,’http://B.com’);
在窗口B中监听:
window.addEventListener(‘message’,function(event){
console.log(event.origin);——>A的网址
console.log(event.source);
console.log(event.data);——>data
},false)
5.Web Socket的原理:
var ws=new WebSocket('wss://echo.websocket.org'):
ws.onopen=function (){
ws.send('发送给对方的信息')
};
ws.onmessage=function(e){
console.log(e.data)
};
ws.onclose=fucntion(){
}
(WebSocket是一种通信协议,在应用层,跟http协议在同一层)
HTTP协议有一个缺陷:通信只能由客户端发起;
WebSocket最大的特点是:服务器可以主动向客户端推送信息,客户端也可以主动向客户端推送信息,是真正的双向对话。
http协议开头是:http:
WebSocket协议开头是:ws:
WebSocket连接的特点:
1.服务器可以主动向客户端推送信息,客户端也可以主动向客户端推送信息,是真正的双向对话。
2.建立在TCP协议之上,服务器端实现比较容易
3.与HTTP有良好的兼容性:默认端口也是80和443,握手阶段采用http协议
4.数据格式比较轻量,性能开销小,通信高效
5.可以发送文本,也可以发送二进制数据
6.没有同源限制,客户端可以与任意服务器端通信
7.协议标识:ws,加密的 协议标识:wss,服务器网站:URL
6.基于http proxy实现跨域请求:
1.在页面里:axios.get(‘/xx’);——>所有当前网址发请求
2.在package.json里,添加一个’proxy’属性:
”proxy”:”跨域的网址”——>页面里所有当前网址发请求,都代理到proxy的网址里;
3.原理是:开发时,webpack里的devServer帮我们做了代理,但上线的时候只有打包后的结果,是没有webpack的,所以上线后需要使用nginx的反向代理;