如何检测JavaScript是否已禁用?

703
早上有一篇帖子询问有多少人禁用JavaScript。这让我开始思考如何确定用户是否已经禁用了它。 有没有人知道一些简单的方法来检测JavaScript是否被禁用?我的意图是给出一个警告,提示该网站需要启用JS才能正常运行。 最终,我想将他们重定向到无需JS即可工作的内容,但我需要这个检测作为占位符来开始。

你想用这些信息做什么?它可能会改变你得到的答案——例如,通常应该优先选择渐进增强而不是尝试检测 JavaScript 是否被禁用并根据此采取特定的操作。 - Jonny Buchanan
渐进增强是我所追求的。我希望能够将用户重定向到备用内容,以便在没有启用或支持JS的浏览器中正常运行。 - MikeJ
1
@expiredninja 这篇来自Nicholas Zakas的文章说大约有2%的用户禁用了JavaScript,不过这已经是一年前的数据了。 - sdleihssirhc
最简单的方法是使用noscript来显示非JavaScript网站,并通过修改样式显示来显示任何JavaScript依赖元素。 - Myforwik
http://www.enable-javascript.com - Vitim.us
40个回答

393
我想在这里补充一点。虽然不是100%防弹,但我认为已经足够好了。
对于我来说,使用某种“如果没有启用Javascript,则该网站无法正常工作”的提示的首选示例存在问题,那就是您需要确保您的网站在没有Javascript的情况下能够正常工作。一旦您开始这样做,您就会意识到该网站应该在关闭JS的情况下也是防弹的,这是一个额外的大块工作。
所以,您真正想要的是重定向到一个页面,告诉用户“打开JS,傻瓜”。但是,当然,您不能可靠地进行元重定向。因此,这里有个建议:
<noscript>
    <style type="text/css">
        .pagecontainer {display:none;}
    </style>
    <div class="noscriptmsg">
    You don't have javascript enabled.  Good luck with that.
    </div>
</noscript>

...其中你的网站中所有的内容都被包裹在一个 class 为 "pagecontainer" 的 div 中。noscript 标签内的 CSS 将隐藏所有页面内容,并显示任何你想要展示的“无 JS”消息。这实际上是 Gmail 所使用的方法……如果它对 Google 足够好,那么它也足以适用于我的小网站。


12
你是否尝试验证google.com?验证只是确定文档遵循规范的程度,它不会对页面的可用性产生任何影响。 - JKirchartz
82
如果您的Web应用程序建立在JavaScript上并且需要JavaScript才能正常运行,那么强制用户需要JavaScript有什么问题呢?我经常听到这种评论,但只有对于最简单的网站才是有效的。试着关闭Facebook的JS功能,看看会发生什么。如果您的应用程序是基于JavaScript构建的,那么要求99%的用户启用JavaScript有什么问题呢? - Lee Benson
24
@Lee说得很中肯,你只能在支持范围内为用户提供服务。我们期望所有用户都有联网设备,那我是否也应该为拒绝使用互联网的用户实现一个纸质版的网站呢? - Kolors
19
@Kolors,我于2012年3月发表了那个评论,我认为它今天的真实性已经翻倍。从那时起,我们已经拥有了Meteor、Angular.Js、Famo.us等大量惊人的库,这些都需要使用Javascript才能启动。我确实想知道那些选择禁用JS的用户到底在尝试什么……显然,他们没有像我们其他人一样在浏览同一个网站,而且没有理由让公司为最顽固的用户子集缩小网站规模…… - Lee Benson
7
没问题,我可以为您进行翻译。原文意思是“是的,我想知道为什么我不能点赞你的答案,后来发现是因为我忘了开启 JavaScript :-)) 我喜欢并实施了你的解决方案!谢谢!”我会尽力使翻译更加通俗易懂,但不改变原意。 - Garavani
显示剩余12条评论

309
我假设你正在考虑是否提供JavaScript增强内容。最好的实现方式是具备良好的降级处理能力,以便在没有JavaScript的情况下网站仍然可以运行。我还假设你指的是服务器端检测,而不是出于未经解释的原因使用<noscript>元素。
没有一种好的方法来执行服务器端JavaScript检测。作为替代方案,可以使用JavaScript 设置cookie,然后在后续页面访问时使用服务器端脚本测试该cookie。但是,这不适用于决定提供何种内容,因为它无法将没有cookie的访客与新访客或未接受JavaScript设置cookie的访客区分开来。

