在现代Web开发中,特别是随着前后端分离架构的普及,跨域问题成为了开发者必须面对的一个重要议题。本文将详细介绍什么是跨域问题、其产生的原因以及如何从前端和后端两个角度来解决这个问题,并提供一些实用的代码示例。

一、跨域问题概述

1. 定义

跨域问题是指当一个资源试图从一个源加载时,如果该资源的域名、协议或端口号与当前网页的域名、协议或端口号不同,则会被浏览器阻止访问。这是为了防止恶意网站读取另一个网站的数据,从而保护用户的隐私和安全。

2. 常见场景

  • 前端页面部署在一个服务器上,而后端API部署在另一个服务器。
  • 开发环境与生产环境使用不同的域名或端口。

例如:

  • https://example.com/api 与 https://example.com:8080/api 不同源(端口不同)
  • https://example.com/api 与 http://example.com/api 不同源(协议不同)
  • https://example.com/api 与 https://sub.example.com/api 不同源(域名不同)

二、跨域问题产生原因

1. 同源策略

浏览器遵循同源策略(Same-origin policy),即只有当请求的URL的协议、域名和端口号都相同的情况下,才允许获取资源。任何一项不匹配都会导致跨域问题。

2. 预检请求(Preflight Request)

对于非简单请求(如PUT, DELETE等),浏览器会先发送一个OPTIONS请求到目标服务器,询问服务器是否允许此次跨域请求。如果服务器响应正确,浏览器才会继续发送实际请求。

三、解决方案

(一)前端解决方案

1. Proxy代理

在开发环境中,可以使用前端工具(如 Webpack Dev Server、Vite)配置代理服务器,将跨域请求转发到目标服务器。

示例(Vue.js/Vite 配置):

