Skip to content

跨域

字数
775 字
阅读时间
4 分钟

跨域(CORS, Cross-Origin Resource Sharing)指的是浏览器出于安全性考虑,阻止在一个网页上加载或请求不同源(域名、协议、端口)资源的行为。由于浏览器的同源策略,一个网页只能请求与自身相同源的资源,避免了恶意网站通过脚本访问用户信息。

1 同源策略的定义:

“同源”是指协议、域名、端口号相同,三个同时相同才认为是同源。例如:

  • 同源:
    • http://example.com/pagehttp://example.com/api
    • https://example.com/pagehttps://example.com/api
  • 不同源:
    • http://example.com/pagehttps://example.com/api(协议不同)
    • http://example.com/pagehttp://sub.example.com/api(域名不同)
    • http://example.com:3000/pagehttp://example.com:4000/api(端口不同)

在前后端分离的项目中,前端通常运行在不同的域名、端口上,向后端API发起请求时会出现跨域问题。

2 解决跨域问题的常见方法

  1. CORS(Cross-Origin Resource Sharing)
    这是最常见的解决跨域问题的方式。服务器通过设置特定的HTTP头允许浏览器访问资源,常用的头包括:

    • Access-Control-Allow-Origin: 指定允许的请求源,可以是具体的域名,也可以设置为 *,表示允许所有域名访问。
    • Access-Control-Allow-Methods: 允许的HTTP方法(如 GET, POST 等)。
    • Access-Control-Allow-Headers: 允许的自定义请求头。

    Spring Boot 配置CORS:
    可以在Spring Boot项目中全局配置CORS:

    java
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:3000") // 允许的前端地址
                    .allowedMethods("GET", "POST", "PUT", "DELETE")
                    .allowedHeaders("*")
                    .allowCredentials(true);
        }
    }
  2. JSONP(JSON with Padding)
    JSONP是一种通过 <script> 标签绕过跨域限制的方式,适用于只需要 GET 请求的场景。前端通过动态插入 <script> 标签来请求不同源的资源,服务器返回JavaScript代码调用回调函数传递数据。由于安全性和局限性,JSONP使用较少。

  3. Nginx反向代理
    可以通过Nginx配置反向代理,将前端请求转发到后端服务器,这样浏览器只看到请求是同源的,跨域问题就解决了。例如:

    nginx
    server {
        listen 80;
        server_name example.com;
    
        location /api/ {
            proxy_pass http://backend-server:8080/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
  4. 前端代理
    在开发环境中,可以通过前端开发服务器配置代理。例如使用webpackvite等构建工具时,可以配置代理将API请求转发到后端,从而避免跨域问题。以 vite 为例:

    js
    export default {
        server: {
            proxy: {
                '/api': {
                    target: 'http://localhost:8080',
                    changeOrigin: true,
                    rewrite: (path) => path.replace(/^\/api/, '')
                }
            }
        }
    }

3 哪种方法适合你?

  • 如果是开发阶段,使用前端代理(webpack、vite等)较为方便。
  • 如果是生产环境,优先选择服务器端配置,如CORSNginx反向代理,这样可以从后端解决跨域问题。