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

Ajax RSS与OpenWeatherMap缓存问题:GET改POST实现实时刷新咨询

解决RSS Feed和API实时刷新的缓存问题

Hey there! Let's break down why your RSS feeds and OpenWeatherMap API calls aren't refreshing in real-time, and how to fix it without switching to POST requests.

问题根源分析

你怀疑的浏览器缓存和GET请求机制确实是关键,但GET本身不是问题——真正的问题在于缓存策略以及你当前实现中nocache参数的生成逻辑有漏洞。目前你的nocache变量只在页面加载时生成一次,后续所有请求都会带上同一个随机值,浏览器还是会把它当成相同的请求缓存起来。另外,服务器端和PHP本身也可能缓存远程资源的响应,导致你看到旧内容。

为什么不需要改成POST

POST请求是用于提交数据到服务器的,而获取RSS/天气数据这类操作属于只读资源请求,完全符合GET的语义。强行改成POST不仅违反REST设计规范,还不一定能解决缓存问题——部分浏览器或代理服务器依然可能缓存POST请求的响应。所以我们应该聚焦在缓存控制上,而不是换请求方法。

具体修改方案

1. 前端代码优化

核心是每次发起请求时生成新的nocache值,并添加缓存控制请求头,确保浏览器不会复用缓存的响应:

<script>
function showRSS(str) {
  if (str.length === 0) {
    document.getElementById("rssOutput").innerHTML = "";
    return;
  }
  
  // 每次请求生成新的随机数,确保URL唯一
  const nocache = "&nocache=" + Math.random() * 1000000;
  let xmlhttp;

  if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
  } else {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  }

  // 添加缓存控制请求头,强制浏览器不缓存
  xmlhttp.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  xmlhttp.setRequestHeader("Pragma", "no-cache");

  xmlhttp.onreadystatechange = function() {
    if (this.readyState === 4 && this.status === 200) {
      document.getElementById("rssOutput").innerHTML = this.responseText;
    }
  };

  xmlhttp.open("GET", "getrss.php?q=" + str + nocache, true);
  xmlhttp.send();
}
</script>

修改点说明:

  • 将nocache的生成移到showRSS函数内部,确保每次调用都生成新的随机值
  • 添加Cache-Control和Pragma请求头,明确告诉浏览器不要缓存这个请求的响应

2. 后端PHP代码优化

需要在PHP响应中添加禁止缓存的头部,同时确保PHP加载远程RSS时不使用缓存:

<?php
// 首先发送禁止缓存的响应头,告诉浏览器和代理不要缓存这个页面
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
header("Pragma: no-cache"); // HTTP 1.0
header("Expires: 0"); // 过期时间设为过去,强制浏览器重新请求

// get the q parameter from URL
$q = $_GET["q"];

// find out which feed was selected
if($q=="Baden-Württemberg") {
  $xmlUrl = "https://verkehrsmeldungen.polizei-bw.de/TicRss.ashx?region=BW";
} elseif($q=="Bayern") {
  $xmlUrl = "http://www.br.de/verkehr-static/verkehrsmeldungen-rss.xml";
}

// 创建不缓存的流上下文,确保PHP拉取远程XML时获取最新内容
$context = stream_context_create([
  'http' => [
    'header' => "Cache-Control: no-cache, no-store, must-revalidate\r\n" .
                "Pragma: no-cache\r\n"
  ]
]);

$xmlDoc = new DOMDocument();
// 使用流上下文加载XML,绕过PHP的远程资源缓存
$xmlDoc->load($xmlUrl, LIBXML_NONET, $context);

//get elements from "<channel>"
$channel=$xmlDoc->getElementsByTagName('channel')->item(0);
$channel_title = $channel->getElementsByTagName('title')
->item(0)->childNodes->item(0)->nodeValue;
$channel_link = $channel->getElementsByTagName('link')
->item(0)->childNodes->item(0)->nodeValue;
$channel_desc = $channel->getElementsByTagName('description')
->item(0)->childNodes->item(0)->nodeValue;

//output elements from "<channel>"
echo("<p ><a href='" . $channel_link . "'>" . $channel_title . "</a>");
echo("<br>");
echo($channel_desc . "</p>");

//get and output "<item>" elements
$x=$xmlDoc->getElementsByTagName('item');
for ($i=0; $i<=5; $i++) {
  $item_title=$x->item($i)->getElementsByTagName('title')
  ->item(0)->childNodes->item(0)->nodeValue;
  $item_link=$x->item($i)->getElementsByTagName('link')
  ->item(0)->childNodes->item(0)->nodeValue;
  $item_desc=$x->item($i)->getElementsByTagName('description')
  ->item(0)->childNodes->item(0)->nodeValue;
  echo ("<p ><a href='" . $item_link . "'>" . $item_title . "</a>");
  echo ("<br>");
  echo ($item_desc . "</p>");
}
?>

修改点说明:

  • 添加了三个缓存控制响应头,彻底禁止浏览器和代理缓存PHP输出
  • 创建了带缓存控制头的流上下文,让PHP加载远程RSS时直接请求最新内容,而不是复用本地缓存

总结

通过调整前端的nocache生成逻辑和缓存请求头,再配合后端的缓存禁止响应头,就能解决实时刷新的问题,完全不需要切换到POST请求。这些修改既符合HTTP规范,又能确保每次请求都获取到最新的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:06:58