使用HLS.js流式播放YouTube M3U8/TS文件时如何绕过CORS限制?
解决Flask应用中YouTube HLS播放的CORS问题
核心原因
Google Video的.m3u8和.ts资源服务器未配置Access-Control-Allow-Origin响应头,浏览器同源策略会阻止前端直接请求跨域资源。而VLC、Safari不受浏览器同源策略限制,因此能正常播放。
方案1:Flask反向代理(生产可用)
通过Flask搭建代理层,让前端请求你的Flask服务器,再由Flask转发请求到Google Video并返回资源,绕开跨域限制。步骤如下:
- 安装依赖:
pip install flask requests
- 给Flask应用添加代理路由:
from flask import Flask, request, Response import requests import re app = Flask(__name__) # 代理m3u8和ts资源 @app.route('/proxy/<path:resource_url>') def proxy_resource(resource_url): full_url = f"https://{resource_url}" try: resp = requests.get(full_url, stream=True) # 复制响应头并添加CORS允许 headers = dict(resp.headers) headers['Access-Control-Allow-Origin'] = 'http://127.0.0.1:5500' # 生产环境替换为你的前端域名 # 处理m3u8文件,替换内部ts链接为代理地址 content = resp.content if resource_url.endswith('.m3u8'): content = re.sub( r'https://([a-z0-9\-]+\.googlevideo\.com)/', r'/proxy/\1/', content.decode('utf-8') ).encode('utf-8') return Response(content, headers=headers, status=resp.status_code) except Exception as e: return str(e), 500 # 获取YouTube视频的代理m3u8链接 @app.route('/get-proxied-hls/<video_id>') def get_proxied_hls(video_id): import yt_dlp ydl_opts = { 'format': 'best', 'quiet': True, 'skip_download': True, } with yt_dlp.YoutubeDL(ydl_opts) as ydl: info = ydl.extract_info(f'https://www.youtube.com/watch?v={video_id}', download=False) m3u8_url = next((f['url'] for f in info['formats'] if f['protocol'] == 'm3u8_native'), None) if m3u8_url: # 替换为代理地址 return m3u8_url.replace('https://', '/proxy/') return "No m3u8 URL found", 404 if __name__ == '__main__': app.run(debug=True, port=5000)
- 前端调整:
将播放器的源地址改为Flask返回的代理链接(例如http://127.0.0.1:5000/proxy/manifest.googlevideo.com/.../index.m3u8),即可通过代理加载所有资源。
方案2:临时开发调试方案(禁用浏览器CORS)
仅用于本地测试,绝对不能用于生产环境:
- Chrome:关闭所有窗口后,通过命令行启动:
# Windows chrome.exe --disable-web-security --user-data-dir="C:/ChromeDevSession" # Mac open -a Google\ Chrome --args --disable-web-security --user-data-dir="/tmp/ChromeDevSession"
- Firefox:安装CORS Everywhere类插件,临时开启跨域允许。
注意事项
- 生产环境需将
Access-Control-Allow-Origin设置为具体的前端域名,避免使用*带来安全风险。 - yt-dlp获取的m3u8链接有过期时间,需添加逻辑定期刷新链接。
- 代理路由需完善错误处理,避免请求失败导致前端崩溃。
内容的提问来源于stack exchange,提问作者Yousseif Muhammed
相关产品推荐
相关产品推荐

