一、问题概述
本人小破站于22年11月9号上线了每日新闻页面,当时是直接调用的 alapi 接口获取到的图片,这样的好处就是直接调用接口即可,不用自己爬取数据;就这样过了一年 23年11月15号我的同事告诉我,每日新闻挂了!没错免费套餐到期了!!本来我想着是再找一个可用的免费接口继续使用,但是免费接口的新闻质量并不高所以这个方案不是最优解。在和同事的探讨下发现可以自己爬取网页上的数据,后面发现这个方法可行就开搞了一开始是从网易新闻爬取内容,再生成图片贴到自己页面上。本以为事情到这里就结束了,可没过几天网易新闻爬不到数据了,然后就开始转为爬取知乎上的新闻。好在知乎上的内容是可以获取的,且每天更新,这就解决了数据来源这一问题。
数据来源虽然解决了,但还是存在其他问题:因为图片是自己爬取数据后生成的这就使得每次生成的图片文件名都是一样的,贴在每日新闻页面后,用户在浏览器加载过一次就会存在缓存后续访问时显示的就是缓存中的图片而不是最新图片了,每次想要获取最新的图片就需要手动按下 Ctrl + F5
来进行强制刷新(忽略缓存)。23年11月-24年3月这一期间都只有我和同事访问每日新闻界面,我们也都是每次强制刷新来获取新闻的并没有发现有什么不妥。问题转折点就在24年3月29号,我的大学同学访问每日新闻界面后提出说每次点开新闻都要手动刷新,用户体验不好,让我优化一下。没错,之前每日新闻页面最大问题就是每次访问都需要手动刷新。
二、解决过程
2.1 添加button
一开始想着是添加一个button,在点击button后执行重新加载页面的操作,查阅相关资料后发现可行,那就开搞:
<html>
<body>
<input id="input_username"></input>
</body>
<div style="text-align: center;">
<button style="background-color: #9a92b9; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 12px;" onclick="myFunction()">点击以获取最新简报</button>
</div>
<script>
function myFunction() {
location.reload();
}
</script>
</html>
这样每次就只需要点击这个button就可以刷新页面了,3月29号我以为问题解决了,我就直接提交更新了。3月30号,当我满心欢喜点击这个button的时候我发现 图片还是用的缓存中的图片!!!并没有获取最新的图片!!!此时我又一顿搜索发现 location.reload()
这个方法还可以传入参数 true
强制刷新(忽略缓存)或者 false
刷新(不忽略缓存)。于是我又带上参数 true
又试了一次,结果还是不行 因为查阅MDN文档发现,reload参数并未入规范,浏览器不一定生效。
2.2 模拟按键输入
第一种方法不能实现点击刷新后我又想到能不能通过JS模拟按键输入呢?我又搜索了一番发现在理论上也是可行的,但UIEvent.initUIEvent和KeyboardEvent.initKeyEvent()等方法在最新的Chrome浏览器中已废弃。按最新标准改用KeyboardEvent构造函数。
<html>
<body>
<input id="input_username"></input>
</body>
<div style="text-align: center;">
<button style="background-color: #9a92b9; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 12px;" onclick="myFunction()">点击以获取最新简报</button>
</div>
<script type="text/javascript">
function fireKeyEvent(element, evtType, keyChar) {
element.focus();
var KeyboardEventInit = {key:keyChar, code:"", location:0, repeat:false, isComposing:false};
var evtObj = new KeyboardEvent(evtType, KeyboardEventInit);
element.dispatchEvent(evtObj);
}
var objInput = document.getElementById("input_username");
objInput.addEventListener('keydown', function (e) {
objInput.value += e.key;
}, false);
function myFunction() {
fireKeyEvent(objInput,"keydown","Control");
// fireKeyEvent(objInput,"keydown","Ctrl");
fireKeyEvent(objInput,"keydown","F5");
}
</script>
</html>
发现也是可行的,但是需要获取一个元素来监听捕获键盘按下事件,上述编写完后我验证了一下发现在输入框是监听到了 Control
和 F5
的点击事件的,但是由于浏览器限制 好像这个方法并没有生效。
2.3 在URL后面添加查询参数
上述方法尝试过后发现都不能生效后我开始从另一个角度去解决这个问题:这个问题本质上就是每日新闻页面在加载过程中图片资源会使用缓存中的资源,既然这样那不让其从缓存中获取就可以了。于是我又开始百度(百度大法好)
查阅资料后我发现可以在图片的URL后面添加一个唯一的查询参数。这个查询参数可以是当前的时间戳,因为它在每次刷新页面时都会改变。这样,浏览器会认为这是一个新的URL,因此会重新获取图片,而不是从缓存中获取。类似这样:
< !DOCTYPE html >
<html>
<body>
<div id="imageDiv" style="text-align: center;"></div>
<script>
window.onload = function() {
var img = document.createElement('img');
img.src = "图片URL?timestamp=" + new Date().getTime();
document.getElementById('imageDiv').appendChild(img);
}
</script>
</body>
</html>
把每日新闻页面更新后发现每次访问都需要手动刷新这个问题已经解决啦~ ★,°:.☆( ̄▽ ̄)/$:.°★ 。撒花
举报了