跨域问题
-
浏览器的同源策略限制了前端跨域请求数据
-
同源策略:协议、域名、端口号三者必须相同,有一个不相同即为跨域
跨域解决方案
- cors
- 服务端代理请求
- jsonp res.send(mycb+'({"name":"zs","age":13})')
- 前端本地服务器代理请求
const express = require('express')
const app = express()
// 1.使用cors中间件跨域
const cors = require('cors')
app.use(cors())
// 2.设置头部信息允许跨域
app.all("*",function(req,res,next){
//设置允许跨域的域名,*代表允许任意域名访问
res.header("Access-Control-Allow-Origin","*")
//允许的header类型
res.header("Access-Control-Allow-Headers","content-type")
//允许的跨域请求方式
res.header("Access-Control-Allow-Methods","POST,GET")
next()
})
// 3.服务端代理跨域请求
// 可以使用http模块来发起请求,工作中可以使用封装好的request模块
const https = require('https')
app.get('/hehe',(req,res)=>{
let url = 'https://m.you.163.com/xhr/index.json?__timestamp=1600266481664'
https.get(url,(res)=>{
let resData = ''
// 只要接收到数据就会触发data事件
res.on('data',(chunk)=>{
// chunk是每次接收到的数据片段
resData += chunk.toString('utf8')
})
// 数据流传输完毕触发end事件
res.on('end',()=>{
res.send(resData)
})
})
})
app.listen(3003,()=>{
console.log('----------- server start ----------');
})
socket
-
socket应用场景
- 会员到期提醒
- 站内信
- 中奖信息
- 数据可视化
- 需要实时更新的场景 等等......
-
轮询,如 1s请求一次 ---- 短连接(ajax)
-
服务端主动向前端推送消息 ---- 长连接(socket)
-
实现长连接
- socket.io 稍微麻烦,兼容性较好
- websocket 使用方便,h5新增,低版本浏览器兼容性差
// 服务端代码
安装:npm install ws
let WebSocket = require('ws')
// 创建WebSocket对象,启动WebSocket服务
let ws = new WebSocket.Server({port: 8181},()=>{
console.log('------- socket start -------')
})
let clients = [] // 缓存所有客户端连接
// 监听connection事件,有客户端连接时触发
ws.on('connection',(client)=>{
// client 客户端对象
clients.push(client)
// 监听message事件,客户端发消息过来时触发
client.on('message',(msg)=>{
// console.log('来自客户端的数据:'+msg)
clients.forEach((item,index)=>{
// 给所有连接客户端发消息
item.send(msg)
})
})
// 监听close事件,客户端断开连接时触发
client.on('close',()=>{
console.log('客户端断开连接')
})
// 给客户端发送消息
client.send('欢迎光临~')
})
// 前端代码
<input type="text" id="ipt">
<button id="btn">发送消息</button>
<script>
let ws = new WebSocket('ws://localhost:8181')
// 监听open事件,连接上WebSocket服务时触发
ws.onopen = ()=>{
console.log('服务已连接')
}
// 监听message事件,服务端发送消息过来时触发
ws.onmessage = (msg)=>{
console.log('来自服务端的消息:'+msg.data)
}
// 监听close事件,服务端关闭时触发
ws.onclose = ()=>{
console.log('服务器关闭')
}
btn.onclick = function (){
// 给服务端发消息
ws.send(ipt.value)
}
</script>
- 安装:npm install socket.io
// 后端代码
const express = require('express')
const app = express()
// 将socket服务和express结合(socket服务和node服务都可以使用)
const server = require('http').Server(app)
const ws = require('socket.io')(server)
// 监听connection事件,有客户端连接时触发
ws.on('connection',(client)=>{
// 触发前端的hehe事件并发送消息
client.emit('hehe','你好前端~')
// 监听haha事件并接收消息
client.on('haha',(msg)=>{
console.log(msg)
})
})
// 监听8181端口,启动服务
server.listen(8181,()=>{
console.log('--------- server start ----------')
})
// 前端代码
<script src="./socket.io.js"></script>
<script>
// 连接服务器
let socket = io.connect('http://localhost:8181')
// 监听hehe事件并接收消息
socket.on('hehe',(msg)=>{
console.log(msg)
})
// 触发后端的haha事件并发送消息
socket.emit('haha','你好后端~')
</script>
Q.E.D.