From CORS multi-permission errors to Cloudflare cache hit issue

一次完整的 Nginx + FastAPI TTS 服务排错记录

From CORS multi-permission errors to Cloudflare cache hit issue

最近为了保证Worder的英文朗读质量,我部署一个 TTS(Text-to-Speech)API接口微服务,并通过 Cloudflare 做加速缓存。一路踩坑的经历非常典型:

  • CORS 报错 MultipleAllowOriginValues
  • Cloudflare 免费套餐下,页面规则/缓存规则无法缓存 API → cf-cache-status: BYPASS
  • 本地缓存 x-cache: HIT,但 CDN 不命中
  • blob URL 出现 206 Partial Content

这篇文章记录完整排查过程和最终可行方案。


1. 背景

  • 前端站点:https://worder.me
  • TTS API:https://worder.me/api/tts?text=xxx&lang=en&format=mp3
  • 后端:Python FastAPI
  • 前置:Nginx 反向代理 + Cloudflare CDN

目标:让 TTS 结果在 Cloudflare 全站缓存(HIT),减轻服务器压力


2. CORS 报错 —— MultipleAllowOriginValues

前端播放音频报错:

Cross-Origin Resource Sharing error: MultipleAllowOriginValues

原因

  • FastAPI 添加了 CORS 中间件
  • Nginx 同时设置了 CORS 响应头

浏览器收到两个 Access-Control-Allow-Origin,报错。

解决

  • FastAPI 注释掉 CORS 中间件
  • Nginx 统一管理 CORS:
location /api/ {
    set $cors_origin "";
    if ($http_origin ~* ^https://(www\.)?worder\.me$) {
        set $cors_origin $http_origin;
    }
    add_header Access-Control-Allow-Origin $cors_origin always;
    add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always;
    add_header Access-Control-Allow-Headers "Content-Type" always;
}

✅ CORS 问题解决。


3. 免费套餐缓存规则 / 页面规则无法解决 BYPASS

尝试:

  • 页面规则:*worder.me/api/tts*
  • 缓存规则:URI 路径开头 /api/tts

但是 Cloudflare 免费套餐的 动态 API + query 参数 仍然显示:

cf-cache-status: BYPASS

原因:

  • 免费套餐无法自定义 Cache Key
  • Cloudflare 默认不缓存带 query 的动态请求
  • 页面规则 / 缓存规则只能缓存静态文件或完全匹配规则

所以必须使用 Worker 强制缓存


4. Worker 强制缓存解决方案

下面是我实际使用的 Worker 代码:

export default {
  async fetch(request) {
    const url = new URL(request.url);

    // 只处理 TTS API
    if (!url.pathname.startsWith('/api/tts')) {
      return fetch(request);
    }

    // 转发到源站
    const response = await fetch(url.toString(), {
      method: request.method,
      headers: request.headers,
      cf: {
        cacheEverything: true,      // ← 关键:强制 Cloudflare 缓存非静态内容
        cacheTtl: 2592000           // ← 缓存 30 天
      }
    });

    // 创建新响应,移除 Set-Cookie
    const newHeaders = new Headers(response.headers);
    newHeaders.delete('Set-Cookie');

    // 统一返回缓存头
    newHeaders.set('Cache-Control', 'public, max-age=2592000, immutable');

    return new Response(response.body, {
      status: response.status,
      headers: newHeaders
    });
  }
}

说明

  • cacheEverything: true → 即使是动态 API 也会缓存
  • cacheTtl: 2592000 → 缓存 30 天
  • 删除 Set-Cookie → 防止 Cloudflare 拒绝缓存
  • 返回 Cache-Control → 告诉浏览器和 CDN 这是可缓存内容

✅ 使用 Worker 后,cf-cache-status: HIT 正常命中。


5. 验证缓存效果

第一次请求:

cf-cache-status: MISS

第二次请求:

cf-cache-status: HIT 🎉

浏览器端播放正常,TTS 服务器压力大幅下降。


6. blob URL + 206 正常现象

浏览器将音频流转成 blob,206 Partial Content = 支持 Range 请求,可拖动播放,与缓存无关。


