web-dev-qa-db-fra.com

Chrome affiche une réponse ajax lorsque vous appuyez sur le bouton Précédent

J'ai rencontré un problème qui dit que si j'utilise la méthode Get de jQuery pour obtenir du contenu, si je clique en arrière, au lieu de revenir en arrière d'une page de l'historique, le contenu renvoyé par la requête Ajax s'affiche.

Des idées?

http://www.dameallans.co.uk/preview/allanian-society/news/56/Allanian-test

Sur la page ci-dessus, si vous utilisez la pagination située sous la liste des commentaires, vous remarquerez que lorsque vous cliquez en arrière après avoir modifié une page, le contenu HTML utilisé pour générer la liste des commentaires apparaît.

J'ai remarqué que ce n'est pas toujours le cas, mais si vous cliquez plusieurs fois sur une page différente, puis sur le bouton Précédent, il affiche simplement le texte json dans la fenêtre au lieu du site Web.

Pour une raison quelconque, cela n'affecte que Chrome car IE et Firefox fonctionnent correctement.

48
Gavin

Assurez-vous que vos demandes AJAX utilisent une URL différente des documents HTML complets. Chrome met en cache la requête la plus récente, même s’il s’agit d’une requête partielle.

https://code.google.com/p/chromium/issues/detail?id=108425

43
abraham

Juste au cas où vous utilisez jQuery avec History API (ou une bibliothèque telle que history.js), vous devez modifier $ .getJSON en $ .ajax avec le cache défini sur false:

$.ajax({
    dataType: "json",
    url: url,
    cache: false,
    success: function (json) {...}
});
16
Dmitrii Sorin

En fait, il s’agit du comportement attendu du système de mise en cache conformément aux spécifications et non d’un problème lié à Chrome. Le cache différencie uniquement les requêtes en fonction de l'URL et de la méthode de requête (get, post, ...), pas des en-têtes de requête. 

Mais il existe un en-tête Vary pour indiquer au navigateur de tenir compte de certains en-têtes lors de la vérification du cache. Par exemple, en ajoutant Vary: X-Requested-With à la réponse du serveur, le navigateur sait que cette réponse varie si request X-Requested-With header est modifié. Ou en ajoutant Vary: Content-Type à la réponse du serveur, le navigateur sait que cette réponse varie si request Content-Type en-tête est modifié.

Vous pouvez ajouter cette ligne à votre routeur pour PHP:

header('Vary:X-Requested-With');

Et utilisez un middleware dans node.js:

app.use(function(req, res) {
    res.header('Vary', 'X-Requested-With');
});
13
Ali

Vous pouvez également ajouter une valeur aléatoire à la fin de l'URL ajax. Cela ignorera le cache chromé précédent et demandera une nouvelle version

url = '/?'+Math.random()
5
astroanu

Il suffit d’ajouter l’en-tête suivant à l’en-tête Response :

Vary: Accept
2
Anis Hamidi

Je ne pouvais pas donner d'URL différentes pour chaque requête ajax car il s'agissait d'une pagination ajax, déclarant qu'aucun cache sur les en-têtes ne faisait rien. J'ai donc inclus un peu de javascript dans la vue uniquement lorsque les en-têtes étaient destinés à la requête ajax:

<script>
if (typeof jQuery == 'undefined') {
    window.location = "<?php echo $this->here; ?>";
}
</script>

C'est un sale coup, mais ça marche, si le contenu ajax est chargé normalement, le conteneur a Jquery chargé donc il ne fait rien. Mais si vous chargez le contenu supposé ajax sans le contenu environnant, Jquery est manquant (du moins dans mon cas), donc je redirige vers la page en cours demandant une page GET normale avec tous les en-têtes et scripts.

Si vous le mettez en haut de la page, l'utilisateur ne le remarquera pas car il n'attendra pas le chargement de la page, il le redirigera dès que le navigateur obtiendra ces 4 lignes ...

Remplacez ici; ?> Par l'URL actuelle dans votre APP, il s'agissait d'un CakePhp 2.X

1
Gestudio Cloud

La réponse de @ abraham est correcte. Je voulais simplement publier une solution pour Rails: il suffit simplement d’ajouter un chemin différent à routes.rb.

Par exemple, j'ai resource :people et je veux composer une page d'index à partir de pièces ajax. L'une de celles-ci est une liste de personnes. La méthode la plus simple consiste à créer index.js.erb et à charger une partie du fichier via ajax à l'aide de url: people_path. Mais voici le problème.

Donc, pour Rails, il suffit d’ajouter un autre itinéraire, comme

get 'people_list', to: 'people#index', as: :people_list, format: :js

0
atlascoder