# 跨域及解决方案
# 什么是同源策略
同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
# 同源策略限制内容
- Cookie、LocalStorage、IndexedDB 等存储性内容
- DOM 节点
- AJAX 请求发送后,结果被浏览器拦截了
但是有三个标签是允许跨域加载资源:
<img src=XXX>
<link href=XXX>
<script src=XXX>
# 跨域解决方案
// 1.原生 node 实现
app.use(async (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', ctx.headers.origin)
ctx.set('Access-Control-Allow-Credentials', true)
ctx.set('Access-Control-Request-Method', 'PUT,POST,GET,DELETE,OPTIONS')
ctx.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, cc')
if (ctx.method === 'OPTIONS') {
ctx.status = 204
return
}
await next()
})
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
// 2.使用第三方中间件
/**
CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。
浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。
**/
const cors = require('koa-cors')
app.use(cors())
// 3.使用 node 正向代理,比如
webpackConfig.devServer.proxy
// 4.使用 nginx 反向代理
// 实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。
// 5.websocket
// WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据
// 6.iframe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 5.jsonp
// 利用 script 标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。
// JSONP请求一定需要对方的服务器做支持才可以。
<script>
window.jsonpCallback = function(res) {
console.log(res)
}
</script>
<script
src="http://localhost:8080/api/jsonp?msg=hello&cb=jsonpCallback"
type="text/javascript"
></script>
<script>
jsonpCallback({ a: 1 })
</script>
// 6.window.postMessage // index.html
// postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
<iframe src="http://localhost:8080" frameborder="0" id="iframe" onload="load()"></iframe>
<script>
function load() {
iframe.contentWindow.postMessage('秋风的笔记', 'http://localhost:8080')
window.onmessage = e => {
console.log(e.data)
}
}
</script>
// another.html
<div>hello</div>
<script>
window.onmessage = e => {
console.log(e.data) // 秋风的笔记
e.source.postMessage(e.data, e.origin)
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
←
→
在线客服