You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

前端使用YouTube Data API v3上传视频遇CORS拦截问题求助

解决前端JS调用YouTube Data API可恢复上传的CORS问题

核心原因

YouTube Data API的可恢复上传流程中,POST请求返回的上传URL(Location头)指向Google Cloud Storage(GCS)资源,而这些GCS URL默认不允许前端直接发起跨域PUT请求——哪怕文档说明API支持CORS,最终的上传节点并不支持前端跨域写入。另外你步骤2用mode:'no-cors'会导致响应变成不透明(opaque),大概率拿到的上传URL不完整或无效,进一步加剧步骤3的问题。

可行解决方案

1. 强制使用后端代理(推荐,无限制)

前端不要直接和YouTube的上传URL交互,所有上传请求通过自有后端服务转发:

  • 前端完成OAuth授权拿到access token后,调用后端接口,由后端发起POST请求获取上传URL
  • 前端将视频分块发送给后端,后端代为向YouTube的上传URL发起PUT请求(后端不受浏览器CORS规则限制)

前端代码示例(传块到后端):

// 前端分块上传到自有后端
async function sendChunkToBackend(chunk, uploadUrl, totalSize) {
  const start = chunk.offset;
  const end = start + chunk.size - 1;
  const response = await fetch('/api/youtube-upload-proxy', {
    method: 'PUT',
    headers: {
      'X-Upload-Url': uploadUrl,
      'Content-Range': `bytes ${start}-${end}/${totalSize}`,
      'Content-Type': 'video/mp4' // 替换为你的视频MIME类型
    },
    body: chunk.data,
    duplex: 'half'
  });

  if (!response.ok) {
    throw new Error(`上传块失败: ${response.statusText}`);
  }
  return response;
}

后端代理示例(Node.js/Express):

// 后端转发PUT请求到YouTube上传URL
app.put('/api/youtube-upload-proxy', async (req, res) => {
  const uploadUrl = req.headers['x-upload-url'];
  const forwardHeaders = {
    'Content-Range': req.headers['content-range'],
    'Content-Type': req.headers['content-type']
  };

  try {
    const youtubeRes = await fetch(uploadUrl, {
      method: 'PUT',
      headers: forwardHeaders,
      body: req.body
    });

    res.status(youtubeRes.status).send(await youtubeRes.text());
  } catch (err) {
    res.status(500).send(`代理失败: ${err.message}`);
  }
});

2. 修复步骤2的CORS问题(仅解决POST请求,仍无法绕开PUT的CORS限制)

如果想尝试前端直接处理步骤2,必须去掉mode:'no-cors',并确保:

  • 在Google Cloud Console的OAuth 2.0客户端ID配置中,将你的前端域名添加到已授权的JavaScript来源列表
  • POST请求的Header完全符合要求,示例如下:
async function getValidUploadUrl(accessToken, videoMeta) {
  const res = await fetch('https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
      'X-Upload-Content-Type': 'video/mp4' // 匹配视频实际类型
    },
    body: JSON.stringify(videoMeta)
  });

  if (!res.ok) throw new Error(`获取上传URL失败: ${res.status}`);
  return res.headers.get('Location');
}

注意:即使步骤2的CORS解决了,步骤3的PUT请求依然会被浏览器拦截,因为GCS的上传URL不支持前端跨域PUT,最终还是得走后端代理。

总结

YouTube可恢复上传的最终上传节点不支持前端跨域写入,后端代理是唯一可靠的解决方案。步骤2的CORS问题本质是OAuth客户端配置错误,不要用no-cors绕过,否则会导致后续流程失效。

内容的提问来源于stack exchange,提问作者pedrobroese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:53:11