关于同源策略及跨域的解决方案
同源策略
同源策略:协议、域名、端口号全相同
URL1 | URL2 | 是否跨域/原因 |
---|---|---|
http://www.baidu.com/a.js | http://www.baidu.com/b.js | 否 / 协议,域名,端口号都相同 |
http😕/www.baidu.com/a.js | https😕/www.baidu.com/b.js | 是 / 协议不同 |
http://www.baidu.com/a.js | http://www.taobao.com/b.js | 是 / 主域名不同 |
http://www.baidu.com/a.js | http://map.baidu.com/b.js | 是 / 子域名不同 |
http://www.baidu.com/a.js | http://www.baidu.com**:90**/b.js | 是 / 端口号不同 |
只要协议、域名、端口号三者有一个不同,都会形成跨域
跨域的解决方案
jsonp
- script标签不受跨域影响
- 客户端定义一个函数作为回调函数
- 客户端通过script标签引入服务端文件,且将回调函数名传入
- 服务端接收到回调函数名,将目标数据作为参数传入回调函数并执行
客户端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jsonp</title>
</head>
<body>
<script>
//定义一个函数,接收服务端传过来的值
function show(data){
alert(data)
}
</script>
<!-- 该script标签指向服务端地址,callback参数的值要和上面定义的函数名相同 -->
<script src="http://localhost:90?callback=show"></script>
</body>
</html>
服务端:
const http = require('http');
const url = require('url')
//创建一个服务器
http.createServer(function (req, res) {
//接收客户端传来的callback参数
let callback = url.parse(req.url, true).query.callback
res.writeHead(200, { 'Content-type': 'text/plain;charset=UTF-8' })
//将callback作为函数,传入想要传回客户端的值
res.write(`${callback}('你好')`)
res.end()
}).listen(90)
CORS
CORS(跨域资源共享)是一种机制,该机制使用附加的HTTP头来告诉浏览器,准许运行在一个源上的Web应用访问位于另一不同源选定的资源
简单的直接在服务器端HTTP头信息中添加“Access-Control-Allow-Origin”解决
如node服务器:
var http = require('http');
var data = {
name: "Bob",
age: 12
}
http.createServer(function (req, res) {
//头信息中添加"Access-Control-Allow-Origin"字段并设置为同意跨域任意请求
res.setHeader("Access-Control-Allow-Origin", "*")
res.writeHead(200, { 'Content-Type': 'text/plain;charset=UTF-8' })
res.end(JSON.stringify(data))
}).listen(90)
详细一点的可查看阮一峰的网络日志:跨域资源共享 CORS 详解
WebSocket
基于ws模块的简易WebSocket服务器
客户端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket学习</title>
</head>
<body>
<script>
var ws = new WebSocket("ws://localhost:91");
ws.onopen = function () {
ws.send("客户端模拟请求数据");
console.log("数据发送中...")
}
ws.onmessage = function (res) {
console.log("返回数据为:"+res.data)
}
ws.onclose = function () {
console.log("连接已关闭")
}
</script>
</body>
</html>
服务器端
var ws = require('ws').Server,
wss = new ws({ port: 91 });
wss.on('connection', function (ws) {
console.log('已连接');
ws.on('message', function (message) {
//打印客户端监听的消息
console.log("客户端请求数据为:"+message);
ws.send("服务器端模拟返回数据",function(err){
if(err){
console.log("出错了")
}
})
});
});