JavaScript触发视频下载失败求助及尝试方案汇总
问题:JavaScript无法触发视频下载,仅能下载链接或直接播放
我需要点击按钮触发指定视频下载,已创建按钮并绑定函数,但只能下载视频链接而非视频本身。用外部下载器或拖拽URL到浏览器下载栏可正常下载,JavaScript实现却不行。
尝试过的解决方法
- 无Axios的简单Blob技术
const blob = new Blob([this.src_url], { type: 'video/mp4' }) const link = document.createElement('a') link.href = URL.createObjectURL(blob) link.download = this.src_url.replace( // 'https://redis-test.com/videos/', link.click() URL.revokeObjectURL(link.href)
执行结果:视频URL被下载为122字节的文本文件
- 使用File Saver包
var FileSaver = require('file-saver') console.log(this.src_url) var blob = new Blob([this.src_url], { type: 'video/mp4' }) FileSaver.saveAs(blob, 'hello world.mp4')
执行结果:同样下载的是URL文本而非视频
- 表单方法
<form method="get" action="file.doc"> <button type="submit">Download!</button> </form>
执行结果:视频在当前窗口直接播放
- 使用href的download属性
function download(url) { const a = document.createElement('a') a.href = url a.download = url.split('/').pop() document.body.appendChild(a) a.click() document.body.removeChild(a) }
执行结果:视频在当前窗口直接播放
- 直接点击链接方法
const link = document.createElement('a') link.href = url link.click()
执行结果:视频在当前窗口直接播放
- Axios默认配置+window.open
axios.defaults.withCredentials = true window.open( 'https://cdn.pixaandom_urlrbay.com/vieo/487508532/Woman%20-%2058142.mp4?rendition=source&expiry=1666842719&hash=7dd6d178d9dbbd8adaf68dafd80c9167e91eca21&download' )
执行结果:视频在新窗口直接播放
- Axios请求头添加Content-Disposition
axios .get( String(nuxtConfig.axios.mediaURL) + this.src_url.replace( 'https://redisrandom_url.com/videos/', '' ), { headers: { mode: 'no-cors', referrerPolicy: 'no-referrer', 'Content-Disposition': 'attachment; filename=Woman - 58142.mp4', Host: 'redis-nfs', 'User-Agent': 'PostmanRuntime/7.29.2', Accept: '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', Connection: 'keep-alive', Cookie: 'tk_or=%22https%3A%2F%2Fwww.google.com%2F%22; tk_lr=%22https%3A%2F%2Fwww.google.com%2F%22; _gcl_au=1.1.954672920.1660108804; _ga=GA1.2.1392122600.1660108808; _fbp=fb.1.1660108809200.1970395787', 'Upgrade-Insecure-Requests': '1', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-User': '?1', Pragma: 'no-cache', 'Cache-Control': 'no-cache', }, } ) .then((response) => { console.log(response) const url = window.URL.createObjectURL(new Blob([response.data])) const link = document.createElement('a') link.href = url link.setAttribute('download', 'title') document.body.appendChild(link) link.click() }) .catch((error) => { console.log('rex') })
执行结果:跨源请求被阻止,同源策略不允许读取目标资源,原因是缺少CORS头Access-Control-Allow-Origin,状态码200
可行解决方案
方案1:后端代理(推荐)
前端受同源策略限制,直接请求跨域视频资源会被拦截。可以在自己的后端服务器创建代理接口,由后端获取视频资源并添加Content-Disposition: attachment响应头后返回给前端,前端即可正常触发下载。
示例Node.js+Express代理实现:
const express = require('express'); const axios = require('axios'); const app = express(); app.get('/proxy-video', async (req, res) => { const videoUrl = req.query.url; try { const response = await axios.get(videoUrl, { responseType: 'stream' }); res.setHeader('Content-Disposition', `attachment; filename="${req.query.filename || 'video.mp4'}"`); res.setHeader('Content-Type', 'video/mp4'); response.data.pipe(res); } catch (err) { res.status(500).send('下载失败'); } }); app.listen(3000);
前端调用代码:
function downloadVideo(url, filename) { const a = document.createElement('a'); a.href = `/proxy-video?url=${encodeURIComponent(url)}&filename=${encodeURIComponent(filename)}`; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); }
方案2:检查URL强制下载参数
部分CDN或视频服务器支持通过URL参数(如?download、?force-download)强制触发下载。可确认目标服务器是否支持该逻辑,若支持则构造带参数的URL,结合a标签的download属性使用(需确保服务器允许跨域下载)。
方案3:正确获取视频二进制数据生成Blob(无跨域时可用)
之前的Blob方法错误地将URL字符串作为内容,导致下载文本。正确做法是先请求获取视频二进制数据,再生成Blob,但此方法仅在无跨域限制时生效:
async function downloadVideo(url, filename) { const response = await fetch(url, { credentials: 'include' }); const blob = await response.blob(); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = filename; a.click(); URL.revokeObjectURL(a.href); }
内容的提问来源于stack exchange,提问作者ash
相关产品推荐
相关产品推荐

