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

JavaScript触发视频下载失败求助及尝试方案汇总

问题:JavaScript无法触发视频下载,仅能下载链接或直接播放

我需要点击按钮触发指定视频下载,已创建按钮并绑定函数,但只能下载视频链接而非视频本身。用外部下载器或拖拽URL到浏览器下载栏可正常下载,JavaScript实现却不行。


尝试过的解决方法

  1. 无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字节的文本文件

  1. 使用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文本而非视频

  1. 表单方法
<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>

执行结果:视频在当前窗口直接播放

  1. 使用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)
}

执行结果:视频在当前窗口直接播放

  1. 直接点击链接方法
const link = document.createElement('a')
link.href = url
link.click()

执行结果:视频在当前窗口直接播放

  1. 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'
)

执行结果:视频在新窗口直接播放

  1. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:50:48