解决跨域的4种方法

00_跨域的概念

浏览器只允许请问具有相同的协议,域名,端口,进行请求,有一个不同,就会拒绝。

01.前后端协商jsonp

复制代码
    //jsonp
    //jsonp 是 json with padding 的缩写,是一种通过 <script> 标签的 src 属性来实现跨域请求的技术。
    //jsonp 的原理是利用 <script> 标签的 src 属性可以加载外部资源,并且不受同源策略的限制,
    //所以可以通过 <script> 标签的 src 属性来加载外部资源,实从而现跨域请求。
    //jsonp 的缺点是只能发送 get 请求,不能发送 post 请求。
    //jsonp 的优点是简单易用,不需要服务器端的支持,只需要在客户端实现即可。
    只能发送get请求

后端

前端

(通过挂载全局函数解决)

02_前端解决,使用代理dev

直接请求,有跨域问题

解决方案:使用打包构建工具:vite或者webpack解决

复制代码
import { defineConfig } from 'vite';

export default defineConfig({
  server: {
    proxy: {
      // 将 /api 开头的请求代理到 Node.js 服务器
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
  }
});

03.后端解决,设置请求头

直接在接口处使用cors插件也行,设置请求头允许所有源访问。

前端

后端

nginx反向代理配置

将前端请求代理到后端API,例如:

nginx

复制代码
server {
    listen 80;
    server_name localhost;

    location /api {
        proxy_pass http://api.example.com;
    }
}

2. 添加跨域响应头

在代理配置中设置CORS相关头信息:

nginx

复制代码
location /api {
    proxy_pass http://api.example.com;
    
    # 允许的请求来源(替换为你的前端域名)
    add_header 'Access-Control-Allow-Origin' 'http://localhost:8080' always;
    
    # 允许的HTTP方法
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    
    # 允许的请求头
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
    
    # 允许携带凭证(如cookies)
    add_header 'Access-Control-Allow-Credentials' 'true' always;
}
复制代码
  • always 参数确保即使后端返回4xx/5xx错误,头信息仍被添加。

3. 处理OPTIONS预检请求

针对OPTIONS方法单独处理,直接响应无需转发到后端:

复制代码
nginx

location /api {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'http://localhost:8080';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
        add_header 'Access-Control-Max-Age' 1728000;  # 缓存预检结果20天(秒)
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }

    proxy_pass http://api.example.com;
    # ... 其他头配置同上
}

4. 动态允许多域名(可选)

使用map模块动态匹配允许的域名:

nginx

复制代码
map $http_origin $cors_origin {
    default "";
    ~^https?://(localhost:8080|example\.com|app\.example\.net)$ $http_origin;
}

server {
    ...
    location /api {
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' $cors_origin;
            ...
            return 204;
        }

        proxy_pass http://api.example.com;
        add_header 'Access-Control-Allow-Origin' $cors_origin always;
        ...
    }
}
复制代码

5. 完整配置示例

nginx

复制代码
http {
    map $http_origin $cors_origin {
        default "";
        ~^https?://(localhost:8080|example\.com)$ $http_origin;
    }

    server {
        listen 80;
        server_name localhost;

        location /api {
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' $cors_origin;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain; charset=utf-8';
                add_header 'Content-Length' 0;
                return 204;
            }

            proxy_pass http://api.example.com;
            add_header 'Access-Control-Allow-Origin' $cors_origin always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
        }
    }
}

6. 关键注意事项

  • 安全性 :避免使用*作为Access-Control-Allow-Origin的值,明确指定可信域名。

  • 凭证携带 :若前端需要发送Cookies,设置Access-Control-Allow-Credentials: true,且Access-Control-Allow-Origin不能为*

  • 缓存预检 :合理设置Access-Control-Max-Age减少OPTIONS请求次数。

  • 测试验证 :使用浏览器开发者工具或curl检查响应头是否包含CORS头信息。

验证命令示例

复制代码
curl -I -X OPTIONS http://nginx-server/api
# 检查返回头中是否包含CORS相关字段

更详细的可以访问:nginx跨域解决

相关推荐
爱学习的小囧8 分钟前
VMware Horizon 8 智能卡认证信任库配置攻略:新增 Root CA 导入指南
服务器·esxi·vmware·horizon
希望永不加班30 分钟前
SpringBoot 过滤器(Filter)与请求链路梳理
java·spring boot·后端·spring
sunny_30 分钟前
💥 Claude Code 源码泄露?我把这个最强 AI Coding Agent 的架构扒干净了
前端·agent·claude
Lyyaoo.33 分钟前
【JAVA基础面经】抽象类/方法与接口
java·开发语言
西洼工作室35 分钟前
React轮播图优化:通过延迟 + 动画的组合,彻底消除视觉上的闪烁感
前端·react.js·前端框架
0xDevNull36 分钟前
Java实现Redis延迟队列:从原理到高可用架构
java·开发语言·后端
于先生吖40 分钟前
无人共享健身房 Java 后端源码 + 多端对接完整方案
java·开发语言
yaaakaaang44 分钟前
(八)前端,如此简单!---五组结构
前端·javascript
恼书:-(空寄1 小时前
Spring 事务失效的 8 大场景 + 原因 + 解决方案
java·后端·spring
我是若尘1 小时前
我的需求代码被主干 revert 了,接下来我该怎么操作?
前端·后端·代码规范