关于跨域
条评论为什么会跨域
跨域的原因:浏览器的同源策略(是一种安全策略,用于隔离潜在恶意文件)
浏览器是从两个方面去做这个同源策略的,一是针对接口的请求,二是针对Dom的查询。如果没有同源策略,会出现以下的安全问题:
1. 没有同源策略限制的接口请求
CSRF(Cross-site request forgery)攻击,中文名:跨站请求伪造
步骤:
1. 登录受信任网站A,并在本地生成Cookie
2. 在不登出A的情况下,访问危险网站B
2. 没有同源策略限制的Dom查询
利用高仿域名和iframe干坏事
1 | // HTML |
解决跨域问题
同源策略一定程度上防止了如CSRF这种恶意攻击,但也给开发造成了一些不便。尤其在流行前后端分离的开发模式之后,前端的开发环境通常会有自己的服务,调用后端端口时由于跨域问题会调用失败,那么我们有以下的方法来解决跨域问题:
JSONP:
在HTML标签里,一些标签比如script、img这样的获取资源的标签是不会受跨域限制,JSONP正是利用了这一点。
空iframe加form
JSONP只能发GET请求,因为本质上script标签获取资源就是GET请求,如果想要发送POST请求,可以利用空irame加form的办法:
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
36
37const requestPost = ({url, data}) => {
// 首先创建一个用来发送数据的iframe.
const iframe = document.createElement('iframe')
iframe.name = 'iframePost'
iframe.style.display = 'none'
document.body.appendChild(iframe)
const form = document.createElement('form')
const node = document.createElement('input')
// 注册iframe的load事件处理程序,如果你需要在响应返回时执行一些操作的话.
iframe.addEventListener('load', function () {
console.log('post success')
})
form.action = url
// 在指定的iframe中执行form
form.target = iframe.name
form.method = 'post'
for (let name in data) {
node.name = name
node.value = data[name].toString()
form.appendChild(node.cloneNode())
}
// 表单元素需要添加到主文档中.
form.style.display = 'none'
document.body.appendChild(form)
form.submit()
// 表单提交后,就可以删除这个表单,不影响下次的数据发送.
document.body.removeChild(form)
}
// 使用方式
requestPost({
url: 'http://localhost:9871/api/iframePost',
data: {
msg: 'helloIframePost'
}
})
CORS
CORS(Corss-origin resource sharing)是一个W3C标准,全称是“跨域资源共享”。
CORS详解代理
服务器之间的通信不存在同源策略问题,例如webpack-dev-server:
1
21. browser => localhost:8080(webpack-dev-server无代理) => http://you.test.com
2. browser => localhost:8080(webpack-dev-server有代理) => http://you.test.com- 上面第一种情况客户端直接访问跨域的服务端,会受同源策略限制。
- 而第二种,客户端访问代理服务器,代理服务器访问真正的服务器。服务器之间的通信不存在同源策略问题,所以同源策略的问题就通过代理服务器得到了解决。