我遇到了一个问题,如果我使用jQuery的Get方法来获取一些内容,如果我点击回来,而不是实际返回历史记录中的一个页面,它会显示Ajax查询返回的内容。
有什么想法吗?
http://www.dameallans.co.uk/preview/allanian-society/news/56/Allanian-test
在上面的页面中,如果您在更改页面后单击后面时会注意到注释列表下方的分页,则会显示用于生成注释列表的HTML内容。
我注意到它并不总是这样做,但是如果您点击不同的页面几次并单击后退按钮,它只会在窗口中显示json文本而不是网站。
出于某种原因,这只会影响Chrome,因为IE和Firefox可以正常工作。
答案 0 :(得分:44)
确保您的AJAX请求使用完整HTML文档中的其他URL。 Chrome会缓存最近的请求,即使它只是部分请求。
答案 1 :(得分:18)
如果您使用jQuery和History API(或某些库如history.js),您应该将$ .getJSON更改为$ .ajax,并将缓存设置为false:
$.ajax({
dataType: "json",
url: url,
cache: false,
success: function (json) {...}
});
答案 2 :(得分:14)
实际上,这是根据规范而不是chrome问题的缓存系统的预期行为。缓存仅根据URL和请求方法(get,post,...)区分请求,而不是任何请求标头。
但是有一个 Vary 标头可以告诉浏览器在检查缓存时考虑一些标头。例如,通过向服务器响应中添加 Vary:X-Requested-With ,如果请求 X-Requested-With 标头发生更改,则浏览器会知道此响应会发生变化。或者,通过向服务器响应中添加 Vary:Content-Type ,如果请求 Content-Type 标题发生更改,则浏览器会知道此响应会发生变化。
您可以将此行添加到您的路由器以获取PHP:
header('Vary:X-Requested-With');
并在node.js中使用中间件:
app.use(function(req, res) {
res.header('Vary', 'X-Requested-With');
});
答案 3 :(得分:5)
您还可以在ajax网址的末尾添加随机值。这将忽略之前的chrome缓存并将请求新版本
url = '/?'+Math.random()
答案 4 :(得分:2)
只需将以下标题添加到响应标题:
Vary: Accept
答案 5 :(得分:1)
我无法为每个ajax请求提供不同的URL,因为它是一个ajax分页,声明标头上没有缓存没有做任何事情,所以我只在标题是针对ajax请求时在视图中包含一些javascript:
<script>
if (typeof jQuery == 'undefined') {
window.location = "<?php echo $this->here; ?>";
}
</script>
这是一个肮脏的技巧,但它的工作原理,如果ajax内容正常加载,容器已加载Jquery,所以它什么都不做。但是如果加载没有周围内容的ajax假设内容,Jquery就会丢失(至少在我的情况下),所以我重定向到当前页面,请求包含所有头文件和脚本的普通GET页面。
如果你把它放在页面的顶部,用户就不会注意到,因为它不会等到页面加载,一旦浏览器获得这4行就会重定向......
替换在这里; ?&GT;通过你APP中的当前网址,这是一个CakePhp 2.X
答案 6 :(得分:1)
在 2021 年的 Chrome 中仍然存在这个问题。
问题正在向与用户当前所在的 URL 相同的 URL 执行底层 ajax 请求。 我在 Symfony 工作,为我完成工作的完整修复是
$response->headers->addCacheControlDirective('no-cache', true);
$response->headers->addCacheControlDirective('max-age', 0);
$response->headers->addCacheControlDirective('s-maxage', 0);
$response->headers->addCacheControlDirective('must-revalidate', true);
$response->headers->addCacheControlDirective('no-store', true);
/**
* from https://stackoverflow.com/a/1975677/5418514
*
* The HTTP request header 'Accept' defines the Content-Types a client can process.
* If you have two copies of the same content at the same URL, differing only in Content-Type,
* then using Vary: Accept could be appropriate.
*/
$response->headers->set('Vary', 'Accept');
答案 7 :(得分:0)
@ abraham的回答是正确的。
我只是想为Rails发布一个解决方案:你需要的只是添加routes.rb
的不同路径。
在示例中,我有resource :people
,我想从ajax组成索引页面,其中一个是人员列表。直接的方法是创建index.js.erb
并使用url: people_path
通过ajax加载部分。但是这里出现了问题。
因此,对于Rails,它只需要添加一个不同的路径,比如
get 'people_list', to: 'people#index', as: :people_list, format: :js
答案 8 :(得分:0)
如果我想使用laravel控制器的索引方法返回html和json响应,则在端点的末尾添加一个get参数以传递浏览器缓存:
axios.get(url, {params: {ajax: 1}})