【问题标题】:Storing a list of key value pairs in a url parameter, javascript.在 url 参数 javascript 中存储键值对列表。
【发布时间】:2012-08-24 04:51:32
【问题描述】:

以www.mydomain.com?param1=example为例。

存储作为键值对列表的第二个参数的最佳方式是什么?目前我使用&param2=key|value,key|value。我使用垂直线将键与值分开,并用逗号配对,等号之后的所有内容都使用encodeURIComponent() 进行编码。这工作正常。

但是,用户可以控制该值...作为明智的人,我们都知道用户可能会做的第一件事是将竖线或逗号作为破坏我的参数解析器的值之一。有一个更好的方法吗?我见过 PHP 用户谈论在 url 中存储关联数组,但我正在寻找 纯 javascript 解决方案。

【问题讨论】:

标签: javascript jquery url url-parameters


【解决方案1】:

PHP(和其他服务器端语言)支持在查询字符串中传递数组。

www.mydomain.com?param1=example&param2[key1]=value1&param2[key2]=value2

PHP 会这样解析 GET 字符串:

array(2) {
  ["param1"]=>
  string(7) "example"
  ["param2"]=>
  array(2) {
    ["key1"]=>
    string(6) "value1"
    ["key2"]=>
    string(6) "value2"
  }
}

如果不传键,就会变成数值数组:

www.mydomain.com?param1=example&param2[]=value1&param2[]=value2

会被解析为:

array(2) {
  ["param1"]=>
  string(7) "example"
  ["param2"]=>
  array(2) {
    [0]=>
    string(6) "value1"
    [1]=>
    string(6) "value2"
  }
}

UPDATE:也可以用 JavaScript 解析查询字符串。

这是我制作的一个简单的 jQuery 插件:

$.parseQuery = function(str) {
    var ret = {};
    $.each(str.split("&"), function() {
        var data = this.split('='),
            name = decodeURIComponent(data.shift()),
            val = decodeURIComponent(data.join("=")).replace('+', ' '),
            nameVal = name.match(/(.*)\[(.*)\]/);

        if (nameVal === null) {
            ret[name] = val;
        }
        else {
            name = nameVal[1];
            nameVal = nameVal[2];
            if (!ret[name]) {
                ret[name] = nameVal ? {} : [];
            }
            if ($.isPlainObject(ret[name])) {
                ret[name][nameVal] = val;
            }
            else if($.isArray(ret[name])){
                ret[name].push(val);
            }
        }
    });
    return ret;
};

那么你可以这样做:$.parseQuery('param1=example&param2[]=value1&param2[]=value2');。

【讨论】:

  • 仅使用 Javascript 可以做到这一点吗?以这种方式解析get字符串?参数仅用于查询本地数据。我实际上只是使用参数来允许用户为过滤后的数据添加书签
  • @CrimsonChin:是的。 window.location.search 包含获取字符串。然后,您可以在 JavaScript 中解析它。你可以使用我写的这个方法:gist.github.com/3528917 :-)(注意:window.location.search 包含?,你需要这样称呼它:$.parseQuery(window.location.search.substring(1)))。
  • 我无权访问查询字符串 - 我认为这是 JQM 的事情,因为 # 标记。话虽如此,我可以拆分 window.location.href 以获取查询字符串,并且您的 github 代码运行良好。我可以建议将代码放入您的答案中吗?我认为它对问题/答案非常有价值。它是你的代码,所以选择是你的。无论哪种方式都感谢
【解决方案2】:

为防止随意篡改,您可以添加校验和并对您的值进行 base-64 编码,然后对结果字符串进行编码URIComponent()。 (见How can you encode to Base64 using Javascript?和A JavaScript CRC32。)

当然,这并不能阻止那些真正有决心的人来搞乱你的价值观,但它会减慢那些喜欢玩弄 URL 的人的速度。

【讨论】:

    【解决方案3】:

    当我想到序列化键值对列表时,我立即想到使用查询字符串。

    基础知识(用于显示反序列化的 JSON):

    foo=bar&foo=baz&fizz=buzz&alpha&beta=
    

    本质上是:

    {
        foo: [
            'bar',
            'baz'
        ],
        fizz: 'buzz',
        alpha: null,
        beta: ''
    }
    

    但特殊字符必须转义:

    foo=bar%26baz
    

    本质上是:

    {
        foo: 'bar&baz'
    }
    

    这意味着您可以将查询字符串作为值传递给另一个查询字符串:

    foo=bar%3Dbaz%26fizz%3Dbuzz
    

    本质上是:

    {
        foo: 'bar=baz&fizz=buzz'
    }
    

    而foo可以解析产生:

    {
        bar: baz,
        fizz: buzz
    }
    

    话虽如此,编码/解码时很容易出错,而且一旦开始双重编码和双重解码,肯定会遇到问题。如果可以,请使用单个查询字符串来包含所有必要的数据,并且不要在查询字符串中嵌入查询字符串。

    【讨论】:

      【解决方案4】:

      一种可能的解决方案是在将用户输入中的管道和逗号发布到您的网址之前对其进行转义。

      这意味着清理用户输入值并将| 和, 替换为不会破坏您的代码或完全剥离它们的东西。

      【讨论】:

      • 问题是值是查询参数,他们需要匹配他们正在查询的数据
      • 您需要在途中进行某种编码/解码。请记住,& 符号也会破坏您的数组。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      • 1970-01-01
      相关资源
      最近更新 更多