假设www.mydomain.com?param1=example
为例。
存储第二个参数(键值对列表)的最佳方法是什么?在那一刻我使用¶m2=key|value,key|value
。我使用垂直线将键与值分开,并使用逗号配对,等于之后的所有内容都使用encodeURIComponent()
进行编码。这很好用。
然而,用户可以控制价值......而作为明智的人,我们都知道用户可能做的第一件事就是将垂直条或逗号作为破坏我的参数解析器的值之一。有一个更好的方法吗?我见过PHP用户正在讨论在URL中存储相关数组,但我正在寻找一个纯javascript解决方案。
答案 0 :(得分:6)
PHP(和其他服务器端语言)支持在查询字符串中传递数组。
www.mydomain.com?param1=example¶m2[key1]=value1¶m2[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¶m2[]=value1¶m2[]=value2
将被解析为:
array(2) {
["param1"]=>
string(7) "example"
["param2"]=>
array(2) {
[0]=>
string(6) "value1"
[1]=>
string(6) "value2"
}
}
更新:您还可以在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¶m2[]=value1¶m2[]=value2');
。
答案 1 :(得分:0)
一种可能的解决方案是在将用户输入发布到您的网址之前转义用户输入中的管道和逗号。
这意味着要清理用户输入值并将|
和,
替换为不会破坏代码或完全剥离代码的内容。
答案 2 :(得分:0)
为防止偶然篡改,您可以添加校验和,然后对您的值进行base-64编码,然后使用encodeURIComponent()生成字符串。 (请参阅How can you encode to Base64 using Javascript?和A JavaScript CRC32。)
当然,这并不能阻止那些真正决定诋毁你的价值观的人,但这会让那些只想改变网址的人感到沮丧。
答案 3 :(得分:-1)
当我想到序列化键值对列表时,我立即想到使用查询字符串。
对于基础知识(用于显示反序列化的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
}
尽管如此,在编码/解码时很容易出错,并且只要你开始双重编码和双重解码,你就可以保证遇到问题。如果可以,请使用单个查询字符串来包含所有必需的数据,并且不要在查询字符串中嵌入查询字符串。