2012-07-04 2 views
6

J'ai une page qui peut être consulté à URL/produits. Lorsque je le visite dans un navigateur, il répond par une page entière dans une mise en page. Voici un exemple simplifié des en-têtes de demande et le corps de réponse:Navigateur ne distingue pas un HTML partiel obtenu via AJAX et une page complète

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 

<layout> 
<products /> 
</layout> 

Lorsqu'un utilisateur fait une recherche les résultats des mises à jour via javascript AJAX. Les résultats sont rendus sans mise en page, car il faut du temps pour rendre et je ne ont pas besoin de toute façon:

Accept: */*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript 
X-Requested-With: XMLHttpRequest 

<products /> 

Donc, cela a bien fonctionné jusqu'à ce que j'ajouté la mise en cache Cache-Control: private, max-age=3600. Au départ, je pensais ajouter Vary: X-Requested-With en-tête et un navigateur distinguerait les deux réponses. Cependant, lorsque j'obtiens des produits via AJAX et que je consulte/products dans le navigateur, il affiche la réponse AJAX partielle.

Existe-t-il un moyen simple de résoudre ce problème?

P.S. J'utilise Ruby on Rails et jQuery si ça compte.

+2

Avez-vous essayé 'Vary: Accepter'? – regilero

+0

Oui, ça ne marche pas aussi. Je pense que le navigateur cache correctement les deux réponses. Mais à cause de Content-Type: text/html il les traite également et montre le dernier qui s'avère être partiel. –

+0

En fait, j'ai essayé de répondre avec JSON, et maintenant il montre JSON. Donc cela ne dépend pas de Content-Type: text/html. Je suis assez surpris que "Vary" n'ait aucun effet ici. –

Répondre

1

Demandez à votre appel Ajax d'utiliser une URL différente comme/products/partial.

+0

Cela ressemble à la seule solution pour l'instant. Mais cela signifie que je devrai modifier chaque URL sur le javascript côté client ce qui n'est pas très pratique. –

0

Vous devriez avoir une url diferent pour des résultats partiels (c.-à-? Partielle = oui ou quelque chose comme ça ...)

OU

vous pouvez obtenir la page entière via ajax et extraire seulement la partie vous voulez utiliser jquery.load().

$("#productsContainerHolder").load("/my/products/url #productsContainer", { myParam: "beer", myParam2: "cold"}); 

.load $ appellera votre serveur avec une méthode 'GET', récupérer tous les contenus, extraire le #productsContainer à partir de là et d'insérer sur "#productsContainerHolder"

<div id="productsContainerHolder"> 
    <div id="productsContainer> 
     ... 
    </div> 
</div> 
+0

Je ne rends pas la mise en page car cela prend beaucoup de temps de réponse. Extraire n'est pas vraiment un problème ici. –

0

Ce article par Steve Luscher décrit un cas similaire, le problème était plus intermittent que ce que vous décrivez. Les solutions proposées sont les suivantes:

  1. Annuler toutes les requêtes AJAX au moment où le formulaire est soumis

  2. utiliser une URL différente en fonction de la réponse que vous attendez

Steve est allé pour # 1 en utilisant cancel() sur les requêtes ajax.

Vous ne mentionnez pas ce que les navigateurs que vous avez utilisé, il y a une question relative navigateur here

+1

La première solution n'est pas vraiment applicable dans ma situation. Mais je suis heureux de voir d'autres personnes signaler le même problème. La question que vous avez liée ne semble pas être liée à moi, mais j'utilise Safari. Testé dans Firefox aussi. –

0

Utilisez Vary: Accept. Cela devrait fonctionner.

+0

J'ai essayé mais le problème est toujours là. Copier mes pensées d'en haut: Je pense que le navigateur cache correctement les deux réponses. Mais à cause de Content-Type: text/html il les traite également et montre le dernier qui s'avère être partiel. –

0

probablement le plus simple est de mettre à 'False' le paramètre 'cache' de la méthode Ajax de jquery. Il ajoutera automatiquement un horodatage à l'URI pour l'empêcher d'être mis en cache.

Cela peut être fait avec une large application l'extrait suivant:

$.ajaxSetup({ 
    cache: false 
}); 

Si le cache est importante même pour la demande dynamique, vous pouvez vous générer l'horodatage en fonction de la date ainsi que l'heure.

0

Essayez d'envoyer must-revalidate au lieu de private (ce qui est plus pour proxy).

Cache-Control: max-age=3600, must-revalidate 

Je recommande de lire cet article: http://www.mnot.net/cache_docs/ cela pourrait aider. Et également utiliser l'outil http://redbot.org/ de Mark pour tester vos résultats pour éliminer votre machine locale ou isp ou quoi que ce soit.

Questions connexes