跨域
同源策略
当出现非同源的请求时就会导致跨域问题。协议、域名和端口号都相同才称为同源。浏览器会丢失非同源请求的响应数据。
解决跨域
- JSONP
- CORS(跨源资源共享)
JSONP(JSON with padding)
前端通过动态设置<script>
标签来发送请求,可以在url
中指定回调函数和参数,后端将对应的数据放到回调函数执行语句中返回,而浏览器会立即执行该语句,这样就达到了跨域获取数据的目的。
// 前端
<script>
// 先定义好函数
function callback(arg1,arg2){
// 执行某些操作
}
const script = document.createElement('script')
script.src = "www.example.com?param1=arg1¶m2=arg2?"
document.body.appendChild(srcipt)
</script>
// 后端返回
callback({arg1: [1,2,3],arg2: '123'})
JSONP实现跨端的本质是利用了浏览器不会对html中的请求进行同源检测的特点。
JSOMP的缺点
- 只能使用get方法
- 执行起来麻烦,需要和后端约定数据、回调函数等。
- 不安全,如果请求的域不可行,则很容易被注入恶意代码
CORS 跨源资源共享
对于get
、post
这类简单请求,在发送时会包含一个Origin
属性,内容是请求页面的源,如果服务器同意响应,则需要在响应头Access-Control-Allow-Origin
包含相同的源或者是*
。
对于非简单请求,CORS会使用预检请求机制。
即在发送请求前,先发送一条Options
方法的请求来确认服务器允许的请求方式和头部字段等。
请求包含以下头部
❑ Origin:与简单请求相同。
❑ Access-Control-Request-Method:请求希望使用的方法。
❑ Access-Control-Request-Headers:(可选)要使用的逗号分隔的自定义头部列表。
响应包含以下头部
❑ Access-Control-Allow-Origin:与简单请求相同。 // 特定域名或者*
❑ Access-Control-Allow-Methods:允许的方法(逗号分隔的列表)。
❑ Access-Control-Allow-Headers:服务器允许的头部(逗号分隔的列表)。
❑ Access-Control-Max-Age:缓存预检请求的秒数。
nginx反向代理
使用nginx反向代理,但是这种方式需要在nginx实现跨域。
❑ add_header Access-Control-Allow-Origin:与简单请求相同。
❑ add_header Access-Control-Allow-Methods:允许的方法(逗号分隔的列表)。
❑ add_header Access-Control-Allow-Headers:服务器允许的头部(逗号分隔的列表)。
document.domain
该方式只能用于二级域名相同的情况下,比如 a.test.com
和 b.test.com
适用于该方式。 只需要给页面添加 document.domain ='test.com'
表示二级域名都相同就可以实现跨域。
实现原理:两个页面都通过js强制设置document.domain
为基础主域,就实现了同域。
websocket
Websocket
实现了浏览器和服务器的全双工通讯,它的建立依靠http,但是建立连接后双方即可主动发送或接收数据。