Nginx反向代理解决跨域问题详解

核心原理

Nginx反向代理解决跨域的核心思路是让客户端请求同域名下的接口,由Nginx将请求转发到目标服务器,从而规避浏览器的同源策略限制。

客户端(同源:www.domain.com)↓Nginx(同源:www.domain.com)↓
目标服务器(跨域:api.external.com)

完整配置与代码示例

基本反向代理配置

# /etc/nginx/conf.d/default.confserver {listen 80;server_name mydomain.com;  # 前端域名# 前端静态资源location / {root /usr/share/nginx/html;index index.html;}# 接口代理配置location /api {# 后端实际地址(跨域的目标服务器)proxy_pass http://api.external.com;# 设置必要的请求头proxy_set_header Host $proxy_host;  # 保留原始Hostproxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;# CORS支持(可选)add_header 'Access-Control-Allow-Origin' '*' always;add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;add_header 'Access-Control-Allow-Credentials' 'true' always;# 处理OPTIONS预检请求if ($request_method = 'OPTIONS') {add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;return 204;}}
}

关键配置解析

  1. proxy_pass

    location /api {proxy_pass http://api.external.com;
    }
    
    • 所有以/api开头的请求都会被转发到http://api.external.com
  2. 请求头保留

    proxy_set_header Host $proxy_host;      # 保留原始主机头
    proxy_set_header X-Real-IP $remote_addr; # 保留客户端真实IP
    
  3. CORS支持

    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    
    • 直接从Nginx层支持CORS,后端服务不需要额外处理
  4. OPTIONS请求处理

    if ($request_method = 'OPTIONS') {add_header 'Access-Control-Max-Age' 1728000;# ...return 204;
    }
    
    • 直接响应预检请求,减轻后端服务器压力

常见场景定制配置

场景1:URL重写(删除API前缀)
location /api {# 重写路径:移除/api前缀rewrite ^/api/(.*)$ /$1 break;proxy_pass http://api.external.com;
}
场景2:添加API前缀
location /user-service {# 添加/api前缀rewrite ^/user-service/(.*)$ /api/$1 break;proxy_pass http://api.external.com;
}
场景3:负载均衡
upstream backend {server backend1.example.com:8080 weight=3;  # 权重server backend2.example.com:8081;server backup.example.com:8082 backup;       # 备用服务器
}location /api {proxy_pass http://backend;  # 使用负载均衡器proxy_set_header Host $host;
}
场景4:WebSocket支持
location /socket {proxy_pass http://ws-server.com;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_set_header Host $host;
}

前端代码示例

// 请求代理路径(不再需要直接访问跨域地址)
const API_BASE = '/api'; // 与Nginx配置中的location匹配// GET请求示例
async function getData() {try {const response = await fetch(`${API_BASE}/data`, {method: 'GET',headers: {'Content-Type': 'application/json'}});return await response.json();} catch (error) {console.error('Error fetching data:', error);}
}// POST请求示例
async function postData(data) {try {const response = await fetch(`${API_BASE}/save`, {method: 'POST',headers: {'Content-Type': 'application/json','Authorization': `Bearer ${token}`},body: JSON.stringify(data)});return await response.json();} catch (error) {console.error('Error posting data:', error);}
}

完整操作流程

  1. 安装Nginx

    # Ubuntu/Debian
    sudo apt update
    sudo apt install nginx# CentOS/RHEL
    sudo yum install epel-release
    sudo yum install nginx
    
  2. 编辑配置文件

    sudo nano /etc/nginx/conf.d/default.conf
    

    添加上面的代理配置

  3. 测试配置

    sudo nginx -t
    

    输出 syntax is oktest is successful 表示配置正确

  4. 重启Nginx

    sudo systemctl restart nginx
    # 或
    sudo service nginx restart
    
  5. 部署前端项目

    # 将前端构建文件放入指定目录
    sudo cp -R /path/to/dist /usr/share/nginx/html
    
  6. 验证访问
    访问 http://your-domain.com 应该加载前端页面,所有API请求自动代理到目标服务

优势对比

方案是否需要修改代码安全性性能影响多服务支持
Nginx反向代理⭐⭐⭐⭐⭐几乎没有⭐⭐⭐⭐⭐
CORS⭐⭐⭐⭐中等⭐⭐
JSONP
Webpack代理✘ (仅开发)⭐⭐低(开发)⭐⭐

