Nginx部署前后端项目时的跨域问题

最近在准备一个小项目来着,使用tomcat部署后端的SpringBoot项目,然后使用Nginx部署前端界面并转发后端请求到相应的tomcat集群时,发生了跨域问题,解决过程欲仙欲死,特在此记录一下。

  • 环境介绍
    • 本地物理主机,配置host
    192.168.182.135 api.mk-shop.com
    192.168.182.135 shop.mk-shop.com
    192.168.182.135 center.mk-shop.com
    
    • 四台虚拟机,IP如下
    # tomcat主机1
    192.168.182.130
    # tomcat主机2
    192.168.182.131
    # nginx主机1
    192.168.182.135
    # nginx主机2
    192.168.182.132
    
    • 开放端口
    80/tcp 8080/tcp 8088/tcp 3306/tcp
    
    • 项目部署
      1. 前端项目部署在nginx本地,作为静态资源文件部署
      2. 后端项目部署在tomcat中,作为tomcat集群形式存在
请求过程
  • 实体主机作为请求发起端(客户端),访问shop.mk-shop.com(也就是Nginx服务器所在的主机地址)获取到前端页面的index.html文件,浏览器解析页面中的异步请求后在客户端浏览器向Nginx主机再次发起请求,获取到动态加载的数据。
  • 由于配置了nginx作为反向代理服务器,对于客户端而言请求都是发送给nginx代理服务器的,因此Nginx主机监听的都是客户端请求过来的url地址或者说是域名。
跨域处理
Nginx配置,一下配置只使用了一台Nginx(192.168.182.135)和两台Tomcat虚拟机。
# work的执行者,涉及到权限问题
user  root;
# work进程的个数
worker_processes  3;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    # 默认的事件调度机制 [ kqueue | rtsig | epoll | /dev/poll | select | poll ] 
    use epoll;
    # 每个work能连接的最大请求格式
    worker_connections  1024;
}