134
最语义化的指定非JavaScript内容的方式是检测JavaScript是否启用,而不是检测是否禁用JavaScript。因此,默认显示“您需要启用JavaScript才能正确使用我的网站”消息,但立即在onLoad时使用JavaScript函数隐藏它。 - matt lohkamp
61
甚至可以默认隐藏消息,并在<noscript>中放置<style>块来取消隐藏(如果启用JS,则不会重新流动)。令人惊讶的是,这在所有现代浏览器甚至在IE6中都有效。 - Piskvor left the building
7
@matt - 我之前一直在这样做,但是对于网络慢的用户来说,消息会停留一段时间,让他们感到困惑。我在这里寻找另一种解决方案。@Piskvor - 在头部使用<noscript>标签无法通过验证,在正文中使用<style>标签也无法通过验证。 - Ben
21
除了你关注验证的原因是什么?你是为了纯粹验证而验证吗?如果它能够正常工作并以“有点污秽”的方式达成目标,那还有问题吗?别担心,我不会评判的;-) - keif
5
如果只是使用style属性来给<noscript>标签内的特定元素添加样式(例如<noscript><div style="color:red;">blahblah</div></noscript>或类似的内容),那么这仍然是有效的。但如果您将<style>块放在页眉中,定义某些.noscript(或类似)类元素的样式,并在<body>标签内,在<noscript>标签内仅为给定元素赋予先前定义的.noscript类,则它也仍然有效,如下所示:<noscript><div class="noscript">blahblah</div></noscript>。 - Sk8erPeter
显示剩余6条评论

204
noscript代码块在JavaScript被禁用时执行,通常用于展示替代性内容,以取代由JavaScript生成的内容。
<script type="javascript">
    ... construction of ajaxy-link,  setting of "js-enabled" cookie flag, etc..
</script>
<noscript>
    <a href="next_page.php?nojs=1">Next Page</a>
</noscript>

没有开启 JavaScript 的用户将会得到 next_page 链接——您可以在此添加参数,以便在下一页中知道他们是通过 JS/非 JS 链接进入的,或者尝试通过 JS 设置 cookie,其缺失意味着 JavaScript 已被禁用。这两个示例都相当简单,并且容易受到操纵,但您已经有了想法。

如果您想纯粹地统计有多少用户禁用了 JavaScript,可以采取以下措施:

<noscript>
    <img src="no_js.gif" alt="Javascript not enabled" />
</noscript>

然后检查您的访问日志,以查看该图像被点击的次数。这是一个稍微粗糙的解决方案,但它会为您的用户基础提供一个很好的百分比概念。

对于只支持纯文本浏览器或根本不支持JS的浏览器,上述方法(图像跟踪)将无法很好地发挥作用,因此,如果您的用户群主要偏向于该领域,这可能不是最佳选择。


9
这并不是非常有效的。例如,它无法统计使用仅支持文本的浏览器的用户,因为这些浏览器通常不支持JavaScript。至少,你应该禁用该图像的缓存。 - Jim
3
完全不支持JS的浏览器会忽略<noscript>标签并显示图片吗? - LKM
1
@LKM:这取决于它们是如何编写的,很可能会,所以您可以将其设置为1x1像素点。该选项主要用于跟踪服务器端的使用模式,因此仍然可以使用,因为它由没有JavaScript功能的用户触发。 - ConroyP
请注意,如果您对noscript标签进行样式设置,目前存在与IE8有关的错误... 请参阅positioniseverything.net/explorer.html。 - alex
2
你也可以将该图片作为服务器端脚本提供,设置mime类型,并使用它来记录有关用户的一些信息或放置cookie... http://px.sklar.com/code.html/id=256 - JKirchartz
太棒了,太容易了!我真后悔之前不知道这个。然而,我只是想让用户知道网站需要JavaScript才能正常运行,所以在<noscript>标签内加一个简单的<p>标签就解决了我的问题。 - rDroid

50
这是对我有效的方法:如果禁用了JavaScript,它会将访问者重定向。
<noscript><meta http-equiv="refresh" content="0; url=whatyouwant.html" /></noscript>

6
这是无效的。noscript元素不能包含meta元素。我不会相信这个能在所有浏览器中可靠地工作(包括您目前无法测试的未来浏览器),因为它们可能以不同的方式执行错误恢复。 - Quentin
16
这可能是无效的,但看一下Facebook的代码,它在<head>部分使用了相同的解决方案-这并不意味着这是一个非常好的解决方案,因为Facebook的代码远非有效代码,但它可以意味着它在许多用户的浏览器上工作,这可能是一个重要的方面。但是确实并不建议这样做。下面是他们的代码:<noscript><meta http-equiv=refresh content="0; URL=/about/messages/?_fb_noscript=1" /></noscript> - Sk8erPeter
IE9(至少)有一个“允许META REFRESH”的设置。我没有看到很多人关闭它,但可能那些不喜欢JavaScript的人会这么做。但是,如果您想要100%,这不是办法。 - jenson-button-event
它在HTML5中是有效的。 - Naszta
编辑:已添加XML关闭。 - Naszta
1
这会破坏在Linkedin上分享链接的功能,我们通过艰难的方式发现了这一点...这不是一个好主意。因为Linkedin遵循meta refresh,忽略Og标签等。 - SomeDudeSomewhere

46

