深耕系列之浏览器跨域

·  阅读 242

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

问题引入

想必大家在与后端同学联调接口时,经常会遇到以下报错:

image.png

这报错是浏览器跨域引起的报错,那跨域到底是什么呢?

什么是跨域

在这里,引入了一个概念:同源策略

意思是说,如果协议,域名或者端口都相同才满足同源策略,资源之间才能互相访问。

http://baidu.com:8000/test

该条链接可知协议是http,域名是baidu.com,端口是8000
复制代码

如果有其中一个条件不符合,就会引起跨域问题,比如

  1. http协议不一致
http://baidu.com 和 https://baidu.com
复制代码
  1. 域名不一致
http://baidu.com 和 http://google.com
复制代码
  1. 端口不一致
http://baidu.com:8000/test 和 http://baidu.com:8001/test
复制代码

跨域问题是不满足同源策略引起的,那么为什么浏览器要引入这个同源策略呢?

同源策略引入原因

浏览器引入同源策略是为了防止CSRF攻击,CSRF攻击是利用用户的登录态发起恶意请求。

假如有A和B两个站点,在没有同源策略的情况下,A和B是可以互相访问的。如果A站点已经登录,存在登录状态,那么B站点就可以通过访问A站点获取到A站点的登录信息,从而发起恶意请求。

既然有了同源策略,浏览器是怎么拦截的呢?

跨域在何处被拦截

如果请求被跨域了,那么浏览器是否有发出请求?服务器是否有接到请求?实际上,请求是已经发出去了,但是浏览器在接受请求时,认为内容不安全,从而拦截了请求。

因此,你会发现,浏览器调用某接口报跨域错误,但是直接用postman工具去调接口,是可以拿到数据的,是正常的。

既然有跨域,前后端如何协助呢?

跨域处理方案

1. JSONP

jsonp的原理是利用

<script src="http://test.com/api?callback=jsonp"

<script>
	function jsonp(data) {
		console.log(data)
	}
</script>
复制代码
// http://test.com/api?callback=jsonp

jsonp('test')
复制代码

JSONP的兼容性良好,但是只限于get请求。

2. Proxy

由于跨域问题是浏览器引起的,而Proxy方案通过避开浏览器来解决跨域。

我们再使用vue项目进行开发时,可以在配置里启动代理。实际vue项目会在本地启动一个node代理服务器,发起请求会先请求到node代理服务器,node代理服务器会转发请求到目标服务器。由于node代理服务器和站点 是符合同源策略的,就不会出现跨域问题。

在线上部署时,我们也可以通过添加一层代理服务器做转发来处理跨域。

3. CORS

这个方案是常用,也是我推荐的。

CORS是需要后端支持的,只要在返回响应头时,服务器设置Access-Control-Allow-Origin,那么浏览器就允许跨域。这个属性表示哪些域名可以访问,我们可以设置通配符*来使得所有站点都可以访问。

通过CORS方案来解决跨域时,浏览器在发送请求时,会分为简单请求和复杂请求。

简单请求

满足一下条件时,就会触发简单请求

  1. 请求方法为以下:
  • GET
  • HEAD
  • POST
  1. Content-type的值为以下;
  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

复杂请求

不是简单请求的就是复杂请求。

对于复杂请求,浏览器会先发起一个预检查请求,为OPTION方法,用来咨询服务器是否支持跨域。

如果服务器返回200,表示支持跨域,那么浏览器才会发送真正的请求。因此服务器需要处理OPTION请求。

4. 浏览器插件

插件地址:chrome.google.com/webstore/de…

Chrome浏览器安装该插件后,可以避免跨域问题,具体原理是对响应头设置跨域头,和CORS一样,但不是服务器设置,而是插件设置。

这个方法只能用在开发环境上,便于开发人员调试。

总结

以上就是我对浏览器跨域的理解,如果觉得对你有帮助,请帮忙点个赞+评论+收藏。

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改