Cloudflare通过代理服务器绕过 CORS 限制:原理、实现场景解析

第一部分:问题背景

在这里插入图片描述

1.1 错误现象复现

// 浏览器控制台报错示例
Access to fetch at 'https://chat.qwenlm.ai/api/v1/files/' from origin 'https://ocr.doublefenzhuan.me' 
has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

1.2 CORS 机制的核心原理

  • 同源策略 (Same-Origin Policy):浏览器的安全沙箱规则。
  • 预检请求 (Preflight Request)OPTIONS 方法的作用与触发条件。
  • 服务端责任Access-Control-Allow-Origin 等响应头的重要性。

1.3 逆向工程场景的特殊性

  • 无服务器控制权:无法修改目标服务器的 CORS 配置。
  • 突发性策略变更:目标服务器可能动态调整安全规则(如案例中的突然限制)。

第二部分:代理方案的技术实现

2.1 整体架构图

[浏览器] --> [同域代理接口 /proxy/upload] --> [目标服务器 chat.qwenlm.ai]

2.2 代码实现详解(以 Cloudflare Worker 为例)

// Worker 路由配置
addEventListener('fetch', event => {const url = new URL(event.request.url);switch(url.pathname) {case '/proxy/upload':if (event.request.method === 'POST') {return event.respondWith(handleProxyUpload(event.request));}break;// ...其他路由...}
});// 代理请求处理函数
async function handleProxyUpload(request) {try {// 1. 提取客户端请求内容const formData = await request.formData();const token = request.headers.get('Authorization')?.replace('Bearer ', '');// 2. 转发到目标服务器const targetResponse = await fetch('https://chat.qwenlm.ai/api/v1/files/', {method: 'POST',headers: {'accept': 'application/json','authorization': `Bearer ${token}`,},body: formData,});// 3. 返回处理后的响应const data = await targetResponse.json();return new Response(JSON.stringify(data), {headers: {'Content-Type': 'application/json','Access-Control-Allow-Origin': '*',},});} catch (error) {// ...错误处理...}
}

2.3 关键代码解析

代码片段作用说明
case '/proxy/upload'定义代理路由入口,匹配特定路径的请求
await request.formData()提取客户端提交的表单数据(含文件上传)
fetch('https://chat.qwenlm.ai')服务器端发起跨域请求,不受浏览器策略限制
Access-Control-Allow-Origin: *确保浏览器接受代理返回的响应

第三部分:技术原理深度解析

3.1 为什么代理方案有效?

  • 同源策略的规避:浏览器只感知到与页面同域的 /proxy/upload 请求。
  • 服务端特权:服务器间通信不受 CORS 限制(Node.js/Python/Worker 等)。
  • 请求头传递:代理可透传/修改敏感头信息(如 Authorization)。

3.2 与传统方案的对比

方案优点缺点适用场景
修改服务器 CORS 配置原生支持、性能最佳需要目标服务器控制权自有 API 服务
代理方案无需目标服务器配合增加中间层、略影响性能第三方 API/逆向工程
JSONP兼容老旧浏览器仅支持 GET、存在安全风险历史遗留系统
no-cors 模式快速实现无法读取完整响应简单请求且无需响应内容

问题

https://ocr.doublefenzhuan.me/proxy/upload 为什么加了proxy/upload就变成了后端服务器呢?

  1. 关于「后端服务器」的定义
    前端和后端的本质区别在于代码执行的位置:
  • 前端:运行在用户浏览器中的代码(HTML/CSS/JavaScript)。
  • 后端:运行在服务器上的代码(如 Node.js、Python、Java 等)。

URL 路径(如 /proxy/upload)本身不决定前后端,而是看该路径的请求由谁处理:

  • 如果请求由浏览器直接处理(如静态文件请求),属于前端。
  • 如果请求由服务器端代码处理(如动态接口),属于后端。
  1. 为什么 /proxy/upload 是后端服务器?
case '/proxy/upload':if (request.method === 'POST') {return handleProxyUpload(request); // 由服务器端代码处理}break;

路径 /proxy/upload 只是一个路由标识:
当客户端访问 https://ocr.doublefenzhuan.me/proxy/upload 时,请求会被 Worker 脚本捕获。
Worker 脚本根据路由规则(case ‘/proxy/upload’)调用 handleProxyUpload 函数。
handleProxyUpload 是服务器端代码(运行在 Cloudflare Worker 的服务器环境中),因此这个路径对应的逻辑属于后端。

  1. 为什么说「服务器之间没有跨域问题」?
  • CORS 是浏览器强制的安全策略,只影响浏览器发起的请求。
  • 服务器之间的 HTTP 请求(如 Worker → chat.qwenlm.ai)不受 CORS 限制,因为:
    • 服务器没有「同源策略」的概念。
    • 服务器可以自由向任何域名发起请求(除非目标服务器主动封禁)。

4.前端直接发起跨域请求的代码
创建 FormData 对象:前端通过 FormData 对象将文件数据包装成表单格式。 发起跨域请求:使用 fetch 直接向目标服务器 (https://chat.qwenlm.ai/api/v1/files/) 发起 POST 请求。 添加Authorization 头:将用户的认证令牌添加到请求头中。 处理响应:如果请求成功,解析并返回响应数据;如果失败,抛出错误。因为目标服务器不支持 CORS,前端需要通过代理服务器(或 Worker)绕过同源策略限制。

async function uploadFile(file, token) {try {// 创建 FormData 对象const formData = new FormData();formData.append('file', file); // 添加文件// 发起 POST 请求const response = await fetch('https://chat.qwenlm.ai/api/v1/files/', {method: 'POST',headers: {'accept': 'application/json','authorization': `Bearer ${token}`, // 添加 Authorization 头},body: formData, // 发送 FormData});// 处理响应if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const data = await response.json();return data;} catch (error) {console.error('Upload failed:', error);throw error;}
}

附录
5. 完整 Worker 代理代码示例
6. CORS 调试工具推荐
7. Cloudflare Worker 官方文档

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

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

相关文章

VMware虚拟机安装Linux系统(openKylin)

首先打开VMware Workstation,点击创建新的虚拟机。 进入虚拟机引导界面后,选择“典型”选项,点击下一步; 选择“稍后安装操作系统”,点击下一步; 客户机操作系统选择“Linux”,版本选择Ubuntu 6…

RabbitMQ 多种安装模式

文章目录 前言一、Windows 安装 RabbitMq1、版本关系2、Erlang2.1、下载安装 Erlang 23.12.2、配置 Erlang 环境变量 3、RabbitMQ3.1、下载安装 RabbitMQ 3.8.93.2、环境变量3.3、启动RabbitMQ 管理插件3.3、RabbitMQ3.4、注意事项 二、安装docker1、更新系统包:2、…

【Java-数据结构】Java 链表面试题上 “最后一公里”:解决复杂链表问题的致胜法宝

我的个人主页 我的专栏:Java-数据结构,希望能帮助到大家!!!点赞❤ 收藏❤ 引言: Java链表,看似简单的链式结构,却蕴含着诸多有趣的特性与奥秘,等待我们去挖掘。它就像一…

【0x03】HCI_Connection_Complete事件详解

目录 一、事件概述 二、事件格式及参数详解 2.1. HCI_Connection_Complete事件格式 2.2. 事件参数 2.2.1. Status 2.2.2. Connection_Handle 2.2.3. BD_ADDR 2.2.4. Link_Type 2.2.5. Encryption_Enabled 三、事件处理流程 3.1. 事件触发 3.2. 事件接收与解析 3.…

激活版,快速安装

每天开机都要等待很长时间,玩游戏或看视频时频繁卡顿,甚至偶尔还会莫名其妙地崩溃。这种情况几乎每个人都遇到过,真是让人头疼不已。 别担心,其实有一种方法可以让你的电脑恢复如新,让我们一起看看如何解决这些烦恼吧…

二叉树(了解)c++

二叉树是一种特殊的树型结构,它的特点是: 每个结点至多只有2棵子树(即二叉树中不存在度大于2的结点) 并且二叉树的子树有左右之分,其次序不能任意颠倒,因此是一颗有序树 以A结点为例,左边的B是它的左孩子,右边的C是…

C#标准Mes接口框架(持续更新)

前言 由于近期我做了好几个客户的接入工厂Mes系统的需求。但是每个客户的Mes都有不同程度的定制需求,原有的代码复用难度其实很大。所以打算将整个接入Mes系统的框架单独拿出来作为一个项目使用,同时因为不同的设备接入同一个Mes系统,所以代…

【Nacos】负载均衡

目录 前言 一、服务下线二、权重配置三、同一个集群优先访问四、环境隔离 前言 我们的生产环境相对是比较恶劣的,我们需要对服务的流量进行更加精细的控制.Nacos支持多种负载均衡策略,包括配置权重,同机房,同地域,同环…

嵌入式MCU面试笔记2

目录 串口通信 概论 原理 配置 HAL库代码 1. 初始化函数 2. 数据发送和接收函数 3. 中断和DMA函数 4. 中断服务函数 串口通信 概论 我们知道,通信桥接了两个设备之间的交流。一个经典的例子就是使用串口通信交换上位机和单片机之间的数据。 比较常见的串…

DDD该怎么去落地实现(1)关键是“关系”

DDD落地的关键是“关系” 这些年,我认为DDD走到了一个死胡同里了,因为落地实现过于困难。很多团队在经过一段时间的学习,清楚理解了DDD那些晦涩的概念,根据业务绘制出领域模型,这都不困难。但绘制领域模型不是我们最终…

RabbitMQ---面试题

常见面试题 1.MQ的作用及应用场景 类似问题:项目什么情况下用到了MQ,为什么要用MQ MQ的主要应用场景,消息队列的应用场景,为什么说消息队列可以削峰 首先MQ是一种用来接收和转发消息的队列,常见的应用常见如下&…

PaddleSeg 从配置文件和模型 URL 自动化运行预测任务

git clone https://github.com/PaddlePaddle/PaddleSeg.git# 在ipynb里面运行 cd PaddleSegimport sys sys.path.append(/home/aistudio/work/PaddleSeg)import os# 配置文件夹路径 folder_path "/home/aistudio/work/PaddleSeg/configs"# 遍历文件夹,寻…

2_高并发内存池_各层级的框架设计及ThreadCache(线程缓存)申请内存设计

一、高并发内存池框架设计 高并发池框架设计,特别是针对内存池的设计,需要充分考虑多线程环境下: 性能问题锁竞争问题内存碎片问题 高并发内存池的整体框架设计旨在提高内存的申请和释放效率,减少锁竞争和内存碎片。 高并发内存…

WebODM之python实现

1、安装webodm_slam 主要是了解API文档,查看之前的文章 安装WebODM_slate 2、安装webodm 查看之前的文章 Win10安装WebODM和操作全流程 3、python脚本 项目案例 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of…

2025年美赛C题:奥运奖牌榜模型 解析及Python代码实现

2025年美赛C题:奥运奖牌榜模型 解析及Python代码实现 1 题目 2025 MCM问题C:奥运奖 牌榜模型在最近的2024年巴黎夏季奥运会期间, 粉丝们除了观看个人项目外, 还关注每个 国家的整体 “ 奖牌榜 ”。 最终的结果(表1&am…

Qt 5.14.2 学习记录 —— 십칠 窗口和菜单

文章目录 1、Qt窗口2、菜单栏设置快捷键添加子菜单添加分割线和菜单图标 3、工具栏 QToolBar4、状态栏 QStatusBar5、浮动窗口 QDockWidget 1、Qt窗口 QWidget,即控件,是窗口的一部分。在界面中创建控件组成界面时,Qt自动生成了窗口&#xf…

Spring Boot 邂逅Netty:构建高性能网络应用的奇妙之旅

一、引言 在当今数字化时代,构建高效、可靠的网络应用是开发者面临的重要挑战。Spring Boot 作为一款强大的 Java 开发框架,以其快速开发、简洁配置和丰富的生态支持,深受广大开发者喜爱。而 Netty 作为高性能、异步的网络通信框架&#xff…

Windows中本地组策略编辑器gpedit.msc打不开/微软远程桌面无法复制粘贴

目录 背景 解决gpedit.msc打不开 解决复制粘贴 剪贴板的问题 启用远程桌面剪贴板与驱动器 重启RDP剪贴板监视程序 以上都不行?可能是操作被Win11系统阻止 最后 背景 远程桌面无法复制粘贴,需要查看下主机策略组设置,结果按WinR输入…

深圳大学-智能网络与计算-实验一:RFID原理与读写操作

实验目的与要求 掌握超高频RFID标签的寻卡操作。掌握超高频RFID标签的读写操作。掌握超高频RFID标签多张卡读取时的防冲突机制。 方法,步骤 软硬件的连接与设置超高频RFID寻卡操作超高频RFID防冲突机制超高频RFID读写卡操作 实验过程及内容 一.软硬…

快门:凝固瞬间与塑造动感的魔法开关

目录 一、快门的基本概念 二、快门速度的分类及效果 (一)高速快门 (二)低速快门 (三)安全快门 三、快门优先模式:掌控拍摄节奏的利器 四、快门与其他摄影要素的关系 (一&…