Storing a list of key value pairs in a url paramet

2019-07-07 04:16发布

Assuming www.mydomain.com?param1=example as an example.

What is the best way to store a second parameter that is a list of key value pairs? At the minute I use &param2=key|value,key|value. I separate the key from the value using a vertical line, and the pairing with a comma, everything after the equals is encoded using encodeURIComponent(). This works fine.

However, the user has control of the value... And as sensible human beings we all know that the first thing the user will probably do is stick a vertical bar or a comma as one of the values breaking my parameter parser. Is there a better way to do this? I've seen PHP users talking about storing associated arrays in urls but I'm looking for a pure javascript solution.

4条回答
放荡不羁爱自由
2楼-- · 2019-07-07 04:52

To prevent casual tampering, you could add a checksum and base-64 encode your values then encodeURIComponent() the resulting string. (See How can you encode to Base64 using Javascript? and A JavaScript CRC32.)

Of course, this won't prevent someone who's really determined from messing with your values, but it will slow down people who just like to twiddle URLs.

查看更多
萌系小妹纸
3楼-- · 2019-07-07 05:00

A possible solution would be to escape the pipe and commas in the user input before posting them to your url.

That means sanitising the user input values and replacing | and , with something that doesn't break your code or just stripping them altogether.

查看更多
Summer. ? 凉城
4楼-- · 2019-07-07 05:07

PHP (and other server-side languages) support passing arrays in the query string.

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

PHP will parse the GET string as such:

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

If you don't pass keys, it will be become a numeric array:

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

Will be parsed as:

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

UPDATE: You can also parse the query string in JavaScript.

Here is a simple jQuery plugin I made:

$.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;
};

Then you can do: $.parseQuery('param1=example&param2[]=value1&param2[]=value2');.

查看更多
时光不老,我们不散
5楼-- · 2019-07-07 05:12

When I think of serializing a list of key-value pairs, I immediately think of using a query-string.

For basics (JSON used to show deserialization):

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

is essentially:

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

But special characters have to be escaped:

foo=bar%26baz

is essentially:

{
    foo: 'bar&baz'
}

What this means is that you can pass a query-string as a value in another query-string:

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

is essentially:

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

And foo can be parsed to produce:

{
    bar: baz,
    fizz: buzz
}

That all being said, it's very easy to make mistakes while encoding/decoding, and as soon as you start double-encoding and double-decoding you're guaranteed to run into issues. If you can, use a single query string to contain all the necessary data, and don't embed a query-string within a query-string.

查看更多
登录 后发表回答