Nginx 跨域 + 无法设置 Cookie 解决办法

今天来分享一下关于项目部署上线时怎么解决跨域问题!!!

首先感谢一下大佬的方法,才让这个困扰我很久的问题得以解决!!!

这也是我请教大佬才解决的问题,大佬和我说,这是他耗费两周才解决的问题,我这也是属于前人栽树后人乘凉了,嘿嘿嘿!!!

前端问题

前端没有携带 cookie 导致后端识别不到

1) 前端 axios 是否开启了 withCredentials=true

2) 在 OpenAPI 的那边配置项,设置下 withCrendential

首先 F12 看 login 接口对应的网络请求有没有 ⚠️,如果有那是后端的问题,如果没有那是前端的问题

后端问题

YML 配置

Java 复制代码
复制代码
server:
  servlet:
    session:
      cookie:
        domain: 域名或者IP

http 环境就不要使用 secure 和samesite

使用宝塔跨域

后端相关的反向代理+跨域

Java 复制代码
server {
    # 这个监听的端口任意都行,但是要注意前端要请求这个端口
    listen       9090;
    server_name  localhost;


    location / {
        # 禁止非 GET|POST|HEAD|OPTIONS|PUT|PATCH|DELET 的请求
        if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) {
            return 444;
        }

        set $origin $http_origin;
        # 重点!比如:
        # $origin !~ '^http?://leikooo\.com$
        # $origin !~ '^http?://127.0.0.1$
        if ($origin !~ '^http?://服务器IP或者域名$') {
            set $origin 'http://服务器IP或者域名';
        }

        if ($request_method = 'OPTIONS') {

            add_header 'Access-Control-Allow-Origin' "$origin" always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;

            add_header Access-Control-Max-Age 1728000;
            add_header Content-Type 'text/plain charset=UTF-8';
            add_header Content-Length 0;
            return 204;
        }


        if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {
            add_header Access-Control-Allow-Origin "$origin" always;
            add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
            add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;
            add_header Access-Control-Allow-Credentials true always;
        }
        # 反向代理到后端具体运行的端口
        proxy_pass http://localhost:后端实际运行端口;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr; 

    }
}

注意:

  1. 前端请求 9090 (上面 server 模块下 listen 的端口)而不是直接请求后端实际运行端口

  2. 直接请求后端端口,那么 Nginx 就失去了存在的意义!

  3. 宝塔 + 服务器放行 9090 端口,这个要注意!!(具体看自己写的是哪个端口)

  4. 完成 添加 nginx 配置 + 放行端口 正常就没什么问题了!

使用原生 Nginx 跨域

经过实际测试,用 nginx 跨域就可以解决

nginx 复制代码
user  root;
worker_processes  1;

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

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}

http {

    include       mime.types;
    default_type  application/octet-stream;
    access_log  logs/access.log;

    sendfile        on;
    keepalive_timeout  65;

    #gzip  on;

    # 前端配置不是重点
    server {
        listen       80;
        server_name localhost ;

      	root /root/app/dist;
        # 访问默写前端页面 404 就是没加下面这行的原因
        try_files $uri $uri/ /index.html;
        
        location / {
            index  index.html index.htm;
        }
   }  

   # 后端相关的反向代理+跨域
   server {
        # 这个监听的端口任意都行,但是要注意前端要请求这个端口
        listen       9090;
        server_name  localhost;
        
      
        location / {
            # 禁止非 GET|POST|HEAD|OPTIONS|PUT|PATCH|DELET 的请求
            if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) {
                return 444;
            }
                
            set $origin $http_origin;
            # 重点!比如:
            # $origin !~ '^http?://leikooo\.com$
            # $origin !~ '^http?://127.0.0.1$
            if ($origin !~ '^http?://服务器IP或者域名$') {
                set $origin 'http://服务器IP或者域名';
            }

            if ($request_method = 'OPTIONS') {

                add_header 'Access-Control-Allow-Origin' "$origin" always;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
                add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
                add_header 'Access-Control-Allow-Credentials' 'true' always;

                add_header Access-Control-Max-Age 1728000;
                add_header Content-Type 'text/plain charset=UTF-8';
                add_header Content-Length 0;
                return 204;
            }
                

            if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {
                add_header Access-Control-Allow-Origin "$origin" always;
                add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
                add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;
                add_header Access-Control-Allow-Credentials true always;
            }
            # 反向代理到后端具体运行的端口
            proxy_pass http://localhost:后端实际运行端口;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr; 

        }
    }
}

注意:

1)前端请求 9090 而不是直接请求后端实际运行端口

2)服务器放行 9090 端口,这个要注意!!(具体看自己写的是哪个端口)

使用 HTTPS

实际测试使用域名 + HTTPS 也可以解决

这里看一下大佬写的!!!

教程:https://www.code-nav.cn/post/1831983737277050881

BUG

  1. 前端使用域名,但是前端后端使用 ip ,导致 session 设置不上

解决:前后端统一,要用域名都用域名、IP 都用 IP

  1. 还是不行?

1)端口是否放行!!!

2)前端请求的端口是否是 Nginx listen 的端口,不要直接请求实际端口 !!!

相关推荐
XIAOHEZIcode5 小时前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户03284722207021 小时前
如何搭建本地yum源(上)
运维
ping某2 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树884 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质4 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工4 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智4 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_4 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉4 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造