今天早上有个帖子问有多少人禁用JavaScript。然后我开始想知道可以使用什么技术来确定用户是否禁用了它。
有人知道一些简单的方法来检测JavaScript是否被禁用吗?我的意图是给一个警告,如果浏览器没有启用JS,站点将无法正常运行。
最终,我想把它们重定向到能够在没有JS的情况下工作的内容,但我需要这个检测作为一个占位符来开始。
今天早上有个帖子问有多少人禁用JavaScript。然后我开始想知道可以使用什么技术来确定用户是否禁用了它。
有人知道一些简单的方法来检测JavaScript是否被禁用吗?我的意图是给一个警告,如果浏览器没有启用JS,站点将无法正常运行。
最终,我想把它们重定向到能够在没有JS的情况下工作的内容,但我需要这个检测作为一个占位符来开始。
当前回答
下面是一个PHP脚本,它可以在生成任何输出之前包含一次。它不是完美的,但在大多数情况下,它工作得足够好,以避免交付客户端不会使用的内容或代码。标题注释解释了它是如何工作的。
<?php
/*****************************************************************************
* JAVASCRIPT DETECTION *
*****************************************************************************/
// Progressive enhancement and graceful degradation are not sufficient if we
// want to avoid sending HTML or JavaScript code that won't be useful on the
// client side. A normal HTTP request will not include any explicit indicator
// that JavaScript is enabled in the client. So a "preflight response" is
// needed to prompt the client to provide an indicator in a follow-up request.
// Once the state of JavaScript availability has been received the state of
// data received in the original request must be restored before proceding.
// To the user, this handshake should be as invisible as possible.
//
// The most convenient place to store the original data is in a PHP session.
// The PHP session extension will try to use a cookie to pass the session ID
// but if cookies are not enabled it will insert it into the query string.
// This violates our preference for invisibility. When Javascript is not
// enabled the only way to effect a client side redirect is with a "meta"
// element with its "http-equiv" attribute set to "refresh". In this case
// modifying the URL is the only way to pass the session ID back.
//
// But when cookies are disabled and JavaScript is enabled then a client side
// redirect can be effected by setting the "window.onload" method to a function
// which submits a form. The form has a "method" attribute of "post" and an
// "action" attribute set to the original URL. The form contains two hidden
// input elements, one in which the session ID is stored and one in which the
// state of JavaScript availability is stored. Both values are thereby passed
// back to the server in a POST request while the URL remains unchanged. The
// follow-up request will be a POST even if the original request was a GET, but
// since the original request data is restored, the containing script ought to
// process the request as though it were a GET.
// In order to ensure that the constant SID is defined as the caller of this
// script would expect, call session_start if it hasn't already been called.
$session = isset($_SESSION);
if (!$session) session_start();
// Use a separate session for Javascript detection. Save the caller's session
// name and ID. If this is the followup request then close the caller's
// session and reopen the Javascript detection session. Otherwise, generate a
// new session ID, close the caller's session and create a new session for
// Javascript detection.
$session_name = session_name();
$session_id = session_id();
session_write_close();
session_name('JS_DETECT');
if (isset($_COOKIE['JS_DETECT'])) {
session_id($_COOKIE['JS_DETECT']);
} elseif (isset($_REQUEST['JS_DETECT'])) {
session_id($_REQUEST['JS_DETECT']);
} else {
session_id(sha1(mt_rand()));
}
session_start();
if (isset($_SESSION['_SERVER'])) {
// Preflight response already sent.
// Store the JavaScript availability status in a constant.
define('JS_ENABLED', 0+$_REQUEST['JS_ENABLED']);
// Store the cookie availability status in a constant.
define('COOKIES_ENABLED', isset($_COOKIE['JS_DETECT']));
// Expire the cookies if they exist.
setcookie('JS_DETECT', 0, time()-3600);
setcookie('JS_ENABLED', 0, time()-3600);
// Restore the original request data.
$_GET = $_SESSION['_GET'];
$_POST = $_SESSION['_POST'];
$_FILES = $_SESSION['_FILES'];
$_COOKIE = $_SESSION['_COOKIE'];
$_SERVER = $_SESSION['_SERVER'];
$_REQUEST = $_SESSION['_REQUEST'];
// Ensure that uploaded files will be deleted if they are not moved or renamed.
function unlink_uploaded_files () {
foreach (array_keys($_FILES) as $k)
if (file_exists($_FILES[$k]['tmp_name']))
unlink($_FILES[$k]['tmp_name']);
}
register_shutdown_function('unlink_uploaded_files');
// Reinitialize the superglobal.
$_SESSION = array();
// Destroy the Javascript detection session.
session_destroy();
// Reopen the caller's session.
session_name($session_name);
session_id($session_id);
if ($session) session_start();
unset($session, $session_name, $session_id, $tmp_name);
// Complete the request.
} else {
// Preflight response not sent so send it.
// To cover the case where cookies are enabled but JavaScript is disabled,
// initialize the cookie to indicate that JavaScript is disabled.
setcookie('JS_ENABLED', 0);
// Prepare the client side redirect used when JavaScript is disabled.
$content = '0; url='.$_SERVER['REQUEST_URI'];
if (!$_GET['JS_DETECT']) {
$content .= empty($_SERVER['QUERY_STRING']) ? '?' : '&';
$content .= 'JS_DETECT='.session_id();
}
// Remove request data which should only be used here.
unset($_GET['JS_DETECT'],$_GET['JS_ENABLED'],
$_POST['JS_DETECT'],$_POST['JS_ENABLED'],
$_COOKIE['JS_DETECT'],$_COOKIE['JS_ENABLED'],
$_REQUEST['JS_DETECT'],$_REQUEST['JS_ENABLED']);
// Save all remaining request data in session data.
$_SESSION['_GET'] = $_GET;
$_SESSION['_POST'] = $_POST;
$_SESSION['_FILES'] = $_FILES;
$_SESSION['_COOKIE'] = $_COOKIE;
$_SESSION['_SERVER'] = $_SERVER;
$_SESSION['_REQUEST'] = $_REQUEST;
// Rename any uploaded files so they won't be deleted by PHP. When using
// a clustered web server, upload_tmp_dir must point to shared storage.
foreach (array_keys($_FILES) as $k) {
$tmp_name = $_FILES[$k]['tmp_name'].'x';
if (move_uploaded_file($_FILES[$k]['tmp_name'], $tmp_name))
$_SESSION['_FILES'][$k]['tmp_name'] = $tmp_name;
}
// Have the client inform the server as to the status of Javascript.
?>
<!DOCTYPE html>
<html>
<head>
<script>
document.cookie = 'JS_ENABLED=1';
// location.reload causes a confirm box in FireFox
// if (document.cookie) { location.reload(true); }
if (document.cookie) { location.href = location; }
</script>
<meta http-equiv="refresh" content="<?=$content?>" />
</head>
<body>
<form id="formid" method="post" action="" >
<input type="hidden" name="<?=$session_name?>" value="<?=$session_id?>" />
<input type="hidden" name="JS_DETECT" value="<?=session_id()?>" />
<input type="hidden" name="JS_ENABLED" value="1" />
</form>
<script>
document.getElementById('formid').submit();
</script>
</body>
</html>
<?php
exit;
}
?>
其他回答
这里是转折! 可能有客户端浏览器启用了Javascript,并且使用JS兼容的浏览器。但是不管出于什么原因Javascript在浏览器中不能工作(比如:防火墙设置)。据统计,这种情况每93个场景中就会发生1个。所以服务器检测到客户端有能力执行Javascript,但实际上并没有!
作为解决方案,我建议我们在客户端站点设置一个cookie,然后从服务器读取它。如果cookie设置好了,JS就可以正常工作。有什么想法吗?
我建议您反过来编写不引人注目的JavaScript。
使您的项目的功能为禁用JavaScript的用户工作,当您完成后,实现您的JavaScript ui增强。
https://en.wikipedia.org/wiki/Unobtrusive_JavaScript
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>
没有js的用户会得到next_page链接——你可以在这里添加参数,这样你就可以在下一页知道他们是否通过js /非js链接来访问,或者试图通过js设置cookie,如果没有这些就意味着js被禁用了。这两个例子都非常琐碎,可以进行操作,但是您可以理解其中的含义。
如果你想知道有多少用户禁用了javascript,你可以这样做:
<noscript>
<img src="no_js.gif" alt="Javascript not enabled" />
</noscript>
然后检查您的访问日志,看看这个映像被击中了多少次。这是一个略显粗糙的解决方案,但它将为你的用户基础提供一个很好的百分比。
上面的方法(图像跟踪)不适用于纯文本浏览器或根本不支持js的浏览器,所以如果你的用户群主要倾向于这方面,这可能不是最好的方法。
只是有点难,但是(发型师给了我灵感)
CSS:
.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的解决方案吗?
我已经想出了另一种方法使用css和javascript本身。 这只是开始修补类和id。
CSS代码片段: 1. 创建一个css ID规则,命名为#jsDis。 2. 使用"content"属性在BODY元素后生成文本。(你可以按照自己的意愿设置样式)。 3创建第二个css ID规则,命名为#jsEn,并对其进行风格化。(为了简单起见,我给#jsEn规则设置了不同的背景色。
<style>
#jsDis:after {
content:"Javascript is Disable. Please turn it ON!";
font:bold 11px Verdana;
color:#FF0000;
}
#jsEn {
background-color:#dedede;
}
#jsEn:after {
content:"Javascript is Enable. Well Done!";
font:bold 11px Verdana;
color:#333333;
}
</style>
JavaScript代码片段: 1. 创建一个函数。 2. 使用getElementById获取BODY ID并将其分配给一个变量。 3.使用JS函数'setAttribute',改变BODY元素ID属性的值。
<script>
function jsOn() {
var chgID = document.getElementById('jsDis');
chgID.setAttribute('id', 'jsEn');
}
</script>
HTML部分。 1. 将BODY元素属性的ID命名为#jsDis。 2. 使用函数名添加onLoad事件。(jsOn())。
<body id="jsDis" onLoad="jsOn()">
因为BODY标签的ID是#jsDis: -如果Javascript被启用,它会自己改变BODY标签的属性。 -如果Javascript是禁用的,它将显示css 'content:'规则文本。
你可以使用#包装容器,或者使用任何使用JS的DIV。 希望这有助于理解。