Этот код JavaScript безопасен? - PullRequest
       3

Этот код JavaScript безопасен?

1 голос
/ 05 августа 2011

Я нашел следующий JS в сети.

Это функция для получения значений параметров url.

function get_url_param(param) {
  param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+param+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec(window.location.href);
  if( results == null )
    return '';
  else
    return results[1];
}

Однако всегда, когда я вижу функцию exec(), я думаю,: Eeek!

Итак, мой вопрос: это безопасно?

Дополнительная ставка: Если вы думаете, что эта функция отстой и у вас есть лучший вариант, не стесняйтесь поделиться:)

Приведенная выше функция использует реальный URL, но мне нужно только проанализировать строку, содержащую URL.

Ответы [ 3 ]

4 голосов
/ 05 августа 2011

* * * * * .exec(), который вы видите в своей функции, относится не к окну, а к объекту RegExp.

Таким образом, он идеально подходит для использования.

3 голосов
/ 05 августа 2011

Я бы не перепутал регулярное выражение exec с eval. Немного неуклюже, но это должно сработать.

2 голосов
/ 05 августа 2011

Regexp#exec - безопасный, хотя и не очень приятный интерфейс.

Дополнительная ставка: если вы считаете, что эта функция отстой и у вас есть лучший выбор, не стесняйтесь делиться:)

даааа: -)

param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");

Это не использует g lobal регулярное выражение, поэтому вы заменяете только один экземпляр каждой скобки; field[][] не сработает. Также вам не нужна группа персонажей ... param.replace(/\[/g, '\\[') сработало бы. Или идиома замены без регулярных выражений, param.split('[').join('\\[').

Тогда:

var regexS = "[\\?&]"+param+"=([^&#]*)";

вы не можете избежать почти достаточного количества символов, чтобы иметь возможность бросить их в регулярное выражение и сделать так, чтобы они означали их буквальное "я". См. этот вопрос для более водонепроницаемой альтернативы.

В любом случае, этот вид взлома регулярных выражений все еще не является хорошим способом парсинга URL / строк запроса. Это неправильно работает с ; или % -кодированием, или + для пробела, и это может привести к срабатыванию аналогичных параметров в других местах URL.

Вместо этого давайте сначала получим строку запроса самостоятельно. Если у вас есть ссылка или объект местоположения, вы можете получить его из свойства .search. Если у вас есть только строковый URL, вы можете превратить его в объект ссылки, чтобы получить его надежно:

function getQueryString(url) {
    var a= document.createElement('a');
    a.href= url;
    return a.search;
}

Теперь вы можете разобрать его, отбросив ведущий ?, разделив его на & или ;, а затем отбросив результаты, декодированные по URL, в объект JS:

function parseQuery(query) {
    var lookup= {};
    var params= query.slice(1).split(/[&;]/);
    for (var i= 0; i<params.length; i++) {
        var ix= params[i].indexOf('=');
        if (ix!==-1) {
            var name= decodeURIComponent(params[i].slice(0, ix));
            var value= decodeURIComponent(params[i].slice(ix+1));
            if (!(name in lookup))
                lookup[name]= [];
            lookup[name].push(value);
        }
    }
    return lookup;
}

Это упрощает поиск параметров:

var url= 'http://www.example.com/?a=b&c=d&c=%65;f[]=g#h=i';
var pars= parseQuery(getQueryString(url));

alert(pars.a);      // ['b']
alert(pars.c);      // ['d', 'e']
alert(pars['f[]']); // ['g']
alert('h' in pars); // false

Если вам не нужно читать несколько значений для параметра, вы можете просто сделать lookup[name]= value вместо if...[]...push dance, чтобы вернуть единственные строковые значения в поиске вместо списков.

...