检查 Javascript 中的正整数:性能和安全性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13219926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 18:06:51  来源:igfitidea点击:

Check for positive integers in Javascript: performance and security

javascriptjqueryjquery-selectorsjavascript-security

提问by Lucky Soni

I have written (and copied) a few lines of Javascript and it serves my purpose well. But I am trying to figure out a better way (cross-browser and better performance) of doing this. I copied the isIntegerfunction from a friend but I do not understand why we are checking against a string value in the following condition:

我已经编写(并复制)了几行 Javascript,它很好地满足了我的目的。但我正试图找出一种更好的方法(跨浏览器和更好的性能)来做到这一点。我isInteger从朋友那里复制了该函数,但我不明白为什么我们要在以下条件下检查字符串值:

if (((c < "0") || (c > "9"))) return false;

The above condition works fine but when I change it to check against number values, the functionality breaks. The input field starts accepting alphabetical characters. Here is how it looks when I change it:

上述条件工作正常,但是当我更改它以检查数字值时,功能会中断。输入字段开始接受字母字符。这是我更改它时的外观:

if ((( c < 0 ) || ( c > 9 ) return false;

I have tried to comment out sections so that you can understand what's happening. Also are there any security holes in this code? I read that the 1innerHTML1 method can open some security holes and hence we need to perform a 'clean' operation with it. Hence I chose to use jQuery's .htmlmethod (I am new to JavaScript)

我试图注释掉部分,以便您了解正在发生的事情。这段代码中还有安全漏洞吗?我读到 1innerHTML1 方法可以打开一些安全漏洞,因此我们需要对它执行“干净”操作。因此我选择使用 jQuery 的.html方法(我是 JavaScript 新手)

The page in question: http://thehotdeal.net/clients/wehtmlit/index.php?order/

有问题的页面:http: //thehotdeal.net/clients/wehtmlit/index.php?order/

$(document).ready(function() {
  var total = 0;
  function calcTotal() {
  /* fetching some values from PHP variables and then performing calculations.
    essentially this is multiplying number of pages by price per page
  */
  /* <![CDATA[ */
    var total_price_main_pages = ($("#pages").attr("value")) * (<?php echo $main_price; ?>),
    total_price_sub_pages = ($("#subpages").attr("value")) * (<?php echo $sub_price; ?>);
    /*  ]] > */
    $("input.calculate:checked").each(function() {
    // This happens for each checked input field
    // These are few additional otions available to the user. If selected then
    // the price stored in their "data" attribute is added to the total
      var value = $(this).attr("data");
      total += parseInt(value); 
    });
    total += (parseInt(total_price_main_pages)) + (parseInt(total_price_sub_pages));
    $("#total").html("Total: <strong>" + total + "</strong>");
  }
  // This happens when the page loads
  calcTotal();
  $("input.calculate").click(function() {
    total = 0;
    calcTotal();
  });
  // function to check if an input is positive number(s). returns true if [ 0 <= s <= 9 ]
  function isInteger(s) {
    var i;
    for (i = 0; i < s.length; i++) {
      var c = s.charAt(i);
      if (((c < "0") || (c > "9"))) return false;
    }
    return true;
  }
  // Checking the mainpage input (default value 1)
  // (valid value is greater than or equal to 1 and less than 10)
  $("#pages").keyup(function() {
    var page = $(this).val();
    // if user deletes the value in this input (blank)
    // then just display a warning message and do nothing
    if(page == ""){
      this.value = "";
      $("#pageError").html("Please enter a value equal or greater than 1.");
      return false;
    }
    // if value is less than or equal to zero then
    // then set 1 as the new value, remove the error message and call the calcTotal function
    else if(page <= 0){
      this.value =1;
      $("#pageError").empty();
      total = 0;
      calcTotal();
    }
    // check if value is not a positive integer by calling the isInteger function
    // if not a positive integer then set 1 as the new value,
    //remove the error message and call the calcTotal function
    else if(!isInteger(page)){
      this.value =1;
      $("#pageError").empty();
      total = 0;
      calcTotal();
    }
    // if value does not fall in any of the if statements i.e. value is acceptable
    // remove the error message and call the calcTotal function
    $("#pageError").empty();
    total = 0;
    calcTotal();
  });
  // check if value is not empty when user exits the input
  // if empty then set value as 1, remove error message and call calcTotal function
  $("#pages").blur(function() {
    var page = $(this).val();
    if(page == ""){
      this.value = 1;
      $("#pageError").empty();
      total = 0;
      calcTotal();
    }
  });
  // Checking the subpage input (default value 0)
  // (valid value is greater than or equal to 0 but less than 10)
  $("#subpages").keyup(function() {
    var page = $(this).val();
    if(page == ""){
      this.value = "";
      return false;
    } else if(!isInteger(page)){
      this.value = 0;
      total = 0;
      calcTotal();
    }
    total = 0;
    calcTotal();
  });
  $("#subpages").blur(function() {
    var page = $(this).val();
    if(page == ""){
      this.value = 0;
      total = 0;
      calcTotal();
    }
  });
});

回答by Matt Ball

i do not understand why we are checking against a string value in the following condition

我不明白为什么我们要在以下条件下检查字符串值

Because cis a character (really, a 1-character string), since that's what String.charAtreturns. That said, the isIntegerfunction could be written much more simply using a regex:

因为c是一个字符(实际上是一个 1 个字符的字符串),因为这就是String.charAt返回的内容。也就是说,isInteger可以使用正则表达式更简单地编写函数:

function isPositiveInteger(s)
{
    return !!s.match(/^[0-9]+$/);
    // or Rob W suggests
    return /^\d+$/.test(s);
}

or you could take another approach: convert the string to a number, make sure it's positive, and make sure that the floor of the number is the same as the original (thus it's an integer):

或者您可以采取另一种方法:将字符串转换为数字,确保它是正数,并确保数字的下限与原始数字相同(因此它是一个整数):

function isPositiveInteger(s)
{
    var i = +s; // convert to a number
    if (i < 0) return false; // make sure it's positive
    if (i != ~~i) return false; // make sure there's no decimal part
    return true;
}

回答by jAndy

What about..

关于什么..

if( +inputString > 0 ) {
}

if its just about finding out if the input is a positive integer. If you also don't want to allow numbers with decimal points / floating point values, you should do with with input field validation like

如果它只是找出输入是否为正整数。如果您也不想允许带有小数点/浮点值的数字,则应该使用输入字段验证,例如

<input type="text" pattern="\d+" required/>

This tells the inputfield to only only numbers. The requiredflag is optional, if present it won't allow any submitbutton to continue unless all patternsare satisfied.

这告诉输入字段只有数字。该required标志是可选的,如果存在,它将不允许任何提交按钮继续,除非满足所有模式