YAZONG 我的开源

关于一次域名代理导致的跨域问题

  , ,
0 评论0 浏览

1、1需求基本信息

比如两个域名

A为https://saas.a.com

B为https://saas.b.com

(以后域名都直接以A和B替代)

需求为浏览器访问B的时候要直接显示A的主页,这样对A做一个代理,浏览器的URL还是B并不是重定向到A。

注:

A是前后端分离项目。

前端服务为nodejs加载vue.js,nginx做WEB容器加载,并代理访问后端服务。

后端服务为Springcloud。

Vue.js中请求的API地址前缀为A,这个值并不是动态获取的。

1、2环境信息

1、2、1操作系统

[root@XX]# cat /etc/redhat-release

CentOS Linux release 7.6.1810 (Core)

[root@XX]# uname -r

3.10.0-957.21.3.el7.x86_64

1、2、2软件集成

[root@XX]# java -version

java version "1.8.0_172"

Java(TM) SE Runtime Environment (build 1.8.0_172-b11)

Java HotSpot(TM) 64-Bit Server VM (build 25.172-b11, mixed mode)

[root@XX]# node -v

v6.17.1

[root@XX]# VUE3.X

[root@XX]# nginx -v

nginx version: nginx/1.10.2

[root@XX]# springcloud-pom.xml

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Finchley.RELEASE</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.3.RELEASE</version>

<relativePath/>

</parent>

1、3请求模拟

当访问B执行点击登录操作时

1、3、1错误信息

浏览器console打印错误为:

Access to XMLHttpRequest at 'https://saas.a.com/api/xx/login' from origin 'https://saas.b.com' has been blocked by CORS policy:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

POST https://saas.a.com/api/xx/login net::ERR_FAILED

 

请求headers头信息为:

Request URL: https://saas.a.com/api/XX/login

Referrer Policy: no-referrer-when-downgrade

Provisional headers are shown

Accept: application/json, text/plain, */*

Content-Type: application/json;charset=UTF-8

Referer: https://saas.b.com/

且preview和response都为空。

那么此时我在B的nginx中加入了打印日志

XX/test.log

当刷新B的时候,test.log中并没有打印出请求API的信息,只有加载的静态文件信息。

1、3、2解决方案1-nginx

配置内容

在A的nginx配置中加入下述内容

add_header Access-Control-Allow-Origin *;

add_header Access-Control-Allow-Credentials 'true';

add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';

add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept';

saas.a.com.conf

[root@XX]# cat saas.a.com.conf

upstream gateway_proxy{

 

}

server {

listen       443 ssl;

server_name  saas.a.com;

......

 

location / {

......

root /xx/;

......

 

index index.html;

}

location /api/ {

......

add_header Access-Control-Allow-Origin *;

add_header Access-Control-Allow-Credentials 'true';

add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';

add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept';

proxy_pass  http://gateway_proxy/;

......

 

}

}

1、3、3解决方案2-Springcloud

配置内容

在Springcloud-zuul网关层加入下述内容。

如果要使用下述内容进行简单的测试,那么需要把”1、3、2解决方案1-nginx(不推荐)”中nginx加的配置删除。

当然了也可以nginx和Springcloud配合使用(当修改跨域这个问题时,由于后端开发人员并不清楚后端网关是否配置了跨域设置并且不懂,导致在调试时浪费了不少时间)。

@Bean

public FilterRegistrationBean corsFilter() {

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

CorsConfiguration config = new CorsConfiguration();

config.setAllowCredentials(true); // 设置你要允许的网站域名,如果全允许则设为 *

config.addAllowedOrigin("*"); // 如果要限制 HEADER 或 METHOD 请自行更改

config.addAllowedHeader("*");

config.addAllowedMethod("*");

source.registerCorsConfiguration("/**", config);

FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); // 这个顺序很重要哦,为避免麻烦请设置在最前

bean.setOrder(0);

return bean;

}

还原nginx配置文件

saas.a.com.conf

[root@XX]# cat saas.a.com.conf

upstream gateway_proxy{

 

}

server {

listen       443 ssl;

server_name  saas.a.com;

......

 

location / {

......

root /xx/;

......

 

index index.html;

}

location /api/ {

......

proxy_pass  http://gateway_proxy/;

......

 

}

}

saas.b.com.conf

[root@XX]# cat saas.b.com.conf

server {

 

listen       443 ssl;

server_name  saas.b.com;

 

......

 

location / {

 

......

 

root /xx/;

 

......

 

index index.html;

}

}

1、3、4最终解决效果

当进行B访问点击登录时,正常跳转,且浏览器URL并不是A的URL。

当点击Google-network的login请求时,Headers、Preview、Response都正常。

A对应nginx的access.log访问正常,且没有定向输出错误日志到error.log中。

Headers基本信息如下:

 

General

 

Request URL: https://saas.a.com/api/XX/login

Request Method: POST

Status Code: 200

Remote Address: IP:443

Referrer Policy: no-referrer-when-downgrade

 

Response Headers

 

Access-Control-Allow-Credentials: true

Access-Control-Allow-Origin: https://saas.a.com

Connection: keep-alive

Content-Type: application/json;charset=UTF-8

Date: Fri, 24 Jul 2020 09:18:46 GMT

Server: nginx/1.10.2

Transfer-Encoding: chunked

Vary: Origin

Vary: Access-Control-Request-Method

Vary: Access-Control-Request-Headers

 

Request Headers

 

Accept: application/json, text/plain, */*

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9

Connection: keep-alive

Content-Length: 39

Content-Type: application/json;charset=UTF-8

Cookie: ......

Host: saas.a.com

Origin: https://saas.a.com

Referer: https://saas.a.com/

Sec-Fetch-Dest: empty

Sec-Fetch-Mode: cors

Sec-Fetch-Site: same-origin

token: ......

User-Agent: ......

  

Request Payload

 

......

标题:关于一次域名代理导致的跨域问题
作者:yazong
地址:https://blog.llyweb.com/articles/2020/07/24/1595591374336.html