使用Rails检查Javascript是否已启用(Serverside)

时间:2010-02-23 01:54:10

标签: javascript ruby-on-rails server-side erb noscript

如何检查Rails中是否启用了javascript?所以我可以在视图中做这样的事情:

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

7 个答案:

答案 0 :(得分:6)

你可以检测到它,但它并不漂亮。

首先,您需要一个具有更新会话超时的操作的新控制器:

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

接下来,您需要在所有页面中包含javascript操作,以便在每个页面加载时调用此控制器操作。最简单的方法是将它包含在你的布局中包含的“javascript-confirm.js”文件中(在这个特定的例子中我使用了Prototype的Ajax.Request,所以你需要将它包含在你的javascripts中):

function confirmJavascript()
{
    // Assuming you are using Prototype
    new Ajax.Request('/JavascriptController/confirm');
}

myTimeoutFunction();
setInterval(myTimeoutFunction, 10000); // invoke each 10 seconds

这将在所有页面视图中调用confirm操作。最后,您必须控制自您上次在应用程序控制器中确认后经过的时间。

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

现在,您的所有控制器中都会有一个名为@javascript_active的变量。

即使用户激活/停用javascript,它也应该工作,精度为10秒。如果您的某些页面加载时间超过10页(即包含大量图像),则可能无效。在这种情况下增加时间限制(在applicationcontroller和你的javascript上)

免责声明:我没有测试过这段代码,有些漏洞可能潜伏着 - 但它应该指向正确的方向。

答案 1 :(得分:5)

如果你希望它能所有,那么最好将非JS版本放在视图中:

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

然后将Javascript替换为:(我使用jQuery)

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

此方法几乎可用于您想要添加的任何渐进增强。

答案 2 :(得分:2)

您可以简单地在页面布局中编写(使用HAML)代替编写大量代码来检查您的javascript是否启用 -

%p.javascript_require
  No javascript, please enable JavaScript

并使用hide()函数将您的javascript隐藏此段落 -

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

如果禁用了javascript,请执行您要执行的任何功能。

答案 3 :(得分:1)

在呈现响应期间无法做到这一点。唯一可以确定更低或更可靠的方法是让客户端事先在之前的一个请求中发送一个ajaxical请求。然后,这个ajaxical请求应该在服务器端会话中设置一些令牌,该令牌标识客户端事先发送了一个ajaxical请求(从而证明客户端已启用JS)。但这并未涵盖客户端在会话期间可以同时禁用JS的可能性。或者你必须在每次回复后收集时间戳和ajaxical请求。不是你想做的事。

而是渲染这两个内容并使用<noscript><script>标记来切换其中一个。另请参阅我的答案,例如:opposite of <noscript>

答案 4 :(得分:1)

您无法在服务器端检测到它。实际上,可能会在第一次访问页面时关闭脚本,然后更改浏览器设置并重新导航,而不会发出新的HTTP请求。更不用说各种缓存问题以及脚本可能在技术上“启用”但由于冲突,错误或“安全”工具阻碍而无法工作的地方。

因此,您需要在客户端对with-script / without-script的内容做出所有决定。目前,首选方法通常是“渐进式增强”:在页面上包含基本HTML版本,然后在可能的地方使用JavaScript替换/升级:

<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>

答案 5 :(得分:0)

你可以像这样做一些hacky,但你的“启用javascript”的html需要在帮助器中生成

将它放在您的application_helper.rb

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

这在你看来:

<%= javascript_enabled? %>

答案 6 :(得分:0)

您无法从服务器端检查是否启用了Javascript,但是,您可以在站点之前设置页面,然后使用指示Javascript是否已启用的参数重定向到您的应用程序。请参阅以下示例代码:

<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>

因此,如果启用了Javascript,onload重定向将起作用,如果没有,那么标头元标记将起作用。 诀窍是在元标记重定向上放置1-2秒延迟,因此如果javascript重定向不会重定向,则元标记将指示没有启用JavaScript。