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

Chrome扩展下载TikTok视频遇403错误及视频格式异常问题求助

解决TikTok Chrome扩展下载视频403错误及格式问题

问题根源

你遇到的403错误是TikTok服务器的防盗链机制导致的——你的fetch请求缺少浏览器正常访问时携带的关键请求头,服务器拒绝返回真实视频数据;下载的文件因为是错误的响应内容(比如HTML错误页),所以播放器提示格式错误。另外当前代码还存在DOM监听未生效、可能获取到Blob临时URL而非真实视频地址的问题。

可行解决步骤

1. 为Fetch请求添加必要验证头

TikTok的视频接口需要验证请求是否来自合法的页面会话,必须携带Referer、Cookie和User-Agent这几个请求头,模拟浏览器的正常请求:

修改downloadVideo函数中的fetch调用:

function downloadVideo(url) {
  fetch(url, {
    headers: {
      'Referer': window.location.href,
      'Cookie': document.cookie,
      'User-Agent': navigator.userAgent
    }
  })
  .then(response => {
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    return response.blob();
  })
  .then(blob => {
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `tiktok-video-${Date.now()}.mp4`;
    link.type = 'video/mp4';
    link.click();
    URL.revokeObjectURL(link.href);
  })
  .catch(error => {
    console.error('Error downloading the video:', error);
  });
}

2. 确保获取真实的视频远程地址

页面中的<video>标签的src可能是Blob格式的临时URL(并非真实的TikTok服务器地址),需要优先获取真实的视频源:

修改获取视频地址的逻辑:

// 替换原获取videoUrl的代码
const videoElement = video.querySelector('video');
let videoUrl = videoElement.currentSrc || videoElement.src;

// 如果是Blob URL,尝试从source标签获取真实地址
if (videoUrl.startsWith('blob:')) {
  const sourceTag = videoElement.querySelector('source');
  if (sourceTag) {
    videoUrl = sourceTag.src;
  } else {
    // 备用方案:从TikTok页面的全局状态提取(注意该方式可能随页面更新失效)
    const initialState = window.__INITIAL_STATE__;
    if (initialState && initialState.itemInfo?.itemStruct?.video?.playAddr) {
      videoUrl = initialState.itemInfo.itemStruct.video.playAddr;
    }
  }
}

3. 修复DOM监听逻辑,确保新加载视频添加按钮

原代码中observeDOMChangesDownloadButton函数里的addVideoDownload()被注释,导致滚动加载新视频时不会生成下载按钮,同时要避免重复添加按钮:

function observeDOMChangesDownloadButton() {
  const observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
      if (mutation.type === 'childList' || mutation.type === 'subtree') {
        addVideoDownload();
      }
    });
  });

  observer.observe(document.body, {
    childList: true,
    subtree: true,
  });
}

// 修改addVideoDownload函数,添加重复检查
function addVideoDownload() {
  const videoElements = document.querySelectorAll('.tiktok-1soki6-DivItemContainerForSearch:not([data-has-download-btn])');
  videoElements.forEach(function (video) {
    // 标记已添加按钮的容器,避免重复操作
    video.setAttribute('data-has-download-btn', 'true');
    
    const downloadButton = document.createElement('a');
    downloadButton.href = '#';
    downloadButton.classList.add('download-video-button');
    downloadButton.innerHTML = '<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/9d/Circle-icons-download.svg/1200px-Circle-icons-download.svg.png" alt="Download">';
    
    // 点击事件逻辑
    downloadButton.addEventListener('click', function(event) {
      event.preventDefault();
      event.stopPropagation();

      const videoElement = video.querySelector('video');
      let videoUrl = videoElement.currentSrc || videoElement.src;

      if (videoUrl.startsWith('blob:')) {
        const sourceTag = videoElement.querySelector('source');
        if (sourceTag) {
          videoUrl = sourceTag.src;
        }
      }

      downloadVideo(videoUrl);
    });

    video.appendChild(downloadButton);
  });
}

4. 更新扩展Manifest权限

在manifest.json中添加必要的权限,确保扩展可以访问TikTok的Cookie和资源:

{
  "permissions": [
    "cookies",
    "*://*.tiktok.com/*"
  ],
  "host_permissions": [
    "*://*.tiktok.com/*",
    "*://*.tiktokcdn.com/*"
  ]
}

补充说明

  • TikTok的页面结构和API会频繁更新,若后续再次出现问题,需要检查选择器(如.tiktok-1soki6-DivItemContainerForSearch)是否失效,或者全局状态的字段是否变更。
  • 部分地区的TikTok可能有额外的验证机制,若仍无法下载,可尝试在fetch中添加Origin头,或使用扩展的webRequestAPI拦截视频请求直接获取地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:57:04