是否可以在vue-router中锁定除一个以外的所有路由?它安全吗?或许我应该使用另一种方法?

Ahm*_*aki 5 javascript vue.js vue-router vuejs2

我想建立一个在线考试,这个考试有5页,每个页面有一个倒计时器(120秒)和4个问题.120秒后,用户将自动转移到下一页,或者可以在此之前单击下一个按钮.

Laravel5.4和VueJs,用户回答的每个问题都有一个Ajax请求.我想要的是阻止用户看到其他页面.每页必须最多可见120秒.用户不应该单击后退按钮并查看以前的页面.这有可能吗?

我要创建这个应用程式Vuejsvue-router,但我不知道如何与实现这个vue-router,我做了一些研究,但有没有太多的结果!

或者也许我不应该使用vue-router,并使用我自己的简单路由器,例如:

$("#page1").show();
$("#page2").hide();
$("#page3").hide();
.
.
// after 120 secs 
$("#page1").hide();
$("#page2").show();
$("#page3").hide();
.
.
 // i think this is not secure !
Run Code Online (Sandbox Code Playgroud)

任何想法都表示赞赏.谢谢.

更新: 在此考试中,用户可以看到English wordswords表中随机选择的列表, 而不是其他内容!用户点击他认为自己知道其含义的每个单词!每次点击都有一个ajax请求,用于保存results表中单词的id .此外,如果用户点击假字超过3次,fake_words则会选择随机选择50个字的表,actual words测试将失败.最终结果将告诉用户他有多少词汇技能.

更新2:我尝试这样做vue-router,但在开始编码之前,我想也许它不应该实现,vue-router因为所有问题在一个查询中随机从DB中获取,然后在考试开始之前,所有这些都发送(ajax)到浏览器,现在该怎么办?将它们分成不同的数组并将每个问题数组发送到我的一个页面?我必须这样做吗?我不能只v-for为他们使用一个?如果我决定更改问题的数量怎么办?然后我想我每次都要触摸我的代码并创建新页面vue-router或删除其中一个页面.

Luc*_*oni 1

就安全性而言,JS 框架的选择即使有影响也很小。Vue.js 是一个很好的选择。这是一个可以帮助您入门的示例代码:

<template>
  <div>
    <div id="question" v-if="question">
      {{question}}
      <button @click="nextQuestion();" v-if="hasNextQuestion()"></button>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        curQuestionNo: 0,
        maxQuestions: 4
        question: null,
        timer: null
      }
    },
    methods: {      
      fetchQuestion () {
        // return one question at a time from the server. Storing all questions on the client is not recommended.
        var url = 'https://myapi.com/question?curQuestionNo=' + this.curQuestionNo;

        axios.get(url) // or however you prefer to make ajax calls
          .then(res => {
            this.question = res.question;
            this.curQuestionNo++;
            this.stopTimer();
            if(this.hasNextQuestion()) {
              this.startTimer();
            }
          })
          .catch(() => {
            // do some error handling
          });
      },
      startTimer () {
        this.timer = setTimeout(() => {
          this.nextQuestion();
        }, 120 * 1000);
      },
      stopTimer () {
        clearTimeout(this.timer);
      },
      nextQuestion () {
        if(this.curQuestionNo > 0) {
          this.markAnswered(function() {  
            this.fetchQuestion();
          })
        } else {
          this.fetchQuestion();
        }
      },
      markAnswered (cb) {
        // record the answered question on server
        // server should only send the next question after this
        var url = 'https://myapi.com/mark-complete?curQuestionNo=' + this.curQuestionNo;

        axios.post(url) 
          .then(res => {
            this.fetchQuestion();
          })
          .catch(() => {
            // do some error handling
          });
      },
      hasNextQuestion () {
        return this.maxQuestions - (this.curQuestionNo + 1) > 0;
      }
    },
    created () {
      this.nextQuestion();      

    }
  }
</script>
Run Code Online (Sandbox Code Playgroud)

在服务器端,我推荐类似以下的方法:

  1. 每个请求向客户发送一个问题
  2. 在 API 将下一个问题返回给客户端之前,请确保用户已回答上一个问题或允许回答问题的时间范围已过。这可以很简单地实现,只需在数据存储中保留一个计数器来记录每个用户最后回答(或过期)的问题编号。不应允许用户回答等于或小于记录中的数量的问题。服务器应该只发送比记录中的数字大一的问题编号。

示例代码(不确定 Laravel 5 语法,但你应该明白):

Route::get('question', function(){
    $curQuestionNo = intVal(Input::get('curQuestionNo'));
    $user = User::find($userId); // get the logged in user, for example
    if($user->current_question_number === $curQuestionNo) {
      $question = Question::where('question_no', $curQuestionNo + 1);
      $question->sent_at = time(); // store the time when the question was sent
      return $question
    } else {
      // deny access
    }
});

Route::post('mark-complete', function(){
    $curQuestionNo = intVal(Input::get('curQuestionNo'));
    $user = User::find($userId); // get the logged in user, for example
    $question = Question::find($curQuestionNo);
    if($question->sent_at > 120 seconds) {
     // do not record answers
    } else {
      // record answers
    }
    $user->current_question_number = $curQuestionNo;
    $user->save();
});    
Run Code Online (Sandbox Code Playgroud)