news 2026/9/12 20:50:34

cf前端直接上传

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
cf前端直接上传

之前是后端上传,现在计划改前端直接传。

使用直接创建者上传还无需中间存储桶,也能省去相关的存储/流出成本

参考文档

Presigned URLs · Cloudflare R2 docs

https://developers.cloudflare.com/r2/api/s3/presigned-urls/ 有php版本sdk

https://developers.cloudflare.com/r2/examples/aws/aws-sdk-php/#generate-presigned-urls

生成秘钥地址

https://developers.cloudflare.com/r2/api/tokens/

示例代码

Route::post('/upload/video/presign', [UploadController::class, 'videoPresign']);

/**
* 签发视频直传预签名 URL(前端拿 upload_url 直接 PUT 到 R2,文件不过服务端)。
*
* 入参:filename(必填)、content_type、dir、expires
*/
public function videoPresign(Request $request): Response
{
return $this->run($request, function () use ($request): Response {
$payload = $this->readParams($request);
$signed = Container::get(UploadService::class)->createVideoUploadUrl([
'filename' => trim((string) ($payload['filename'] ?? '')),
'content_type' => trim((string) ($payload['content_type'] ?? '')),
'dir' => trim((string) ($payload['dir'] ?? '')),
'expires' => $payload['expires'] ?? null,
]);

return success($signed, 'success');
});
}

/**
* JSON body 优先,表单提交时回退到 post 参数。
*
* @return array<string, mixed>
*/
private function readParams(Request $request): array
{
if (str_contains(strtolower((string) $request->header('content-type', '')), 'application/json')) {
return $this->readPayload($request);
}

$post = $request->post();

return is_array($post) ? $post : [];
}

/**
* 生成 Cloudflare R2 视频直传预签名 URL。
*
* 后端只负责签发,文件不经过服务端;前端拿到 upload_url 后用 PUT 直传到 R2。
*
* @param array<string, mixed> $options 支持 filename / content_type / dir / expires
* @return array<string, mixed>
*/
public function createVideoUploadUrl(array $options = []): array
{
$filename = trim((string) ($options['filename'] ?? ''));
if ($filename === '') {
throw ValidationException::single('filename', 'required', 'filename is required.');
}

$contentType = $this->resolveVideoMimeType($options, $filename);
$r2 = $this->resolveR2Config($this->cloudflareConfig());
$expires = $this->resolveExpires($options, $r2);
$key = $this->buildVideoKey($options, $r2, $filename, $contentType);
$objectUrl = sprintf('https://%s/%s', $this->r2Host($r2), $key);
$presigner = new S3Presigner(
(string) $r2['access_key_id'],
(string) $r2['secret_access_key'],
trim((string) ($r2['region'] ?? 'auto')) ?: 'auto'
);

$requestTime = new DateTimeImmutable('now', new DateTimeZone('UTC'));
$signedHeaders = $this->shouldSignContentType($r2) ? ['Content-Type' => $contentType] : [];
$uploadUrl = $presigner->presign('PUT', $objectUrl, $signedHeaders, $expires, $requestTime);

return [
'upload_url' => $uploadUrl,
'method' => 'PUT',
// 前端上传时必须原样带上这些请求头,否则签名校验会失败。
'headers' => ['Content-Type' => $contentType],
'key' => $key,
'url' => $this->resolveVideoReadUrl($presigner, $r2, $objectUrl, $key, $expires, $requestTime),
'expires_in' => $expires,
'expires_at' => gmdate('Y-m-d\TH:i:s\Z', (int) $requestTime->getTimestamp() + $expires),
];
}

方案 B:绑定自定义域名 video.com(生产推荐)
当前 video.com 指向你的应用服务器,需要修改 DNS,把它指向 R2。
步骤 1:R2 桶内绑定自定义域名
1.Cloudflare 控制台→R2→桶 assets-video→Settings→Custom Domains
2.点击Add custom domain
3.输入域名:video.com
4.选择:Enable public access(开启公开访问)
5.Cloudflare 会给出 DNS 记录提示,需要在域名 DNS 面板添加一条 CNAME 记录
步骤 2:修改 DNS(关键!)
域名 video.com的 DNS 记录:
。删除原有 video.com 指向你应用的 A/AAAA 记录
。新增一条 CNAME 记录:
Name: video
Type: CNAME
Target:<你的桶ID>.r2.cloudflarestorage.com
TTL:自动
注意:这个 CNAME 是 Cloudflare 提供的,不要填 IP。
步骤 3:等待 DNS 生效(几分钟~半小时)
等待 SSL 证书自动颁发完成。
步骤 4:设置环境变量
env ^

R2 PUBLIC URL=https://video.com
播放地址格式
plaintext
印 、7
https://video.com/videos/abc123.mp4

这条链路是这样的:

你手动加的 CNAME(upsell → <bucket>.r2.cloudflarestorage.com)✅ 已生效(DNS 查询确认)
但 R2 的 S3 端点只认在「桶 → Custom Domains」里注册过的域名。没注册的话,R2 不认识 Host: video.com 这个请求
结果:Cloudflare 边缘收到请求后按 zone 的常规路由走(CF-RAY ...-LAX 证明到了 Cloudflare),最终落到你的 Ouyify 应用,返回了那个 1972 字节的 404 HTML
结论:手动 CNAME 方式对 R2 是无效的,必须在桶的 Custom Domains 功能里完成绑定——它会自动创建特殊的 DNS 记录(不需要你手动加)、签发证书、并注册路由。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 20:47:49

在 Blender 中启用 AMD GPU 加速:ZLUDA 完整指南

在 Blender 中启用 AMD GPU 加速&#xff1a;ZLUDA 完整指南 【免费下载链接】ZLUDA CUDA on non-NVIDIA GPUs 项目地址: https://gitcode.com/GitHub_Trending/zl/ZLUDA 在 RX 580 上&#xff0c;同一份 Cycles 室内场景渲染任务&#xff0c;纯 CPU 需要约 3 小时&…

作者头像 李华
网站建设 2026/9/12 20:45:20

Windows 电脑微信文件保存位置和误删恢复排查

Windows 电脑上排查微信文件丢失&#xff0c;先确认文件来源和存储边界&#xff1a;个人微信通常看 WeChat Files&#xff0c;企业微信通常看 WXWork&#xff1b;实际路径以客户端设置中的存储位置为准。误删后不要继续向原分区写入数据。本文按可验证路径、系统回收入口、备份…

作者头像 李华
网站建设 2026/9/12 20:43:55

ClawX for Mac:AI数字员工搭建工具全解析

1. ClawX for Mac 项目概述OpenClaw 官方桌面客户端 ClawX 是2026年3月推出的新一代AI数字员工搭建工具&#xff0c;专为Mac用户优化设计。作为长期关注效率工具的技术博主&#xff0c;我第一时间测试了这款软件&#xff0c;发现它确实如宣传所说能在5分钟内完成从安装到配置的…

作者头像 李华
网站建设 2026/9/12 20:43:11

Karpathy式LLM工程实践:用claude.md与Claude Code构建可审计工作流

1. 项目概述&#xff1a;这不是一份“技能清单”&#xff0c;而是一份LLM时代工程师的生存地图你点开这个标题——“andrej-karpathy-skills”——大概率不是想查Andrei Karpathy的LinkedIn履历&#xff0c;也不是要背诵他2017年那场经典演讲里的金句。你真正想问的是&#xff…

作者头像 李华