首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这段JavaScript代码安全吗?

这段JavaScript代码安全吗?
EN

Stack Overflow用户
提问于 2011-08-05 04:21:46
回答 3查看 656关注 0票数 1

我在网上找到了下面的JS。

它是一个获取url参数值的函数。

代码语言:javascript
复制
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()函数时,我总是会想:哇!

所以我的问题是:它安全吗?

另外:如果你认为这个函数很烂,并且有更好的选择,请毫不犹豫地分享:)

上面的函数使用了真实的URL,但我只需要解析一个包含url的字符串。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-05 05:47:04

Regexp#exec是安全的,尽管不是一个很好的界面。

Side bet:如果你认为这个函数很烂,并且有更好的选择,请毫不犹豫地分享:)

是:-)

代码语言:javascript
复制
param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");

这不使用g全局正则表达式,因此您只需替换每个括号的一个实例;field[][]将不起作用。此外,您不需要字符组...param.replace(/\[/g, '\\[')本可以工作的。或者,非正则表达式替换习惯用法param.split('[').join('\\[')

然后:

代码语言:javascript
复制
var regexS = "[\\?&]"+param+"=([^&#]*)";

您无法转义足够多的字符,从而无法将它们放入regexp中并让它们表示其字面上的自我。有关更严密的替代方案,请参阅this question

无论如何,这种正则表达式攻击仍然不是解析URL/查询字符串的好方法。这不能正确处理;%-encoding,或者+中的空间,并且它可能会在URL中其他地方的参数外观上出错。

相反,让我们首先自己获取查询字符串。如果您有链接或位置对象,则可以从.search属性中获取它。如果您只有一个字符串URL,您可以将其转换为链接对象,以可靠地获取以下内容:

代码语言:javascript
复制
function getQueryString(url) {
    var a= document.createElement('a');
    a.href= url;
    return a.search;
}

现在您可以通过删除前导?,在&;上拆分,然后将URL解码的结果放入JS对象中,将其解析为:

代码语言:javascript
复制
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;
}

这使得查找参数变得很容易:

代码语言:javascript
复制
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,在查找中返回单个字符串值,而不是列表。

票数 2
EN

Stack Overflow用户

发布于 2011-08-05 04:23:07

您在函数中看到的.exec()不是窗口的,而是RegExp对象的。

所以使用它是非常好的。

票数 4
EN

Stack Overflow用户

发布于 2011-08-05 04:25:07

我不会将Regexp execeval混淆。有点笨拙,但应该能行得通。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6948053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档