7. 总结关键点

  1. CORS 报错 → Nginx + FastAPI 双重设置,保留一个
  2. 免费套餐缓存规则/页面规则 → 动态 API 仍 BYPASS
  3. Worker 强制缓存cacheEverything + cacheTtl + Cache-Control
  4. 删除 Set-Cookie → 避免缓存被拒
  5. blob + 206 → 正常现象

🎉 最终效果

  • CORS OK
  • Cloudflare HIT 成功
  • TTS 服务压力降低
  • 全球 CDN 加速
  • 浏览器播放顺畅

Read more

重新思考英语学习:从语序到沉浸式阅读

重新思考英语学习:从语序到沉浸式阅读

当我看到孩子们每天背单词表、做语法题、机械地重复"主谓宾"时,我常常在想:这真的是学习语言的正确方式吗? 想想我们是如何学会母语的:没有人在我们两岁时教我们"主语必须放在谓语前面",也没有人让我们背诵"苹果, 香蕉, 猫咪, 小狗"。我们是在真实的语境中,通过大量的听、说、模仿,自然而然地掌握了语言。 那么,为什么学英语就一定要反其道而行之呢? 当前英语学习的三大困境 1. 颠倒的学习顺序 传统路径: 语法规则 → 单词表 → 造句练习 → (很少有)真实交流 自然习得路径: 听说 → 理解 → 阅读 → 写作 → 归纳语法规则 这就像要求一个孩子先学习牛顿定律,才允许他学走路一样荒谬。语言是用来交流的工具,不是用来考试的学科。 2. 词汇学习的脱离语境 大多数学生的词汇学习模式:

By 王圆圆
Linux任务管理器 - top命令介绍

Linux任务管理器 - top命令介绍

前言 在Linux系统管理中,top命令是最常用的实时系统监控工具之一。它被称为Linux的"任务管理器",能够动态显示系统资源使用情况和进程信息。本文将详细介绍top命令(基于procps-ng 3.3.17版本)的常用功能和实用技巧。 一、top命令基础 1.1 启动top 在终端中直接输入以下命令即可启动top: top 默认情况下,top会每3秒刷新一次,显示系统摘要信息和进程列表。 1.2 界面布局解读 top的界面主要分为两部分: 系统摘要区(顶部) * 系统时间、运行时长、登录用户数 * 平均负载(1分钟、5分钟、15分钟) * 任务统计(总数、运行、休眠、停止、僵尸进程) * CPU使用率(用户态、系统态、空闲等) * 内存使用情况(物理内存和交换分区) 进程列表区(

By 王圆圆
写作建议

写作建议

核心原则 * 目标:用最少的脑力让读者理解,同时最大化阅读乐趣 关键技巧 明确你的写作场景 想清楚你在什么情境下写作——发短信、写学术论文、还是写演讲稿?不同场景需要不同风格。 清空"创意废水" 刚开始写作时,先把所有烂点子写出来。不要抵制它们,接受它们。排空废水后,好点子才会来。大多数人失败是因为没耐心清空废水。 写作障碍的解决方法 遇到障碍就继续写,即使写得很烂。你的潜意识会告诉你哪里不对。用错误的方式写完这一章,第二天你就会知道为什么错了。 句子长度 变化节奏 * 短句提神。中等句子保持节奏。长句子在读者休息好后使用,制造高潮感。 * 避免连续使用相似长度的句子——单调会让读者昏昏欲睡 * 大声朗读能帮你发现节奏问题 用词技巧 避免重复 * 连续两句以同一词开头:笨拙 * 三四句:怪异 * 一整段:让人抓狂 * 解决方法:改变句式结构 虚构写作 用词选择 主动

By 王圆圆
蠢蛋定律

蠢蛋定律

有句俗语说"损人不利己",这看似矛盾的行为模式,却在现实生活中屡见不鲜。1987年,意大利经济学家卡洛·M·奇波拉(Carlo M. Cipolla)在其著名短文《The Basic Laws of Human Stupidity》(人类愚蠢的基本法则)中,对这种现象进行了深刻剖析。他将人类行为分为四类:损人利己叫"坏",损人不利己叫"蠢",损己利人叫"傻",而双赢则是"聪明"。 愚蠢的本质:超越智力的行为缺陷 我们首先要厘清几个概念。愚蠢(stupid)不同于无知(ignorant)或笨拙(dumb)。无知是缺乏知识,

By 王圆圆