注意事项

  1. 路径匹配

    • 确保location指令的路径匹配模式与前端请求一致
    • 使用正则表达式处理复杂的URL模式
  2. 日志调试

    location /api {proxy_pass http://api.external.com;access_log /var/log/nginx/api-access.log;error_log /var/log/nginx/api-error.log;
    }
    
  3. 超时设置

    proxy_connect_timeout 60s;   # 连接超时
    proxy_send_timeout 60s;       # 发送超时
    proxy_read_timeout 180s;      # 读取超时
    
  4. Cookie传递

    proxy_cookie_domain api.external.com mydomain.com;
    proxy_cookie_path / /api/;
    
  5. 安全限制

    • 避免完全开放的跨域(Access-Control-Allow-Origin: *)
    • 建议使用具体的域名白名单

Nginx反向代理是当前解决跨域问题最成熟、稳定、高性能的解决方案,特别适合生产环境使用,既能解决跨域问题,又能实现负载均衡、安全防护等额外好处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/84605.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/84605.shtml
英文地址,请注明出处:http://en.pswp.cn/web/84605.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单片机测ntc热敏电阻的几种方法

在单片机中测量NTC(负温度系数)热敏电阻的阻值,通常需要将其转换为电压或频率信号,再通过单片机进行采集和处理。以下是几种常见的方法及其详细说明: 1. 分压法(最常用)​​ ​​原理​​&…

一套基于粒子群优化(PSO)算法的天线波束扫描MATLAB实现方案

以下是一套基于粒子群优化(PSO)算法的天线波束扫描MATLAB实现方案,包含完整代码、数学原理和详细注释。该方案针对均匀线性阵列(ULA)的波束方向图优化,通过调整阵元相位实现主瓣指向目标方向并抑制旁瓣。 %% 天线波束扫描的PSO算法实现 % 作者:DeepSeek % 创建日期:20…

增量学习ASAP的源码剖析:如何实现人形的运动追踪和全身控制(核心涉及HumanoidVerse中的agents模块)

前言 过去一周,我司「七月在线」长沙分部的具身团队在机械臂和人形上并行发力 关于机械臂 一方面,在IL和VLA的路线下,先后采集了抓杯子、桌面收纳、插入耳机孔的数据,然后云端训-本地5090推理 二方面,在RL的路线下&a…

计算机网络学习笔记:应用层概述、动态主机配置协议DHCP

文章目录 一、应用层概述1.1、C/S架构1.2、P2P架构 二、动态主机配置协议DHCP2.1、DHCP发现报文2.2、DHCP提供报文2.3、DHCP请求报文2.4、DHCP确认报文2.5、DHCP的续约与终止 总结 一、应用层概述 应用层位于计算机网络结构的最上层,用于解决应用进程的交互以实现特…

为服务器SSH登录增加2FA验证

安装NTP模块并设置时区 安装NTP模块 一般的服务器NTP服务默认是不安装的,需要安装NTP模块【7】并启用。 运行以下指令检查你的NTP模块是否已启用,已启用则忽略安装NTP模块的内容 timedatectl 如果你的返回内容和以下图片一样,则表示NTP未…

AI大模型提示词工程研究报告:长度与效果的辩证分析

一、核心问题:提示词长度与模型性能的平衡 核心矛盾:提示词长度增加 → 信息丰富度↑ & 准确性↑ ↔ 计算成本↑ & 响应延迟↑ 二、详细机制分析 (一)长提示词的优势(实证数据支持) 案例类型短提…

HttpServletResponse源码解析

