使用replaceChild时出现Replit「Not Found」问题,求技术排查
问题:运行代码出现Replit「Not Found」页面,怀疑与
replaceChild相关 我是JavaScript新手,正在做展示YouTube最新上传视频的功能,代码参考了网络资料,现在运行时出现Replit「Not Found」页面,怀疑和replaceChild方法有关,麻烦帮忙排查问题。
相关代码
videos.js
function httpGet(theUrl) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", theUrl, false); // false for synchronous request xmlHttp.send(null); return xmlHttp.responseText; } var videosT = httpGet("https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=abcxyz&maxResults=6&order=date&type=video&key=abcxyz"); const videos = JSON.parse(videosT); for (let step = 0; step < 6; step++) { fetch('js/videos.html') .then(res => res.text()) .then(text => { let oldelem = document.getElementById("vid_" + step); let newelem = document.createElement("div"); newelem.innerHTML = text; oldelem.parentNode.replaceChild(newelem, oldelem); }) }
index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Ashk3000</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous"> <link rel="stylesheet" href="style.css"> </head> <body class="d-flex flex-column" viewport-fit=cover> <!-- Navbar --> <script id="navbar_placeholder" src="js/nav.js" page="home"></script> <!-- Headers --> <div class="d-none d-lg-block shadow bg-body border border-5 border-top-0 rounded-bottom w-75 position-relative start-50 translate-middle-x mb-5"> <div class="container-fluid py-5"> <h1 class="display-5 fw-bold">Home</h1> </div> </div> <div class="d-lg-none shadow-sm bg-body border-bottom border-5 w-100 position-relative mb-3"> <div class="container-fluid py-5"> <h1 class="display-5 fw-bold">Home</h1> </div> </div> <!-- Start --> <div class="container"> <div class="row"> <div id="vid_0"></div> <div id="vid_1"></div> <div id="vid_2"></div> <div class="w-100"></div> <div id="vid_3"></div> <div id="vid_4"></div> <div id="vid_5"></div> </div> </div> <script src="js/videos.js"></script> <!-- Footer --> <div class="mt-auto"></div> <script id="footer_placeholder" src="js/footer.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script> </body> </html>
videos.html
<div class="card col" style="width: 18rem;"> <img src="" id="thumbnail" class="card-img-top" alt=""> <div class="card-body"> <h5 id="title" class="card-title">Title</h5> <a href="#" id="button" class="btn btn-primary stretched-link">Watch</a> </div> </div>
问题排查
- fetch路径错误:Replit的「Not Found」大概率是因为
fetch('js/videos.html')找不到文件——要么文件不在js目录,要么路径大小写不匹配(Replit区分大小写)。 - 同步XHR阻塞页面:你用了同步
XMLHttpRequest,这种方式会卡住页面渲染,可能导致加载异常,现代浏览器也不推荐使用。 replaceChild的潜在报错:如果DOM还没加载完成就执行脚本,oldelem会是null,调用oldelem.parentNode.replaceChild会抛出错误,但这只会在控制台报错,不会直接显示「Not Found」。- 未使用API数据:你请求了YouTube API但没把视频标题、缩略图等数据插入到模板里,功能没落地。
修复方案
1. 确认文件路径
检查videos.html是否在js文件夹下,Replit左侧文件树可以查看。如果路径不对,调整fetch的参数,比如文件和videos.js同目录就写./videos.html。
2. 替换同步XHR为异步fetch
把同步请求改成异步,避免阻塞页面:
async function fetchYouTubeVideos() { try { const response = await fetch('https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=abcxyz&maxResults=6&order=date&type=video&key=abcxyz'); if (!response.ok) throw new Error('API请求失败'); return await response.json(); } catch (err) { console.error(err); return { items: [] }; } }
3. 结合API数据渲染模板,避免报错
只请求一次模板,再结合API数据渲染,同时判断元素是否存在:
// 先获取模板,避免重复请求 fetch('js/videos.html') .then(res => { if (!res.ok) throw new Error('模板文件不存在'); return res.text(); }) .then(template => { // 获取YouTube数据 return fetchYouTubeVideos().then(videos => ({ template, videos })); }) .then(({ template, videos }) => { // 遍历视频数据 videos.items.forEach((item, step) => { const oldElem = document.getElementById(`vid_${step}`); if (!oldElem) return; // 元素不存在就跳过,防止报错 const newElem = document.createElement('div'); newElem.innerHTML = template; // 填充视频信息 const thumbnail = newElem.querySelector('#thumbnail'); const title = newElem.querySelector('#title'); const button = newElem.querySelector('#button'); thumbnail.src = item.snippet.thumbnails.medium.url; title.textContent = item.snippet.title; button.href = `https://www.youtube.com/watch?v=${item.id.videoId}`; // 替换元素 oldElem.parentNode.replaceChild(newElem, oldElem); }); }) .catch(err => { console.error('加载出错:', err); // 可以在这里给页面加错误提示,比如显示"视频加载失败" });
4. 删除旧的同步XHR函数
不再需要httpGet函数,直接用上面的异步代码替代。
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

