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
相关产品推荐
相关产品推荐

