Web Archive页面中Fetch API请求URL被错误拼接的解决咨询
解决Web Archive历史页面中Fetch请求URL被错误拼接的问题
问题原因
Web Archive的Wayback Machine会对存档页面注入脚本,自动重写页面内的所有网络请求(包括Fetch、XHR),将请求URL拼接至Web Archive的基准地址后,导致本地后端的请求被错误转发。即使使用完整绝对URL,也会被其重写机制篡改。
解决方案
1. 禁用Wayback的Fetch重写
Wayback提供了内部变量__wb_disable_fetch,设置后可阻止其拦截并重写Fetch请求:
// 先禁用重写 window.__wb_disable_fetch = true; // 再发送请求 fetch('http://localhost:5000/write', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(yourProcessedDomData) }) .then(res => res.text()) .then(console.log) .catch(console.error);
2. 改用XMLHttpRequest替代Fetch
若上述方法无效,可尝试使用XHR发起请求——Wayback的重写机制对XHR的拦截力度较弱:
const xhr = new XMLHttpRequest(); xhr.open('POST', 'http://localhost:5000/write', true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = () => { xhr.status >= 200 && xhr.status < 300 ? console.log(xhr.responseText) : console.error('请求失败'); }; xhr.onerror = () => console.error('网络错误'); xhr.send(JSON.stringify(yourProcessedDomData));
3. 通过独立iframe上下文发起请求
创建指向本地空白页面的iframe,在iframe的独立上下文中发送请求,完全避开Wayback的页面环境干扰:
const iframe = document.createElement('iframe'); iframe.style.display = 'none'; // 本地后端需提供一个空白页面接口 iframe.src = 'http://localhost:5000/blank'; document.body.appendChild(iframe); iframe.onload = () => { iframe.contentWindow.fetch('http://localhost:5000/write', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(yourProcessedDomData) }) .then(res => res.text()) .then(data => { console.log(data); document.body.removeChild(iframe); }) .catch(err => { console.error(err); document.body.removeChild(iframe); }); };
后端CORS配置注意事项
由于Web Archive页面为HTTPS协议,本地后端为HTTP,会存在跨域问题,需在Node.js后端中配置CORS:
const express = require('express'); const cors = require('cors'); const app = express(); // 开发环境允许所有来源,生产环境请限制特定域名 app.use(cors({ origin: '*' })); app.use(express.json()); // 写入文件接口 app.post('/write', (req, res) => { const fs = require('fs'); fs.writeFileSync('dom-data.json', JSON.stringify(req.body)); res.send('数据保存成功'); }); // 读取文件接口 app.get('/read', (req, res) => { const fs = require('fs'); const data = fs.readFileSync('dom-data.json'); res.json(JSON.parse(data)); }); // 空白页面接口(用于iframe方案) app.get('/blank', (req, res) => { res.send('<html><body></body></html>'); }); app.listen(5000, () => console.log('服务运行在5000端口'));
内容的提问来源于stack exchange,提问作者Mena Lateaf
相关产品推荐
相关产品推荐