http {
    # 文件类型定义
    include       mime.types;
    # 传输的content-type
    default_type  application/octet-stream;
    
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;
    # 文件传输优化
    sendfile        on;
    # tcp传输优化,需要sendfile为on
    #tcp_nopush     on;
    # 每个请求存活时间
    #keepalive_timeout  0;
    keepalive_timeout  65;

    # 压缩传输,可以节省带宽
    gzip  on;
    # 配置压缩率
    gzip_comp_level 3;
    # 压缩文件类型
    gzip_types text/plain application/javascript application/x-javascript text/css app lication/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/json;
    # 允许压缩的最小字节数 1kb
    gzip_min_length 1024;
    
    # 加入自定义的网页界面的配置 静态
    #include frontend.conf;  
    # 加入自定义的tomcat配置 动态
    #include tomcats.conf;

    # 进行服务器配置实验
    server {
    listen 80;
    server_name shop.mk-shop.com;
    location / {
        root /home/website/foodie-shop;
        index index.html;
    }
    #location /mk-shop-api/ {
        # add_header 'Access-Control-Allow-Origin' *;
        #  add_header 'Access-Control-Allow-Credentials' 'true';
        #  add_header 'Access-Control-Allow-Methods' *;
        #    add_header 'Access-Control-Allow-Headers' *;
        #    proxy_pass http://192.168.182.131:8088;
       #}
    } 
    server {
        listen 80;
        server_name center.mk-shop.com;
        location / {
            root /home/website/foodie-center;
            index index.html;
        }
    }

    # 配置集群
    upstream api.mk-shop.com{
      server 192.168.182.131:8088;
      server 192.168.182.130:8088;
    }
      server {
        listen 80;
        server_name api.mk-shop.com;
        #允许跨域请求的域,*代表所有
        add_header 'Access-Control-Allow-Origin' '*';
        #允许带上cookie请求
        add_header 'Access-Control-Allow-Credentials' 'true';
        #允许请求的方法,比如 GET/POST/PUT/DELETE 
        add_header 'Access-Control-Allow-Methods' '*';
        #允许请求的header
        add_header 'Access-Control-Allow-Headers' '*';
        location / {
            proxy_pass http://api.mk-shop.com;
        }
    }
}

  • 配置说明
 server {
    listen 80;#要监听的端口
    server_name shop.mk-shop.com; #要监听的请求域名,这与实体机中配置的映射有关,此处实体机中映射到了135IP
    # 通过映射域名访问80端口时,直接将存储在本地/home/website/foodie-shop中的index.html文件返回给客户端浏览器
    location / {
        root /home/website/foodie-shop;
        index index.html;
    }

server {
        listen 80;
        server_name center.mk-shop.com;
        location / {
            root /home/website/foodie-center;
            index index.html;
        }
    }

Nginx跨域配置方法一

server {
    listen 80;
    server_name shop.mk-shop.com;
    location / {
        root /home/website/foodie-shop;
        index index.html;
    }
    # 通过url映射的方式来实现请求
    location /mk-shop-api/ {
       proxy_pass http://192.168.182.131:8088;# 后端tomcat所在主机的IP
    }
    } 

严格说来,这种方式并不算是跨域请求,因为这种配置要求后端请求的url必须为http://shop.mk-shop.com/mk-shop-api/xxxx的形式,也就是说前端项目的请求地址必须进行更改为和客户端页面访问时的url地址一样,这样貌似也就没有跨域问题了。如果前端项目不同模块的请求地址不一样,则都需要进行更改。
Nginx跨域配置方法二

 # 配置集群
    upstream api.mk-shop.com{
        server 192.168.182.131:8088;
        server 192.168.182.130:8088;
    }

    server {
        listen 80;
        server_name api.mk-shop.com;
        #允许跨域请求的域,*代表所有, 有时候可以添加 always 参数
        #使用 * 号存在一定的风险,可以使用固定的请求地址代替
        add_header 'Access-Control-Allow-Origin' '*';
        #允许带上cookie请求
        add_header 'Access-Control-Allow-Credentials' 'true';
        #允许请求的方法,比如 GET/POST/PUT/DELETE 
        add_header 'Access-Control-Allow-Methods' '*';
        #允许请求的header
        add_header 'Access-Control-Allow-Headers' '*';
        location / {
            proxy_pass http://api.mk-shop.com;
        }
    }

注意:api.mk-shop.com是后端api的请求前缀,也就是客户端异步加载时的请求地址,以我的项目的后端请求地址为例:

http://api.mk-shop.com/mk-shop-api/index/carousel
后端跨域处理

SpringBoot后端处理跨域时可以配置过滤器来实现

@Configuration
public class CorsConfig {

    public CorsConfig() {
    }

    @Bean
    public CorsFilter corsFilter() {
        //1.添加cors配置信息
        CorsConfiguration config = new CorsConfiguration();
        //设置允许的跨域来源
        //发布时本机的域名需要加入到跨域设置中
        //新版本的springboot中不允许在setAllowedOrigins包含 * ,需要使用setAllowedOriginPatterns代替
//        List<String> allowedOrigins = Arrays.asList(
//                "http://localhost:8080",
//                "http://shop.mk-shop.com",
//                "http://shop.mk-shop.com:8080",
//                "http://center.mk-shop.com",
//                "http://center.mk-shop.com:8080",
//                "*"
//        );
//        config.setAllowedOrigins(allowedOrigins);
        config.setAllowedOriginPatterns(Arrays.asList("*"));
        //设置是否允许携带cookie
        config.setAllowCredentials(true);
        //设置允许的header
        config.setAllowedHeaders(Arrays.asList("*"));
        //设置允许的方法
        config.setAllowedMethods(Arrays.asList("*"));

        //2.为url添加请求路径
        UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
        //所有路径都转发
        corsSource.registerCorsConfiguration("/**", config);

        //3.返回重新定义好的corsSource
        return new CorsFilter(corsSource);
    }

注意:使用过程中,新版本的springboot可能会报错不允许在setAllowedOrigins包含 * ,此时需要使用setAllowedOriginPatterns代替。

最后一点!!

  • Nginx和后端配置不要同时使用!!
  • 同时使用貌似会出错,搞死我了!
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容