今天早上有个帖子问有多少人禁用JavaScript。然后我开始想知道可以使用什么技术来确定用户是否禁用了它。

有人知道一些简单的方法来检测JavaScript是否被禁用吗?我的意图是给一个警告,如果浏览器没有启用JS,站点将无法正常运行。

最终,我想把它们重定向到能够在没有JS的情况下工作的内容,但我需要这个检测作为一个占位符来开始。


当前回答

使用我在这里介绍的纯服务器端解决方案检查cookie,然后使用Jquery删除cookie来检查javascript。Cookie,然后检查Cookie,这种方式你检查Cookie和javascript

其他回答

我过去使用的一种技术是使用JavaScript编写一个会话cookie,它只是作为一个标志,表示启用了JavaScript。然后服务器端代码查找此cookie,如果没有找到,则采取适当的操作。当然,这种技术确实依赖于启用cookie !

因为我总是想给浏览器一些有价值的东西,我经常使用这个技巧:

首先,页面中任何需要JavaScript才能正常运行的部分(包括通过getElementById调用等修改的被动HTML元素)都被设计成可用的,假设没有可用的JavaScript。(设计得好像它不存在一样)

任何需要JavaScript的元素,我在标签中放置如下内容:

<span name="jsOnly" style="display: none;"></span>

然后在文档的开头,使用.onload或document。在getElementsByName('jsOnly')的循环中设置.style。Display = "";重新打开JS依赖的元素。这样,非JS的浏览器就不需要看到站点中依赖于JS的部分,如果他们拥有它,它会在准备就绪时立即显示出来。

一旦您习惯了这种方法,就很容易混合您的代码来处理这两种情况,尽管我现在只是在试验noscript标记,并期望它会有一些额外的优点。

如果javascript被禁用,您的客户端代码将无法运行,所以我假设您的意思是您希望该信息可用的服务器端。在这种情况下,noscript就没那么有用了。相反,我有一个隐藏的输入,并使用javascript填充一个值。在你的下一个请求或回发后,如果值在那里,你知道javascript是打开的。

注意像noscript这样的事情,第一次请求可能显示javascript被禁用,但以后的请求会打开它。

下面是一个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;
}
?>

在meta noscript内部添加刷新不是一个好主意。

因为noscript标签不符合XHTML 属性值“Refresh”是非标准的,不应该使用。“刷新”将页面的控制权从用户手中夺走。使用“刷新”将导致W3C的Web内容可访问性指南失败 ——参考http://www.w3schools.com/TAGS/att_meta_http_equiv.asp。