Rennen

Rennen

如何解决跨域问题

2024-02-28

简单水一篇博客~

什么是 CORS 跨域问题

场景

  • 在前后端分离模式开发的过程中,我们希望 Vue 前端项目去调用 Spring Boot 后端项目的接口,但是产生了报错。

    image

  • 通过断点调试,我们发现后端其实是接收到了前端的请求,但是在返回响应的时候却被浏览器阻止了。

同源策略

  • 什么是同源:URL 中的协议、域名、端口号三者都相同

  • 同源策略具体如何工作?

    首先我们要明确的一点是:「同源策略只在浏览器上生效」。这也就解释了明明本地调试能够成功响应的接口,为什么放到浏览器就不行了。

    举个例子,有两个网站,网站 A 是一个银行网站,其中有一个查询用户余额信息的 API 接口。

    网站 B 是一个毫不相干的第三方网站,和网站 A 不同源。

    网站 B 中有一个 JavaScript 脚本想要请求网站 A 的查询余额接口。浏览器携带着网站 A 的 Cookie 向网站 A 的后端发送请求,后端接收请求后又向浏览器返回带有余额信息的响应。此时同源策略发挥作用,由于网站 A 和网站 B 不同源,那么响应会被浏览器「截获」,网站 B 中的这个 JavaScript 脚本就获取不到这个响应,也就无法知道用户的余额信息。

如何解决跨域问题

  • 反向代理实现(以 Nginx 为例,nodejs 应该也可以实现):既然前端和后端不同源,那么可以用反向代理将前端和后端变为同源的。前端项目打包成静态文件部署到 Nginx 上,路径为 / 根目录。同时用 Nginx 将后端 Spring Cloud Gateway 网关反向代理到 /api 路径下。Nginx 的配置文件大概如下:

    http {
    		server {
            listen       80;
            server_name  localhost;
    
             location / {
                root   /home/12306/dist;
                index  index.html index.htm;
                try_files $uri $uri/ /index.html;
            }
    
            location /api {
                proxy_read_timeout 10s;
                proxy_pass http://127.0.0.1:9000/api;
            }
        }
    }
    
  • 后端实现:在后端中,返回响应时添加响应头。

    • Access-Control-Allow-Origin:指定哪些域名可以访问资源。如果设置为 * 则表示允许任何域名的请求。
    • Access-Control-Allow-Methods:指定允许的 HTTP 请求方法,如 GET, POST, PUT, DELETE 等。

具体到 Spring Boot 上的实现的话,可以参看这篇文章:Spring Boot 跨域及三种解决方式