当前位置: 首页 > news >正文

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 官方文档

相关文章:

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 doesnt pass access con…...

吴恩达深度学习——如何实现神经网络

来自吴恩达深度学习,仅为本人学习所用。 文章目录 神经网络的表示计算神经网络的输出激活函数tanh选择激活函数为什么需要非激活函数双层神经网络的梯度下降法 随机初始化 神经网络的表示 对于简单的Logistic回归,使用如下的计算图。 如果是多个神经元…...

《STL基础之vector、list、deque》

【vector、list、deque导读】vector、list、deque这三种序列式的容器,算是比较的基础容器,也是大家在日常开发中常用到的容器,因为底层用到的数据结构比较简单,笔者就将他们三者放到一起做下对比分析,介绍下基本用法&a…...

LockSupport概述、阻塞方法park、唤醒方法unpark(thread)、解决的痛点、带来的面试题

目录 ①. 什么是LockSupport? ②. 阻塞方法 ③. 唤醒方法(注意这个permit最多只能为1) ④. LockSupport它的解决的痛点 ⑤. LockSupport 面试题目 ①. 什么是LockSupport? ①. 通过park()和unpark(thread)方法来实现阻塞和唤醒线程的操作 ②. LockSupport是一个线程阻塞…...

Android开发基础知识

1 什么是Android? Android(读音:英:[ndrɔɪd],美:[ˈnˌdrɔɪd]),常见的非官方中文名称为安卓,是一个基于Linux内核的开放源代码移动操作系统,由Google成立…...

C++ Lambda 表达式的本质及原理分析

目录 1.引言 2.Lambda 的本质 3.Lambda 的捕获机制的本质 4.捕获方式的实现与底层原理 5.默认捕获的实现原理 6.捕获 this 的机制 7.捕获的限制与注意事项 8.总结 1.引言 C 中的 Lambda 表达式是一种匿名函数,最早在 C11 引入,用于简化函数对象的…...

《多线程基础之条件变量》

【条件变量导读】条件变量是多线程中比较灵活而且容易出错的线程同步手段,比如:虚假唤醒、为啥条件变量要和互斥锁结合使用?windows和linux双平台下,初始化、等待条件变量的api一样吗? 本文将分别为您介绍条件变量在w…...

21款炫酷烟花合集

系列专栏 《Python趣味编程》《C/C趣味编程》《HTML趣味编程》《Java趣味编程》 写在前面 Python、C/C、HTML、Java等4种语言实现18款炫酷烟花的代码。 Python Python烟花① 完整代码:Python动漫烟花(完整代码) ​ Python烟花② 完整…...

智能风控 数据分析 groupby、apply、reset_index组合拳

目录 groupby——分组 本例 apply——对每个分组应用一个函数 等价用法 reset_index——重置索引 使用前​编辑 注意事项 groupby必须配合聚合函数、 关于agglist 一些groupby试验 1. groupby对象之后。sum(一个列名) 2. groupby对象…...

Python网络自动化运维---用户交互模块

文章目录 目录 文章目录 前言 实验环境准备 一.input函数 代码分段解析 二.getpass模块 前言 在前面的SSH模块章节中,我们都是将提供SSH服务的设备的账户/密码直接写入到python代码中,这样很容易导致账户/密码泄露,而使用Python中的用户交…...

【JVM】调优

目的: 减少minor gc、full gc的次数,也就是减少STW的时间,因为java虚拟机在做后台垃圾收集线程的时候,会停掉其他线程,专门做垃圾收集,这样会影响网站的性能,以及用户的体验。 调优位置&#x…...

软件测试 —— jmeter(2)

软件测试 —— jmeter(2) HTTP默认请求头(元件)元件作用域和取样器作用域HTTP Cookie管理器同步定时器jmeter插件梯度压测线程组(Stepping Thread Group)参数解析总结 Response Times over TimeActive Thre…...

为什么LabVIEW适合软硬件结合的项目?

LabVIEW是一种基于图形化编程的开发平台,广泛应用于软硬件结合的项目中。其强大的硬件接口支持、实时数据采集能力、并行处理能力和直观的用户界面,使得它成为工业控制、仪器仪表、自动化测试等领域中软硬件系统集成的理想选择。LabVIEW的设计哲学强调模…...

【机器学习】自定义数据集 使用tensorflow框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测

一、使用tensorflow框架实现逻辑回归 1. 数据部分: 首先自定义了一个简单的数据集,特征 X 是 100 个随机样本,每个样本一个特征,目标值 y 基于线性关系并添加了噪声。tensorflow框架不需要numpy 数组转换为相应的张量&#xff0…...

.NET Core缓存

目录 缓存的概念 客户端响应缓存 cache-control 服务器端响应缓存 内存缓存(In-memory cache) 用法 GetOrCreateAsync 缓存过期时间策略 缓存的过期时间 解决方法: 两种过期时间策略: 绝对过期时间 滑动过期时间 两…...

GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比

GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比 目录 GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基于GA-CNN-LST…...

git Bash通过SSH key 登录github的详细步骤

1 问题 通过在windows 终端中的通过git登录github 不再是通过密码登录了,需要本地生成一个密钥,配置到gihub中才能使用 2 步骤 (1)首先配置用户名和邮箱 git config --global user.name "用户名"git config --global…...

《企业应用架构模式》笔记

领域逻辑 表模块和数据集一起工作-> 先查询出一个记录集,再根据数据集生成一个(如合同)对象,然后调用合同对象的方法。 这看起来很想service查询出一个对象,但调用的是对象的方法,这看起来像是充血模型…...

深入理解 C 语言函数指针的高级用法:(void (*) (void *)) _IO_funlockfile

深入理解 C 语言函数指针的高级用法 函数指针是 C 语言中极具威力的特性,广泛用于实现回调、动态函数调用以及灵活的程序设计。然而,复杂的函数指针声明常常让即使是有经验的开发者也感到困惑。本文将从函数指针的基本概念出发,逐步解析复杂…...

【JavaSE】图书管理系统

前言:为了巩固之前学习的java知识点,我们用之前学习的java知识点(方法,数组,类和对象,封装,继承,多态,抽象类,接口)来实现一个简单的图书管理系统…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Python如何给视频添加音频和字幕

在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...