Next.js应用无法播放Flask API视频(返回206 PARTIAL CONTENT)
解决Flask提供MP4视频在Next.js中无法在线播放的问题
浏览器显示206 PARTIAL CONTENT本身是正常状态——在线视频播放依赖浏览器分段请求内容,206就是服务器返回部分内容的标准状态码。但视频无法播放的核心原因是你的Flask端点没有正确处理Range请求,浏览器分段请求时得不到符合要求的响应,导致视频加载失败。
当你把as_attachment设为True时,浏览器会触发完整文件下载流程,不需要分段请求,所以能正常下载,但无法实现在线播放。
解决方案:修改Flask端点支持Range请求
更新你的Flask接口代码,添加对Range分段请求的处理逻辑,返回浏览器需要的视频片段:
from flask import request, make_response, send_file import os @app.route("/uploads/signvideo/<video_id>", methods=['GET']) def getSignVideo(video_id): video_path = os.path.join('videos', video_id) videoFile = os.path.join(video_path, f'{video_id}_signVideo.mp4') absPath = os.path.abspath(videoFile) # 处理浏览器的Range分段请求 range_header = request.headers.get('Range') if range_header: file_size = os.path.getsize(absPath) # 解析Range头,格式示例:"bytes=0-1023" start, end = range_header.split('=')[1].split('-') start = int(start) if start else 0 end = int(end) if end else file_size - 1 chunk_size = end - start + 1 # 读取对应视频片段 with open(absPath, 'rb') as f: f.seek(start) video_chunk = f.read(chunk_size) # 构造符合要求的响应 response = make_response(video_chunk) response.headers['Content-Type'] = 'video/mp4' response.headers['Content-Length'] = str(chunk_size) response.headers['Content-Range'] = f'bytes {start}-{end}/{file_size}' response.status_code = 206 # 返回部分内容状态码 return response else: # 非分段请求时返回完整文件,开启条件请求优化缓存 return send_file(absPath, mimetype='video/mp4', conditional=True)
额外注意:跨域问题
如果你的Next.js应用和Flask API不在同一域名/端口下,必须配置Flask允许跨域请求,否则浏览器会阻止视频加载:
- 安装flask-cors依赖:
pip install flask-cors
- 在Flask应用中启用CORS:
from flask_cors import CORS app = Flask(__name__) # 生产环境建议指定允许的具体域名,这里先允许所有域名测试 CORS(app)
原理说明
在线播放大体积视频时,浏览器会自动发送Range请求分段获取内容,避免一次性加载全部100MB数据。修改后的代码会解析浏览器的Range请求头,返回对应的视频片段,并设置正确的响应头和状态码,让浏览器能正确拼接、缓存和播放分段视频。
内容的提问来源于stack exchange,提问作者yasith rangana
相关产品推荐
相关产品推荐

