跨域问题及前后端常见解决方案?

语言: CN / TW / HK

一.什么是跨域?

跨域其实就是浏览器的同源策略所导致的。protocol(协议)、domain(域名)、port(端口)三个有一个不一致,就会产生跨域。

二.跨域的示例?

了解跨域的概念后,解下来我们就来模拟出现跨域的状况,我们用node来创建后端服务器,并编写相关接口。不了解node的同学,可移步到我这篇文章,从0到1学习Node.js系列教程(第一篇):API接口初体验

编写一个post请求:

image.png

用postman调这个接口,成功调通了。

image.png

然后我们创建一个vue项目来进行联调,就会发现请求没有返回。

image.png

可是刚刚我们用postman来测试都是可以的呀,别着急,我们来看看console,就会发现有以下报错,出现以下报错其实就是出现了跨域问题

image.png

这也充分证明了跨域是浏览器的行为,并不是服务器的行为,出现这样的状况是因为你在浏览器其实是发出请求了的,服务器也接收到请求,并返回了数据了。那这里为什么没有接收到数据了,是因为被浏览器截胡了,所有导致你接收不到服务器返回的数据

三.跨域的常见解决方案?

1.在服务器端的请求头里面设置CROS允许跨域

CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。

同源安全策略 默认阻止“跨域”获取资源。但是 CORS 给了web服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。

那怎么解决呢,英文不好的同学,我们把这段报错复制到翻译里面,翻译也是我自己经常使用的一个工具。我承认我英文不好,但是有工具替我解决问题。

image.png

查看翻译,可以明确看到提示:请求的资源上不存在'access control Allow Origin'标头 所以这里其实已经给出了跨域的解决方案,那就是在后端的请求头里面设置CROS允许跨域。(这里要注意代码中并没有对get请求进行设置,这是因为get请求并不存在跨域问题,比如你在浏览器的地址栏是可以直接访问的,利用ajax也是可以了,这里我就不展示了)

image.png

注意一定要放在应用路由之前,建议位置【var app = express();】后面

再次在前端项目中请求,我们发现能正常访问的,那么这个跨域问题我们解决了。

image.png

2.前端利用proxy代理解决跨域(node正向代理)

前面我们讲到了后端在可以在请求头中设置CROS允许跨域,我们把刚刚在服务端设置跨域问题的代码注释掉,再次复现跨域问题。 \ 在实际项目中比如我们目前市场上大多数使用的都是vue或者react技术栈的项目,如果后端不给解决,或者后端忘记解决了,那我们一定要去求后端解决吗?同样都是工程师,为啥要去求后端解决呢?作为前端工程师我们也有自己的解决方案,那就是利用proxy进行代理解决跨,这里vue2项目为例。

①在前端先建配置文件vue.config.js,然后配置解决跨域的代码。

image.png

②在request.js里面配置baseURL。

image.png

③重启前端服务。

这一点非常重要,因为这属于配置文件,如果你不重启服务,是不会生效的。不然你明明改好了,却在代码层面纠结为啥不行?

④展示效果

代理后的请求路径: image.png

请求参数:

image.png

请求结果:

image.png

以上就是就是跨域的常见解决方案,我这里分别演示了前端解决方案后端解决方案,在日常的项目中,我们用得最多的其实也是这两种方式。

而跨域的解决方案还有以下方式:

3.Nginx 反向代理

4.JSONP

5.Websocket

6.window.postMessage

7.document.domain + Iframe

8.window.location.hash + Iframe

9.window.name + Iframe

10.浏览器开启跨域(终极方案)

这几种方案,大家了解即可。有兴趣的同学可以看看其他大佬的这篇文章哦。10种跨域解决方案(附终极大招),今天的分享就到这里吧。

### 笔者往期好文:

微信小程序如何分包?

前端性能优化,如何提高首屏加载速度?

前端技术日新月异,vue3.0的时代已经来临...