javascriptでクイズを作る時に答えをソースコードから隠す方法

ごめんなさい、結論から言うとjavascriptだけではソースコードから完全に答えを隠すことはできません

答えを隠すためにはサーバーサイドの言語を使用する必要があります

この記事ではPHPを使用してクイズの答えを隠す方法を紹介します

JavaScriptで問題を作る時に答えをjsファイルに直接記述してifで正誤判定をしていませんか?

例えば先日Twitterでこのようなポストを見かけました

https://twitter.com/dpandaramu/status/1733094227318583667
イベントはすでに終了しています

リンクを開いてみると、クイズがあって正解した人だけイベントの詳細を見られるというようなものでした

クイズはinputタグに入力して回答する仕組みだったのですが、大体こういうのってJavaScriptで実装しているのでソースコードを見ると回答がわかっちゃうんですよね、、、

やはり探したらありましたw

まあよほどのモノ好き以外ソースコードを見て答えを覗こうなんて輩はいないと思いますが、これがもしお金が絡んでいる問題であれば話は別です

簡単に正解されるのが嫌だ!くらいの気持ちであれば答えを別ファイルにしたり、JavaScriptを難読化したりと見つかりにくくする方法はいくらでもあると思いますが、確実に答えが見られたくない場合はJavascriptだけではほぼ不可能です
※サーバーサイドの言語を使ったとしても確実にハックされないとは言っていない

ただ、PHP(サーバーサイドの言語)を使ったクイズはそこまで難しくもないので答えを見られたくない場合はPHPを使用してサクッと実装してしまいましょう

PHPでクイズの正誤判定をするコードの例

クイズの回答が「りんご」だった場合に「http://hoge.com」へ遷移するようなコードを実装してみます

JavaScriptで実装した場合

<!DOCTYPE html>
<html>
<head>
    <title>リダイレクトの例</title>
    <script type="text/javascript">
        function checkAnswer() {
            var answer = document.getElementById('answer').value;
            if (answer === 'りんご') {
                window.location.href = 'http://hoge.com';
            } else {
                alert('不正解です。もう一度お試しください。');
            }
            return false; // フォームの送信を防ぐ
        }
    </script>
</head>
<body>
    <div>
        <form onsubmit="return checkAnswer()">
            <input type="text" id="answer" name="ans">
            <input type="submit" value="回答" name="send">
        </form>
    </div>
</body>
</html>

PHPで実装する場合

<!DOCTYPE html>
<html>
<head>
    <title>リダイレクトの例</title>
</head>
<body>
    <div>
        <form action="validate.php" method="get">
            <input type="text" name="ans">
            <input type="submit" value="回答">
        </form>
    </div>
</body>
</html>
<?php
$answer = $_GET['ans'];

if ($answer === 'りんご') {
    header('Location: http://hoge.com');
    exit;
} else {
    echo '不正解です。もう一度お試しください。';
}
?>

遷移先のリンクを直接開いたり、不正解だったときの動きは別途実装する必要がありますが、一旦上記のコードで回答がソースから見られることはありません

おまけ:回答をベーシック認証の答えにしてみる

遷移先のディレクトリにベーシック認証をかけておき、inputタグで受け取った回答をベーシック認証のパスワードとして使用する方法も試してみました

<label> 回答: <input type="text" id="answer" name="ans"></label>
<button id="submitButton" class="btn">送信</button>
<script>
  document.getElementById('submitButton').addEventListener('click', function () {
    var answer = document.getElementById('answer').value;
    accessProtectedPage(answer); // 回答をパスワードとして使用
  });

  function accessProtectedPage(password) {
    var username = 'sbw'; // ベーシック認証のユーザー名

    var headers = new Headers();
    headers.append('Authorization', 'Basic ' + btoa(username + ":" + password));

    fetch('./result/index.html', { method: 'GET', headers: headers })
      .then(response => {
        if (response.ok) {
          // 認証成功時、ページに直接遷移
          window.location.href = './result/index.html';
        } else {
          // 認証失敗時の処理
          alert('認証に失敗しました。');
        }
      })
      .catch(error => console.error('Error:', error));
  }
</script>

正解の時は期待した動きになりました

しかし、不正解だった場合は「// 認証失敗時の処理」の行がはじめに呼び出されてほしかったのですが、先にデフォルトのベーシック認証のアラートが出てしまいます

動き的にあまり美しくないので、ベーシック認証を使用する方法は諦めました

上杉

できる限り簡単な答えを隠す方法があれば教えてください!!

ブログ一覧へ