关于处理跨域问题遇到的坑,以及个人解决方案

前言:

        有这样一个需求,要求在第二个项目的页面中,嵌套展示第一个项目的前端页面,使用nginx作为中间件,此时直接去访问,就会出现跨域的问题

解决过程:

        先附上最开始使用的nginx配置

#第二个项目,仅展示部分配置
	server {
        listen       8002;
        server_name  localhost;

        location / {
            root   这里是路径;
            try_files $uri $uri/ /index.html;
            index  index.html index.htm;
        }

	location /prod-api/ {
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header REMOTE-HOST $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       	proxy_pass   http://192.168.1.1:7002/;
	 }

  	error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
     }

#第一个项目,仅展示部分配置
    server {
        listen       8001;
        server_name  localhost;
		proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

	    location / {
		    alias 这里是路径;
		    index login.html index.html;
        }
        location /xx/ {
             proxy_pass   http://192.168.1.1:7001/xx/;
        }  
 
    }

        在最初遇到这个问题的时候,作者也是查阅了很多资料,也使用过chatGPT去试图寻找答案,但是得到的结果都差强人意,在查找资料的过程中,找到最多的结果是

add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,token';

        使用了之后,跨域问题还是存在,于是找到了以下配置


if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,token';
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
}

add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,token';

这段配置的大概功能是,如果请求方法为OPTIONS,它会返回204响应,以满足预检请求。如果请求方法不是OPTIONS,它会设置其他CORS相关的响应头。

        注意:这项配置需要加在被访问的目标项目的nginx配置中,即本章配置中第一个项目的配置。通常情况下,只需要加到location /之后配置中即可

        当时作者加到了第二个项目中的配置,也可以在一定程度上解决跨域问题,之后又出现了这个问题,于是纠正了一下自己的配置,以下是第二次纠正后的配置

#第二个项目,仅展示部分配置
	server {
        listen       8002;
        server_name  localhost;

        location / {
            root   这里是路径;
            try_files $uri $uri/ /index.html;
            index  index.html index.htm;
        }

	location /prod-api/ {
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header REMOTE-HOST $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       	proxy_pass   http://192.168.1.1:7002/;
	 }

  	error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
     }

#第一个项目,仅展示部分配置
    server {
        listen       8001;
        server_name  localhost;
		proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

	    location / {
            if ($request_method = 'OPTIONS') {
        		add_header 'Access-Control-Allow-Origin' '*';
        		add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        		add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,token';
        		add_header 'Access-Control-Max-Age' 1728000;
        		add_header 'Content-Type' 'text/plain charset=UTF-8';
        		add_header 'Content-Length' 0;
        		return 204;
    		}

    		add_header 'Access-Control-Allow-Origin' '*';
    		add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    		add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,token';
		    alias 这里是路径;
		    index login.html index.html;
        }
        location /xx/ {
             proxy_pass   http://192.168.1.1:7001/xx/;
        }  
 
    }

        这样设置之后,理论上来说,跨域问题应该基本解决了才对,但是我分别试了192.168.1.1和127.0.0.1两个ip之后,还是会有跨域的情况出现,此时我又将每项配置梳理了一遍,发现问题似乎是由location /prod-api/内的配置引起的,因为这一段也设置了header,这里作者猜测与它有关,于是注释掉了这一段

location /prod-api/ {
		#proxy_set_header Host $http_host;
		#proxy_set_header X-Real-IP $remote_addr;
		#proxy_set_header REMOTE-HOST $remote_addr;
		#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       	proxy_pass   http://192.168.1.1:7002/;
	 }

        此时,跨域问题基本解决,第二个项目由于是二次开发的新项目,所以我选择了注释掉这段配置而不是删除,目前也没有出现其他问题,为什么说是基本解决呢,因为作者在测试的时候还有这样一个现象:使用edge浏览器,访问192.168.1.1没问题,但是访问127.0.0.1不能访问,会有跨域的情况,但是使用谷歌浏览器,访问两个ip都没有问题

        时间有限,只能先做到这一步了不过现在的结果也够当前项目的使用了,之后有时间再琢磨这一块吧,这篇文章也是记录一下这件事

第一次补充

        配置完成后还是有跨域分析,分析代码后发现后端Java代码内有全局跨域配置,但是不全,以下是允许所有来源的跨域请求的配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ... 其他安全配置 ...

            // 配置CORS
            .cors().and()

            // ... 其他安全配置 ...
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://example.com", "https://127.0.0.1:7001")); // 允许所有来源
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); // 允许的HTTP方法
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(Arrays.asList("*")); // 允许所有标头

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

        本文仅供参考,严禁全篇无脑转载,如有错误之处欢迎大佬指出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值