开发时的跨域问题解决方案——青训营笔记

121 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第4天

前言

在开发前后端分离的网页应用时,有一个问题是经常发生的,那就是跨域。屏幕前的你,一定在浏览器的控制台看到过这种界面吧:

img_v2_0300bead-b9b7-4150-b03b-cf4a04e89deg.png 那造成这种现象的原因是什么呢?又该如何解决呢?

什么是同源与跨域?

同源策略: 同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

同源的定义: 如果两个 URL 的 protocol、port(如果有指定的话) 和 host都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。

所以说,协议,主机,端口三者缺一不可,但是在前后端分离的开发过程中,前端和后端往往是运行在不同的运行时上的,所以端口就不会相同,跨域问题就产生了。

解决方案

既然知道了原理,那该如何解决呢?

CORS跨域资源共享

简而言之,就是在服务端允许的情况下,让浏览器可以进行跨域访问。

缺点:配置较为复杂,且如果允许全部跨域请求,也会导致不安全的因素产生。

请求代理

那有没有一种更简单的方案呢,有!那就是代理!

在计算机网络中,我们就学习到了代理的相关知识,比如NAT,就是通过代理,使得一个IP的用途增加的方式。简而言之,代理可以通过识别请求的特征,将请求转发给其他的地址,再在其他地址得到相应后,将数据返回。根据可见性,我们又将代理分为两类,正向代理反向代理

服务端配置:反向代理

反向代理是指代理发生在服务器端,例如NGINX就是一个典型的提供反向代理的服务器。这种代理对客户端是透明的。如图,在客户端看来,所有的请求都发到了NGINX上,也由NGINX返回,自然是同源的。

image.png 我们项目的部分NGINX配置如下:

    server {
        listen       80;
        server_name  vue;
         
		 # 用于 vue 页面 
        location / {
            autoindex on;
            root    /usr/share/nginx/html;    # /usr/share/nginx/html docker容器里面的目录
            try_files $uri $uri/ /index.html;  #history 模式
            index  index.html index.htm;
        }
	    # 用于 接口 访问
        location /api/ {
			proxy_pass http://node:3000/;  # 绝对路径,将 ip:80/api/xx 转发到 ip:8080/xx 上去
			proxy_redirect default;
        }
    }

客户端配置:正向代理

以上,服务器的反代做好了,这时候如果把前后端都放上去,也就可以运行了。但又有另一个问题,我们在本地开发时,通常前端是跑在本地的,如localhost:8080。若要与后端交互,不又产生了跨域问题吗?

实际上,前人们肯定想到了这个问题,以Vue为例,在其配置中,我们很容易就可以写好代理来对请求做代理:

  devServer: {
    proxy: { // 代理
      '/api': {
        ws: false,
        target: '后端所在的地址',
        changeOrigin: true,
        secure: false,
      }
    }
  }

这样,在请求localhost:8080/api/xxx的时候,本地服务器就会自动将请求转发到目标地址,这样,跨域问题就完美解决了!