将像document.cookie这样的字符串转换为对象

20

我有一个类似于document.cookie的字符串:

var str = 'foo=bar, baz=quux';

将其转换为数组非常容易:

str = str.split(', ');
for (var i = 0; i < str.length; i++) {
    str[i].split('=');
}

它会产生类似这样的结果:

[['foo', 'bar'], ['baz', 'quux']]

转换为对象(在这种情况下更为合适)较为困难。

str = JSON.parse('{' + str.replace('=', ':') + '}');

这将产生一个无效的对象,如下所示:

{foo: bar, baz: quux}

我想要这样一个对象:

{'foo': 'bar', 'baz': 'quux'}

注意:在我的示例中,我使用了单引号。但是,如果您正在使用JSON.parse(),请记住,当发布您的代码时,它需要双引号而不是单引号。


更新

感谢大家。这里是我将使用的函数(供以后参考):

function str_obj(str) {
    str = str.split(', ');
    var result = {};
    for (var i = 0; i < str.length; i++) {
        var cur = str[i].split('=');
        result[cur[0]] = cur[1];
    }
    return result;
}

这是为一个真实项目,还是一次高尔夫风格问题的尝试? - ircmaxell
4
我会将其拆分为 ','(没有空格),然后对各部分进行修整,而不是拆分成 ', '(注意空格)。这样可以使输入字符串中美化所用的 0、1、2、.. 个空格或制表符无关紧要。 - Stijn de Witt
如果浏览器能够实现一个对象版本的cookie,那就太好了。比如cookieObject这样的东西会很不错。 - KyleFarris
13个回答

34

最短的方式

 document.cookie.split('; ').reduce((prev, current) => {
    const [name, ...value] = current.split('=');
    prev[name] = value.join('=');
    return prev;
  }, {});

似乎是使用reduce的完美情况。 - Buttars
4
这个解决方案的问题在于,如果cookie包含“=”,那么可能会出现问题,特别是当cookie是base64编码时。为了解决这个问题,可以采用以下方法:const [name, ...value] = current.split('='); prev[name] = value.join('=') - Tobias Bergkvist

13
为什么你需要在这里使用 JSON.parse?修改你的数组示例

为什么您需要在这里使用 JSON.parse?修改您的数组示例。

let str = "foo=bar; baz=quux";

str = str.split('; ');
const result = {};
for (let i in str) {
    const cur = str[i].split('=');
    result[cur[0]] = cur[1];
}


console.log(result);


这会产生 ['foo=bar', 'baz=quux'],但我需要一个 对象 - alexia
@Nyuszika7H 不,那会生成一个对象而不是数组。你不能在数组上执行 result['foo'] - Nikita Rybak
@Nyuszika7H - 不,这正是你要求的,就像我的非常相似的例子一样。 - Alnitak
抱歉,我没有看到对象在“result”变量中。谢谢! - alexia
请注意,如果任何“cookie”包含cookie分隔符,则此操作将失败;这可能不是问题,但如果您使用cookie进行更复杂的数据(例如http://stackoverflow.com/questions/10119057)则可能会出现问题。 - ShadSterling

5
使用像URLSearchParamsObject.fromEntries这样的本地方法来解析cookie,避免使用循环和临时变量。

解析document.cookie

Object.fromEntries(new URLSearchParams(document.cookie.replace(/; /g, "&")))

针对此问题的范围(cookies由,分隔,并存储在变量str中)

Object.fromEntries(new URLSearchParams(str.replace(/, /g, "&")))

只提供代码的回答是不被鼓励的。您应该解释您正在做什么以及为什么这样做。 - Kevin

5
注意:document.cookie(问题标题)使用分号而不是逗号进行分隔(问题)...
使用reduce的另一种替代方法:
var str = 'foo=bar; baz=quux';
var obj = str.split(/[;] */).reduce(function(result, pairStr) {
  var arr = pairStr.split('=');
  if (arr.length === 2) { result[arr[0]] = arr[1]; }
  return result;
}, {});

3

给定一个包含中间形式的数组 a

[['foo', 'bar'], ['baz', 'quux']]

那么就简单地执行以下操作:
var obj = {};
for (var i = 0; i < a.length; ++i) {
   var tmp = a[i];
   obj[tmp[0]] = tmp[1];
}

它并不完全正确,会产生{'foo,bar': ['baz', 'quux']} - alexia
我忘记在最后一行使用 tmp 而不是 a - Alnitak
建议的格式称为“entries”(可枚举的字符串键值对)。将entries转换为对象的更简短的方法是Object.fromEntries([['foo', 'bar'], ['baz', 'quux']]) - undefined
@undefined 在2011年不存在。 - Alnitak
@Alnitak说得有道理,当时没有看到它是2011年的。我仍然会保留这个评论,以便人们知道现在存在这个功能。 - undefined

2

将其转换为对象,只需从一开始就这样做:

var obj = {};
str = str.split(', ');
for (var i = 0; i < str.length; i++) {
    var tmp = str[i].split('=');
    obj[tmp[0]] = tmp[1];
}

然后,如果你想要JSON输出:
var jsonString = JSON.stringify(obj);

2

解析 cookies (IE9+):

document.cookie.split('; ').reduce((result, v) => {
  const k = v.split('=');
  result[k[0]] = k[1];
  return result;
}, {})

1

我是John Resig的"搜索而不替换"方法的粉丝,适用于这种情况:

var str = 'foo=bar, baz=quux',
    arr = [],
    res = '{';

str.replace(/([^\s,=]+)=([^,]+)(?=,|$)/g, function ($0, key, value) { 
    arr.push('"' + key + '":"' + value + '"');
});

res += arr.join(",") + "}";

alert(res);

工作示例:http://jsfiddle.net/cm6MT/

不需要 JSON 支持,这样可以使事情变得简单得多。当然,使用相同的正则表达式与 exec()match() 一样容易。


糟糕,我以为你想将其转换为 JSON 字符串,而不是对象。在这种情况下,您只需要稍微修改代码即可:

var str = 'foo=bar, baz=quux',
    res = {};

str.replace(/([^\s,=]+)=([^,]+)(?=,|$)/g, function ($0, key, value) { 
    res[key] = value;
});
console.log(res.foo);
//-> "bar"

工作示例2: http://jsfiddle.net/cm6MT/1/


请删除示例1!它会返回一个字符串,这很令人困惑!请参见http://jsfiddle.net/pjja75hv/。 - sebilasse

1
大多数上述解决方案在处理Google设置的__gads cookie时失败,因为它在cookie值中使用了'='字符。
解决方案是使用正则表达式而不是调用split('=')函数:
document.cookie.split(';').reduce((prev, current) => {
  const [name, value] = current.split(/\s?(.*?)=(.*)/).splice(1, 2);
  prev[name] = value;
  return prev;
}, {});

或者只需执行 const [name, ...value] = current.split('='); prev[name] = value.join('=') - Tobias Bergkvist
1
你还需要移除前导空格,就像 prev[name.slice(1)] = value.join('=') 中的一样。 - Dave

0

更新解决方案的另一版本,检查空字符串并返回空对象,并允许自定义分隔符。

function stringToObject(str, delimiter) {
    var result = {};
    if (str && str.length > 0) {
        str = str.split(delimiter || ',');
        for (var i = 0; i < str.length; i++) {
            var cur = str[i].split('=');
            result[cur[0]] = cur[1];
        }
    }
    return result;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接