【问题标题】:Check array for duplicate values if cookies aren't set, don't check if cookies are set如果未设置 cookie,则检查数组是否存在重复值,不检查是否设置了 cookie
【发布时间】:2018-11-30 18:51:23
【问题描述】:

我正在处理一个聊天室页面,您首先在其中设置用户名,然后在 cookie 中设置用户名值。在此之后,它会加载不同的输入框,您可以在其中实时发送消息。此时您可以重新加载页面,它会给您一个弹出窗口,其中将显示一条欢迎返回消息,其中包含保存在 cookie 中的名称值,这也将再次将其设置为用户名并加载聊天页面。

问题是我希望能够防止从用户名设置输入字段中设置名称的多个重复项,但允许通过 cookie 在数组内多次设置用户名。

这个函数设置原始用户名:

//index.html
function setUsername() {
    var textbox = document.getElementById("name");
    var txtboxval = textbox.value;
    if(textbox.value.length <= 20 && textbox.value.length >= 4){
      socket.emit('setUsername', document.getElementById('name').value);
      setCookie("username", txtboxval, 30);
      socket.on('userExists', function(data) {

      });
    }
    else{
        alert("The name has to be at least 4 characters long");
        return false;
      }
    };

这两个将其设置为 cookie 加载:

  //index.html
  function setUsername2() {
    var nimi = getCookie('username');
    socket.emit('setUsername', nimi);
  }

  function checkCookie() {
      var user = getCookie("username");
      if (user != "") {
          alert("Welcome again " + user);
          setUsername2();
          document.body.innerHTML = '<div class="wrapper"><div class="messagebox"><input type = "text" id = "message" placeholder = "Write your message here">\
          <button type = "button" id="sending" name = "button" onclick = "sendMessage()">Send</button></div>\
          <div id = "message-container"></div></div>';
      }
    }

现在这里实际上将用户名设置到从 index.html 页面上挖掘它的数组中:

  //app.js
  users = [];
  io.on('connection', function(socket){
    console.log('an user connected');
    console.log(users);
    socket.on('setUsername', function(data) {
      console.log(data);

        users.push(data);
        socket.emit('userSet', {username: data});
        console.log(users);
  });

我希望在第一次设置用户名时运行这段代码,而不是在从 cookie 加载时运行:

//app.js
if(users.indexOf(data) > -1) {
          socket.emit('userExists', data + ' Username is already taken.');
        } else {
          users.push(data);
          socket.emit('userSet', {username: data});
          console.log(users);
        }

为什么我不能让它像我希望的那样工作,有什么我遗漏的吗?如果有什么不清楚的地方请追问。

【问题讨论】:

    标签: javascript node.js cookies socket.io


    【解决方案1】:

    您可以使用对象{name: string, cookie: boolean} 而不是仅使用用户名来触发您的'setUsername',就像我在这里所做的那样:

    function setUsername() {
      var textbox = document.getElementById("name");
      var txtboxval = textbox.value;
      if(textbox.value.length <= 20 && textbox.value.length >= 4){
        socket.emit('setUsername', {name: document.getElementById('name').value, cookie: false});
        setCookie("username", txtboxval, 30);
        socket.on('userExists', function(data) {
          // ########## you could add your 'already taken'-message here. :) ##########
          console.log(data);
          document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; 
          // this 'deletes' the cookie.
        });
      } else {
        alert("The name has to be at least 4 characters long");
        return false;
      }
    }
    

    function setUsername2() {
      var nimi = getCookie('username');
      socket.emit('setUsername', {name: nimi, cookie: true});
    }
    
    function checkCookie() {
      var user = getCookie("username");
      if (user != "") {
        alert("Welcome again " + user);
        setUsername2();
        document.body.innerHTML = '<div class="wrapper"><div class="messagebox"><input type = "text" id = "message" placeholder = "Write your message here">\
        <button type = "button" id="sending" name = "button" onclick = "sendMessage()">Send</button></div>\
        <div id = "message-container"></div></div>';
      }
    }
    

    users = [];
    io.on('connection', function(socket){
      console.log('an user connected');
      console.log(users);
      socket.on('setUsername', function(data) {
        console.log(data);
    
        if(!data.cookie && users.indexOf(data.name) > -1) {
          socket.emit('userExists', data.name + ' Username is already taken.');
        } else {
          users.push(data.name);
          socket.emit('userSet', {username: data.name});
          console.log(users);
        }
      });
    });
    

    【讨论】:

    • 这给了我尝试设置名称时的参考错误,“未捕获的 ReferenceError:setUsername 未在 HTMLButtonElement.onclick 中定义”和“(索引):291 未捕获的 ReferenceError:checkCookie 未在 onload 定义”它还说在 setUsername 函数的某个地方有一个缺失)我找不到它。
    • 语法错误现已修复。我的错。 :)
    • ah :),我在语法修复后尝试过,这确实有效,还有 1 件事,我可以在哪里给出一条消息,说该名称已在使用中?
    • socket.on('setUsername' […]函数内,在socket.emit('userExists', data.name + ' Username is already taken.');之下或之上
    • 刚刚试了一下,这行得通,我没有看到任何问题,所以非常感谢你,我已经被这个问题困扰了好几天了!非常感谢!一旦可用,我会将赏金奖励给你:)
    【解决方案2】:

    如果我做对了,并且你想区分两个活动 - 从 cookie 设置用户名和从 input#name 设置用户名 - 所以你只需要发出带有一些额外数据的 userExists一些标志,例如 cookie (这意味着您正在设置来自 cookie 的值)或 user_input (这意味着您正在设置来自输入字段的值),像这样:

    socket.emit('userSet', {username: data.name, user_input: true});
    

    【讨论】:

    • 介意举一个关于我应该怎么做的例子吗?我不完全明白我将如何构建语法。
    • @Veraen,第一部分:您有 2 种设置 cookie 的方法 - 来自输入和来自 cookie。第二部分:你捕获 userSet 事件并从中提取价值。但是你不能说这个事件是从哪里来的。所以你必须在其中添加额外的数据,以便能够说出它来自哪里:来自输入或来自 cookie。现在,当您可以区分用户名来源时,您可以决定是否要发出 userExists 或不发出。就是这样!
    • 感谢您的回答!但我从 J. Sadi 的回答中得到了解决方案。
    猜你喜欢
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    相关资源
    最近更新 更多