Vérifiez si Javascript est activé (Serverside) avec Rails

Comment vérifier si javascript est activé dans Rails? Pour que je puisse faire quelque chose comme ça dans les points de vue:

<div> <% if javascript_enabled? %> <p>Javascript Enabled!</p> <%- else -%> <p>No Javascript</p> <%- end -%> </div> 

Vous pouvez le détecter, mais ce n'est pas joli.

D'abord, vous avez besoin d'un nouveau contrôleur avec une action qui met à jour un délai d'attente dans la session:

 class JavascriptController < ApplicationController def confirm session[:javascript_updated] = Time.now end end 

Ensuite, vous devez inclure une action javascript dans toutes vos pages afin que cette action de contrôleur soit appelée sur chaque chargement de page. Le moyen le plus simple est de l'inclure sur un fichier "javascript-confirm.js" inclus dans votre mise en page (sur cet exemple particulier, j'ai utilisé le mot Ajax.Request de Prototype, donc vous devez l'avoir inclus sur vos javascripts aussi):

 function confirmJavascript() { // Assuming you are using Prototype new Ajax.Request('/JavascriptController/confirm'); } myTimeoutFunction(); setInterval(myTimeoutFunction, 10000); // invoke each 10 seconds 

Cela implique l'action de confirmation dans toutes vos vues de page. Enfin, vous devez contrôler la durée écoulée depuis votre dernière confirmation dans votre contrôleur d'application.

 class ApplicationController < ActionController::Base JAVASCRIPT_TIME_LIMIT = 10.seconds before_filter :prepare_javascript_test private def prepare_javascript_test if (session[:javascript_updated].blank? or Time.now - session[:javascript_updated] > ApplicationController::JAVASCRIPT_TIME_LIMIT) @javascript_active = true else @javascript_active = false end end end 

Vous aurez maintenant une variable appelée @javascript_active dans tous vos contrôleurs.

Il devrait fonctionner même lorsque l'utilisateur active / désactive le javascript, avec une précision de 10 secondes. Cela pourrait ne pas fonctionner si certaines de vos pages prennent plus de 10 pages à charger (c'est-à-dire avec beaucoup d'images). Augmentez le délai dans cette affaire (sur la contrôleur d'application et votre javascript)

Avertissement: Je n'ai pas testé ce code, certains bogues risquent peut-être, mais cela devrait vous indiquer la bonne direction.

Si c'est tout ce que vous voulez faire, il est préférable de mettre la version non-JS dans la vue:

 <p class="replace_by_js">No Javascript</p> 

Et ensuite le remplacer par Javascript: (j'utilise jQuery)

 $('p.replace_by_js').replaceWith("<p>Javascript Enabled!</p>") 

Cette approche devrait être utilisable pour pratiquement toute amélioration progressive que vous souhaitez ajouter.

Au lieu d'écrire beaucoup de code pour vérifier si votre javascript est activé ou non, vous pouvez simplement écrire comme (utilisant HAML) dans votre mise en page –

 %p.javascript_require No javascript, please enable JavaScript 

Et faites de votre javascript cacher ce paragraphe en utilisant la fonction hide () comme –

 $(".javascript_require").hide(); 

Effectuez la fonction que vous souhaitez effectuer lorsque javascript est désactivé.

Vous ne pouvez pas le détecter sur le côté serveur. En effet, les scripts peuvent être désactivés la première fois que votre page est accessible, les paramètres du navigateur ont changé et ont été redistribués sans qu'une nouvelle requête HTTP soit effectuée. Sans parler de toutes sortes de problèmes de mise en cache et des endroits où le script peut être techniquement «activé» mais ne fonctionne pas en raison de conflits, de bogues ou d'outils de «sécurité».

Vous devez donc prendre toutes les décisions concernant le contenu avec-script / without-script du côté client. Ces jours-ci, la méthode préférée serait généralement une «amélioration progressive»: inclure la version HTML de base sur la page, puis la remplacer / la mettre à jour automatiquement, où elle peut:

 <div id="isitjs"> <p>Backup content for no JavaScript</p> </div> <script type="text/javascript"> document.getElementById('isitjs').innerHTML= '<p>Sparkly script-enhanced content!<\/p>'; // or DOM methods, as you prefer </script> 

Ce n'est pas possible pendant le rendu de la réponse. La seule façon de penser que moins ou plus fiable est de laisser le client envoyer une requête ajaxical à l'avance dans l'une des demandes précédentes. Cette requête ajaxical devrait ensuite définir un jeton dans la session côté serveur qui identifie que le client a déjà envoyé une requête ajaxical (ce qui prouve que le client a JS activé). Mais cela ne couvre pas la possibilité que le client puisse désactiver JS pendant ce temps pendant une session. Ou vous devez vous moquer de la collecte des horodatages et des demandes ajaxical après chaque réponse. Pas vraiment quelque chose que vous aimeriez faire.

Préparez plutôt les deux contenus et utilisez les balises <noscript> et <script> pour basculer l'un ou l'autre. Voir aussi ma réponse ici pour plusieurs exemples: en face de <noscript> .

Vous pourriez faire quelque chose de hacky comme ça, mais votre html "javascript-enabled" devrait être généré dans l'assistant

Mettez ceci dans votre application_helper.rb

 def javascript_enabled? content_tag(:div, [ content_tag(:script, 'document.write("Javascript Enabled")'), content_tag(:noscript, 'No Javascript') ]) end 

Cela dépend de votre point de vue:

 <%= javascript_enabled? %> 

Vous ne pouvez pas vérifier depuis le côté du serveur si Javascript est activé, mais vous pouvez configurer une page avant votre site et laisser la redirection vers votre application avec un paramètre indiquant si Javascript est activé. Voir l'exemple de code ci-dessous:

 <html> <head> <meta HTTP-EQUIV="REFRESH" content="2; url=./Login.action?javascriptEnabled=false"> <link rel="icon" href="favicon.ico" type="image/x-icon"/> <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/> <title></title> </head> <body onload="window.location.href='./Login.action?javascriptEnabled=true'" ></body> </html> 

Donc, si Javascript activé, la redirection Onload fonctionnera, sinon la méta-étiquette d'en-tête fonctionnera. L'astuce consiste à mettre 1-2 secondes de retard sur la redirection de méta-tags, donc si la redirection javascript ne redirige pas, la méta-étiquette indiquera qu'aucun JavaScript n'est activé.