157
人生苦短,现在是2012年——启用JavaScript或离开。 - Yarin
27
“人生苦短,现在已经是2012年了——启用JavaScript或回家!”这是在没有JavaScript的情况下显示的一个完美小提示信息。我只是为了告诉你@Yarin。 - user900360
5
我刚登录只是为了说太棒了!@Yarin。我正在制作一个小网站,它不会向公众开放(类似于内部网络,但用于朋友们一起开展项目)。我将其制作成单页应用程序,并不打算添加回退机制。不引人注目的JavaScript将使我投入到单页应用程序概念中的工作量几乎翻倍。使用现代JavaScript库(例如Knockout、Jquery等),我们必须接受并非每个网站都能轻松地实现“不引人注目”。JavaScript是Web的未来。 - lassombra
5
@Yarin 我以建立PHP/JS应用程序为生,我从未添加后备选项...如果某些人无法使用它们,他们会联系我,我会告诉他们停止过去的生活方式并启用JS。 - Someone
3
@n611x007 - 所有代码中都隐藏着不道德的东西,无论是服务器端还是客户端设备。这不是代码的错,而是人类的错。我觉得反对JS的运动很讽刺,因为你仍然使用第三方ISP连接到互联网,仍然使用带有第三方硬件/固件的计算机,仍然使用可以被第三方注入攻击的不安全的蜂窝网络,仍然拥有使用第三方未修补操作系统的手机,仍然使用使用第三方开放更新服务的平板电视等等。无论你是否在浏览器中关闭JS,你始终是MITM-ish通道的受害者。 - dhaupin
显示剩余5条评论

44
如果您的使用情况是有一个表单(例如登录表单),并且您的服务器端脚本需要知道用户是否启用了JavaScript,您可以像这样做:

如果你的使用场景是有一个表单(比如登录表单)而你的服务端脚本需要知道用户是否启用了 JavaScript,你可以采取以下方法:

<form onsubmit="this.js_enabled.value=1;return true;">
    <input type="hidden" name="js_enabled" value="0">
    <input type="submit" value="go">
</form>

在提交表单之前,这将把js_enabled的值更改为1。如果您的服务器端脚本获取到了0,则没有JS。如果它获取到了1,则有JS!


40
<noscript> 标签并不是必要的,更不用说在 XHTML 中不受支持了。

工作示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html>
<head>
    <title>My website</title>
    <style>
      #site {
          display: none;
      }
    </style>
    <script src="http://code.jquery.com/jquery-latest.min.js "></script>
    <script>
      $(document).ready(function() {
          $("#noJS").hide();
          $("#site").show();
      });
    </script>
</head>
<body>
    <div id="noJS">Please enable JavaScript...</div>
    <div id="site">JavaScript dependent content here...</div>
</body>
</html>

在这个例子中,如果JavaScript已启用,则会看到该站点。如果没有启用,则会看到“请启用JavaScript”消息。 测试JavaScript是否已启用的最佳方法是尝试使用JavaScript! 如果它能正常工作,则已启用;否则,则未启用...


3
哈,XHTML。那些日子真是美好啊... 事情已经发生了很大的变化:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/noscript - Stephan Weinhold
1
@StephanWeinhold,JSF使用XHTML。 - Arash

36

在body标签上使用.no-js类,基于.no-js父类创建非JavaScript样式。如果禁用了JavaScript,则您将获得所有非JavaScript样式,如果有JS支持,则.no-js类将被替换为通常的所有样式。

 document.body.className = document.body.className.replace("no-js","js");

HTML5 Boilerplate中使用的技巧http://html5boilerplate.com/是通过Modernizr实现的,但你可以使用一行JavaScript代码替换这些类。

noscript标签没问题,但是为什么要在HTML中添加额外的内容,当可以用CSS完成呢?


5
难以置信在有人提到 .nojs 类之前竟然要花这么长时间!这是最无缝的方法之一,使 noscript 相形见绌。 - Moses

15
Great! What language pair do you need assistance with?
.pagecontainer {
  display: none;
}

JS:

function load() {
  document.getElementById('noscriptmsg').style.display = "none";
  document.getElementById('load').style.display = "block";
  /* rest of js*/
}

HTML:

<body onload="load();">

  <div class="pagecontainer" id="load">
    Page loading....
  </div>
  <div id="noscriptmsg">
    You don't have javascript enabled. Good luck with that.
  </div>

</body>

无论哪种情况下都可以工作对吧? 即使不支持noscript标签(只需要一些css)。 有人知道非css的解决方案吗?


13

您可以使用简单的JS代码片段来设置隐藏字段的值。当提交后,您就会知道是否启用了JS。

或者,您可以尝试打开一个快速关闭的弹出窗口(但可能可见)。

此外,您还可以使用NOSCRIPT标记来显示针对未启用JS的浏览器的文本。


这不是一个好的答案。第一种解决方案需要重新加载页面和提交表单。第二种解决方案打开了一个弹出窗口(哎呀!)并“快速”关闭它 - 是从客户端吗?-1 - Ben
有时您需要在服务器端知道网站是否启用了JS,所以我不认为除了返回某些内容之外还有其他方法来实现它。我同意弹出窗口很丑陋,但我不确定这是否可行,可以在屏幕的不可见区域打开弹出窗口,使用户不会受到干扰。虽然这不太优雅,但它有效并且没有页面重新加载。 - rslite
Spambots 也会发布到隐藏字段。 - Janis Veinbergs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接