Java与前端交互出现跨域问题的14种解决方案

2025-05-14 11:54:42 114
魁首哥

1 前端解决方案( 开发环境代理)

1.1 webpack开发服务器代理

// vue.config.js 或 webpack.config.js
module.exports = {
  devserver: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeorigin: true,
        pathrewrite: {
          '^/api': ''
        }
      }
    }
  }
}

1.2 vite代理配置

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

1.3 jsonp (仅限get请求)

function jsonp(url, callback) {
  const script = document.createelement('script');
  script.src = `${url}?callback=${callback}`;
  document.body.appendchild(script);
}
 
// 后端需要返回类似 callbackname(data) 的响应

1.4 websocket

const socket = new websocket('ws://your-backend-url');

1.5 修改浏览器安全策略 (仅开发环境)

chrome启动参数:--disable-web-security --user-data-dir=/tmp/chrome

2 后端解决方案

2.1 spring框架解决方案

2.1.1 使用@crossorigin注解

@restcontroller
@requestmapping("/api")
@crossorigin(origins = "*") // 允许所有来源
public class mycontroller {
    // 控制器方法
}

2.1.2 全局cors配置

@configuration
public class webconfig implements webmvcconfigurer {
    @override
    public void addcorsmappings(corsregistry registry) {
        registry.addmapping("/**")
            .allowedorigins("http://localhost:3000", "http://example.com")
            .allowedmethods("get", "post", "put", "delete", "options")
            .allowedheaders("*")
            .allowcredentials(true)
            .maxage(3600);
    }
}

2.1.3 过滤器方式

@bean
public filterregistrationbean corsfilter() {
    urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource();
    corsconfiguration config = new corsconfiguration();
    config.setallowcredentials(true);
    config.addallowedorigin("http://localhost:3000");
    config.addallowedheader("*");
    config.addallowedmethod("*");
    source.registercorsconfiguration("/**", config);
    return new filterregistrationbean<>(new corsfilter(source));
}

2.2 spring boot特定配置

application.properties配置

# 允许的源
cors.allowed-origins=http://localhost:3000,http://example.com
# 允许的方法
cors.allowed-methods=get,post,put,delete,options
# 允许的头部
cors.allowed-headers=*
# 是否允许凭证
cors.allow-credentials=true
# 预检请求缓存时间
cors.max-age=3600

2.3 spring security解决方案

@configuration
@enablewebsecurity
public class securityconfig extends websecurityconfigureradapter {
    @override
    protected void configure(httpsecurity http) throws exception {
        http.cors().and()
            // 其他安全配置
            .csrf().disable(); // 通常需要禁用csrf以简化api开发
    }
    
    @bean
    corsconfigurationsource corsconfigurationsource() {
        corsconfiguration configuration = new corsconfiguration();
        configuration.setallowedorigins(arrays.aslist("http://localhost:3000"));
        configuration.setallowedmethods(arrays.aslist("get","post","put","delete","options"));
        configuration.setallowedheaders(arrays.aslist("*"));
        configuration.setallowcredentials(true);
        urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource();
        source.registercorsconfiguration("/**", configuration);
        return source;
    }
}

3 生产环境解决方案

nginx反向代理

server {
    listen 80;
    server_name yourdomain.com;
    
    location /api {
        proxy_pass http://backend-server:8080;
        proxy_set_header host $host;
        proxy_set_header x-real-ip $remote_addr;
        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
    }
    
    location / {
        root /path/to/frontend/dist;
        try_files $uri $uri/ /index.html;
    }
}

4 高级方案

4.1 基于token的跨域认证

// 后端添加响应头
response.setheader("access-control-expose-headers", "authorization");
response.setheader("authorization", "bearer " + token);

4.2 预检请求(options)处理

@restcontroller
public class optionscontroller {
    @requestmapping(value = "/**", method = requestmethod.options)
    public responseentity handleoptions() {
        return responseentity.ok().build();
    }
}

4.3 动态允许源

@bean
public corsfilter corsfilter() {
    return new corsfilter(new urlbasedcorsconfigurationsource() {
        @override
        public corsconfiguration getcorsconfiguration(httpservletrequest request) {
            corsconfiguration config = new corsconfiguration();
            string origin = request.getheader("origin");
            if (allowedorigins.contains(origin)) { // 检查是否在允许列表中
                config.addallowedorigin(origin);
                config.setallowedmethods(arrays.aslist("get","post","put","delete","options"));
                config.setallowedheaders(arrays.aslist("*"));
                config.setallowcredentials(true);
            }
            return config;
        }
    });
}

选择哪种解决方案取决于具体需求、安全要求和部署环境。生产环境中推荐使用nginx反向代理或api网关方案,开发环境中可以使用代理或后端cors配置。

以上就是java与前端交互出现跨域问题的14种解决方案的详细内容,更多关于java跨域问题解决的资料请关注代码网其它相关文章!

分享
海报
114
上一篇:浅析Java中如何优雅地处理null值 下一篇:idea中使用git插件回滚代码的流程步骤

忘记密码?

图形验证码