// vite.config.js
export default defineConfig({server: {proxy: {'/api': {target: 'http://backend-api.com',  // 后端API地址changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, '')}}}
})

原理:
前端请求发送到同域名的代理服务器(如http://localhost:3000/api),代理服务器再将请求转发到实际的后端服务器(如http://backend-api.com),从而避免浏览器的同源策略限制。

2. JSONP

JSONP 是一种古老的跨域解决方案,利用了<script>标签不受同源策略限制的特性。

工作流程:

  1. 前端动态创建<script>标签,src 指向后端 API,并添加回调函数名作为参数(如callback=handleData
  2. 后端收到请求后,将 JSON 数据包装在回调函数中返回(如handleData({"name":"John"})
  3. 浏览器执行返回的 JavaScript 代码,触发回调函数处理数据

示例代码:

function loadData() {const script = document.createElement('script');script.src = 'http://api.example.com/data?callback=handleData';document.body.appendChild(script);
}function handleData(data) {console.log('Received data:', data);
}

缺点

  • 只支持 GET 请求
  • 安全性较低,容易受到 XSS 攻击
  • 仅适用于与支持 JSONP 的 API 交互

(二)后端解决方案

1. CORS(Cross-Origin Resource Sharing)

CORS是一种W3C标准,它允许服务器声明哪些源站通过浏览器有权限访问哪些资源。下面是一个基于Gin框架的Go语言实现示例:

package middlewaresimport ("net/http""github.com/gin-gonic/gin"
)func Cors() gin.HandlerFunc {return func(context *gin.Context) {method := context.Request.Method// 允许所有域名进行跨域调用context.Header("Access-Control-Allow-Origin", "*")// 允许任何请求头context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,x-token,X-User-Id")// 允许任何方法(POST、GET等)context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")// 允许浏览器解析的头context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")// 允许携带Cookiecontext.Header("Access-Control-Allow-Credentials", "true")// 处理预检请求if method == "OPTIONS" {context.AbortWithStatus(http.StatusNoContent)}// 继续处理请求context.Next()}
}

关键响应头说明:

  • Access-Control-Allow-Origin:指定允许访问资源的源,可以是具体域名或*(允许所有)
  • Access-Control-Allow-Methods:允许的 HTTP 方法
  • Access-Control-Allow-Headers:允许的请求头
  • Access-Control-Allow-Credentials:是否允许携带 Cookie
  • Access-Control-Max-Age:预检请求的缓存时间

注意事项:

  • 生产环境应避免使用*,而是指定具体的域名
  • 如果设置了Access-Control-Allow-Credentials: true,则不能使用*
  • 预检请求(OPTIONS)需要快速响应,通常返回 204 状态码

四、生产环境中的跨域配置建议

  1. 精细控制 CORS 设置

    • 避免使用Access-Control-Allow-Origin: *,应指定具体的前端域名
    • 严格限制允许的请求头和方法
    • 仅在必要时启用Access-Control-Allow-Credentials
  2. 使用 HTTPS:混合使用 HTTP 和 HTTPS 可能导致跨域问题,建议前后端均使用 HTTPS。

  3. 监控预检请求:确保服务器正确处理 OPTIONS 请求,避免性能瓶颈。

  4. 考虑 CDN:静态资源(如 CSS、JS、图片)可以部署到 CDN,避免跨域问题。

五、总结

跨域问题是Web开发中不可避免的一部分,尤其是在前后端分离的趋势下。了解其背后的原理有助于我们选择合适的解决方案。一般来说,后端通过配置CORS是最直接有效的方式,而前端则可以通过代理或者JSONP等方式作为补充。合理地应用这些技术,可以有效地提升用户体验,同时确保系统的安全性。

如果这篇文章对大家有帮助可以点赞关注,你的支持就是我的动力😊!

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

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

相关文章

搜索数据建设系列之数据架构重构

导读 主要概述百度搜索业务数据建设的创新实践&#xff0c;重点围绕宽表模型设计、计算引擎优化和新一代业务服务交付模式&#xff08;图灵3.0开发模式&#xff09;三大方向&#xff0c;解决了传统数仓在搜索场景下面临的诸多挑战&#xff0c;实现了搜索数据建设的高效、稳定、…

2025年渗透测试面试题总结-2025年HW(护网面试) 29(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。、 目录 2025年HW(护网面试) 29 1. 样本分析思路 2. Linux GDB分析样本示例 3. 应急案例&#xff1a;WebShell后…

动态编程入门第二节:委托与事件 - Unity 开发者的高级回调与通信艺术

动态编程入门第一节&#xff1a;C# 反射 - Unity 开发者的超级工具箱 动态编程入门第二节&#xff1a;委托与事件 - Unity 开发者的高级回调与通信艺术 上次我们聊了 C# 反射&#xff0c;它让程序拥有了在运行时“看清自己”的能力。但光能看清还不够&#xff0c;我们还需要让…

降低网络安全中的人为风险:以人为本的路径

有效降低网络安全中的人为风险&#xff0c;关键在于采取以人为本的方法。这种方法的核心在于通过高效的培训和实践&#xff0c;使员工掌握安全知识、践行安全行为&#xff0c;并最终培育出安全且相互支持的文化氛围。 诚然&#xff0c;技术和政策必须为良好的安全行为提供支持、…

opencv裁剪和编译

opencv裁剪和编译 0. 准备工作 0.1 下载和安装Eigen 地址 https://eigen.tuxfamily.org/index.php?titleMain_Page对于opencv编译&#xff0c;需要增加EIGEN_INCLUDE_PATH和开启WITH_EIGEN -DWITH_EIGENON -DEIGEN_INCLUDE_PATH./3rd/eigen-3.4.01. 实际脚本 编译脚本如下: ch…

小白成长之路-mysql数据基础(三)

文章目录一、主从复制二、案例总结一、主从复制 1、master开启二进制日志记录2、slave开启IO进程&#xff0c;从master中读取二进制日志并写入slave的中继日志3、slave开启SQL进程&#xff0c;从中继日志中读取二进制日志并进行重放4、最终&#xff0c;达到slave与master中数据…

通过 Windows 共享文件夹 + 手机访问(SMB协议)如何实现

通过 Windows 共享文件夹 手机访问&#xff08;SMB协议&#xff09; 实现 PC 和安卓手机局域网文件共享&#xff0c;具体步骤如下&#xff1a; &#x1f4cc; 前置条件 电脑和手机连接同一局域网&#xff08;同一个Wi-Fi或路由器&#xff09;。关闭防火墙或放行SMB端口&#…

【Python3教程】Python3高级篇之正则表达式

博主介绍:✌全网粉丝23W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

Redis--黑马点评--达人探店功能实现详解

达人探店发布探店笔记探店笔记类似于点评网站的评价&#xff0c;往往是图文结合&#xff0c;对应的表有两个&#xff1a;tb_blog&#xff1a;探店笔记表&#xff0c;包含笔记中的标题、文字、图片等tb_blog_comments&#xff1a;其他用户对探店笔记的评价tb_blog表结构如下&…

一探 3D 互动展厅的神奇构造​

3D 互动展厅的神奇之处&#xff0c;离不开一系列先进技术的强力支撑 。其中&#xff0c;VR(虚拟现实)技术无疑是核心亮点之一。通过佩戴 VR 设备&#xff0c;观众仿佛被瞬间 “传送” 到一个全新的世界&#xff0c;能够全身心地沉浸其中&#xff0c;360 度无死角地观察周围的一…

C++ 网络编程(15) 利用asio协程搭建异步服务器

&#x1f680; [协程与异步服务器实战]&#xff1a;[C20协程原理与Boost.Asio异步服务器开发] &#x1f4c5; 更新时间&#xff1a;2025年07月05日 &#x1f3f7;️ 标签&#xff1a;C20 | 协程 | Boost.Asio | 异步编程 | 网络服务器 文章目录前言一、什么是协程&#xff1f;二…

【Java21】在spring boot中使用虚拟线程

文章目录 0.环境说明1.原理解析2.spring boot的方案3.注意事项&#xff08;施工中&#xff0c;欢迎补充&#xff09; 前置知识 虚拟线程VT&#xff08;Virtual Thread&#xff09; 0.环境说明 用于验证的版本&#xff1a; spring boot: 3.3.3jdk: OpenJDK 21.0.5 spring boot…

利器:NPM和YARN及其他

文章目录**1. 安装 Yarn&#xff08;推荐方法&#xff09;****2. 验证安装****3. 常见问题及解决方法****① 权限不足&#xff08;Error: EPERM&#xff09;****② 网络问题&#xff08;连接超时或下载失败&#xff09;****③ 环境变量未正确配置****4. 替代安装方法&#xff0…

跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能

众所周知&#xff0c;直播平台与短视频平台的贴纸功能不仅是用户表达个性的方式&#xff0c;更是平台提高用户粘性和互动转化的法宝。 可问题来了&#xff1a;如何让一个贴纸功能&#xff0c;在Android和iOS两大平台上表现一致、运行流畅、加载稳定&#xff1f;这背后&#xff…

JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)

前言 本片文章是学习B站黑马程序员苍穹外卖的学习笔记。因为最近期末周&#xff0c;一直在应付考试所以就学的很少&#xff0c;恰好视频中在讲Nginx反向代理和负载均衡&#xff08;写着对前端的内容做一个复习&#xff09; 概述&#xff1a; 1.web前端主要由三部分组成&…

智能学号抽取系统 V5.4.3.2 —— Vue.js 实现的多功能课堂随机抽签工具

智能学号抽取系统 V5.4.3.2 —— Vue.js 实现的多功能课堂随机抽签工具 在教学或会议场景中&#xff0c;我们经常需要随机抽取一个或多个学号/编号来决定发言者、答题者或者参与者。为了提高效率和公平性&#xff0c;我们可以使用一些智能化的小工具来实现这一过程。 今天介绍…

从0开始学习R语言--Day39--Spearman 秩相关

在非参数统计中&#xff0c;不看数据的实际数值&#xff0c;单纯比较两组变量的值的排名是通用的基本方法&#xff0c;但在客观数据中&#xff0c;很多变量的关系都是非线性的&#xff0c;其他的方法不是对样本数据的大小和线性有要求&#xff0c;就是只能对比数据的差异性&…

WSL - Linux 安装 Anaconda3-2025.06-0 详细教程 [WSL 分发版均适用]

一、检查系统状态 安装前先确认 WSL - Linxu 已正常启动&#xff08;比如 Ubuntu&#xff09;&#xff0c;网络连接稳定&#xff0c;并且系统磁盘有足够空间&#xff0c;一般建议预留至少 5GB 以上的可用空间&#xff0c;避免因空间不足导致安装失败。 二、下载安装包 Anacond…

热血三国建筑攻略表格

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>热血三国建筑攻略表格</title><style>…

SpringBoot+MySQL医院挂号系统源码

概述 基于SpringBootMySQL开发的医院挂号系统完整源码&#xff0c;该系统功能完善&#xff0c;包含从患者挂号到医生管理的全流程解决方案&#xff0c;采用主流技术栈开发&#xff0c;代码规范易于二次开发。 主要内容 系统包含完整的前后台功能模块&#xff1a; ​​前台功…