Java Servlet API 中 HttpServletResponse 接口的源码,这是 Java Web 开发中非常核心的一个接口,用于向客户端(通常是浏览器)发送 HTTP 响应。 public interface HttpServletResponse extends ServletResponse {int SC_CONTINUE …

AI基础概念

目录 1、ASR和STT区别 2、流式输出 定义 原理 应用场景 优点 缺点 3、Ollama 4、mindspore和deepseek r1 v3 5、DeepSeek R1/V3 用的哪个底层AI框架 6、HAI-LLM比tensorflow、pytorch还强么 1. 核心优势对比 2. 性能表现 3. 适用场景 总结 7、openai用的什么底层…

ubuntu20.04速腾聚创airy驱动调试

1.下载相关资料 下载包括:速腾airy产品手册.pdf、RSView(用于显示激光雷达数据)、3d数模文件、 RS-LiDAR-16用户手册 以下链接进行下载 https://www.robosense.cn/resources 2.连接线路后通过Wireshark抓包后进行本地IP配置 2.1按照线路连…

Redis的大key和热key如何解决

文章目录 Redis大Key一、什么是Redis大Key二、大Key的产生原因三、大Key的影响四、大Key的解决方案1. 检测大Key2. 解决方案(1) 数据拆分(2) 使用压缩算法(3) 使用合适的数据结构(4) 设置合理的过期时间(5) 合理清理(6) 配置优化 五、预防措施总结 Redis热key一、热Key问题的本…

恒温晶振与温补晶振的区别

在电子设备领域,晶振如同精准的“心脏起搏器”,为电路提供稳定的时钟信号。恒温晶振(OCXO)和温补晶振(TCXO)作为两类重要的晶体振荡器,在不同的应用场景中发挥着关键作用,它们的区别…

基于SpringBoot的在线考试智能监控系统设计与实现

目录 一.🦁前言二.🦁开源代码与组件使用情况说明三.🦁核心功能1. ✅算法设计2. ✅Java开发语言3. ✅Vue.js框架4. ✅部署项目 四.🦁演示效果1. 管理员模块1.1 用户管理 2. 教师模块2.1 考试管理2.2 浏览试题列表2.3 添加试题2.4 成…

0基础学Python系列【16】自动化邮件发送的终极教程:Python库smtplib与email详解

大家好,欢迎来到Python学习的第二站!🎉 Python自带了一些超好用的模块,可以让你不必从头写代码就能实现很多功能。比如数学计算、文件操作、网络通信等。花姐会挑选常用的一些模块来讲解,确保你能在实际项目中用到。🎉 本章要学什么? 接下来花姐会深入浅出的讲解下面…

环卫车辆定位与监管:安心联车辆监控管理平台--科技赋能城市环境卫生管理

一、 引言 城市环境卫生是城市文明的重要标志,也是城市管理的重要内容。随着城市化进程的加快,环卫作业范围不断扩大,环卫车辆数量不断增加,传统的管理模式已难以满足现代化城市管理的需求。为提高环卫作业效率,加强环…

GIS 数据质检:验证 Geometry 有效性

前言 在GIS开发中,数据的几何有效性直接影响分析结果的准确性。无效的几何(如自相交、空洞或坐标错误)可能导致空间计算失败或输出偏差。无论是Shapefile、GeoJSON还是数据库中的空间数据,几何质检都是数据处理中不可忽视的关键步…

AI大模型学习之基础数学:高斯分布-AI大模型概率统计的基石

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…

HarmonyOS性能优化——耗时操作减少

耗时操作减少 在应用开发中,避免主线程执行冗余和耗时操作至关重要。这可以降低主线程负载,提升UI响应速度。 避免主线程冗余操作 冗余操作是不必要的、重复执行且对程序功能无实质性贡献的操作。这些操作浪费计算资源,降低程序运行效率&a…

emscripten 编译 wasm 版本的 openssl

搭建emscripten环境【参考:https://emscripten.org/docs/getting_started/downloads.html】 下载openssl解压复制到emsdk目录 依次执行下列命令: cd emsdk #激活emsdk source ./emsdk_env.shcd opensslemconfigure ./Configure linux-x32 -no-asm -sta…

uniapp 实战新闻页面(一)

新闻系统 一、 创建项目 创建个人中心 page.json 配置 tabar "tabBar": {"color":"#666","selectedColor": "#31C27C","list": [{"text": "首页","pagePath": "pages/inde…

JAVA锁机制:对象锁与类锁

JAVA锁机制:对象锁与类锁 在多线程编程中,合理使用锁机制是保证数据一致性和线程安全的关键。本文将通过示例详细讲解 Java 中的对象锁和类锁的原理、用法及区别。 一、未加锁的并发问题 先看一段未加锁的代码: public class Synchronize…