【问题标题】:Converting strings like document.cookie to objects将 document.cookie 等字符串转换为对象
【发布时间】:2011-06-30 03:51:12
【问题描述】:

我有一个类似于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;
}

【问题讨论】:

  • 这是一个真实的项目,还是一个高尔夫风格问题的尝试?
  • 我不会在', ' 上拆分(注意空格),而是在','(没有空格)上拆分,然后在trim 上拆分各个部分。这使得是否使用 0、1、2、.. 空格甚至制表符来“美化”输入字符串变得不重要了。
  • 如果浏览器只实现cookie的对象版本当然会很好。像cookieObject 这样的东西会很好。

标签: javascript arrays string object


【解决方案1】:

为什么你在这里需要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'],但我需要一个对象
  • @Nyuszika7H 不,这会产生一个对象而不是数组。你不能在数组上做result['foo']
  • @Nyuszika7H - 不,这完全符合您的要求,就像我非常相似的示例一样。
  • 抱歉,我没有看到该对象在result 变量中。谢谢!
  • 请注意,如果任何“cookie”包含cookie分隔符,这将失败;这可能不是问题,但如果您将 cookie 用于更复杂的数据(例如在 stackoverflow.com/questions/10119057 中),则可能会出现问题。
【解决方案2】:

给定一个数组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']}
  • 已更正 - 我忘记在最后一行使用 tmp 而不是 a
  • 建议的格式称为entries(可枚举的字符串键属性对)。将条目转换为对象的更短的方法是 Object.fromEntries([['foo', 'bar'], ['baz', 'quux']])
  • @undefined 在 2011 年不存在。
  • @Alnitak 是有道理的,当时没有看到它是 2011 年。我仍然会在此处保留评论,以便人们知道此功能现在存在
【解决方案3】:

要将其转换为对象,只需从头开始:

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);

【讨论】:

    【解决方案4】:

    这是非常糟糕的数据,只要它不使用 ,= 这将适用于该数据

    var text = 'foo=bar, baz=quux',
        pattern = new RegExp(/\b([^=,]+)=([^=,]+)\b/g),
        obj = {};
    
    while (match = pattern.exec(text)) obj[match[1]] = match[2];
    
    console.dir(obj);
    

    【讨论】:

      【解决方案5】:

      我很喜欢 John Resig 的 "Search and don't replace" 方法:

      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/

      【讨论】:

      【解决方案6】:

      更新解决方案的替代版本,检查空/空字符串,只返回一个空对象,还允许自定义分隔符。

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

      【讨论】:

        【解决方案7】:

        注意: 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;
        }, {});
        

        【讨论】:

          【解决方案8】:

          解析 cookie (IE9+):

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

          【讨论】:

            【解决方案9】:

            最短路径

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

            【讨论】:

            • 似乎是使用 reduce 的完美情况。
            • 这个解决方案的一个问题是cookie是否包含“=”。如果 cookie 是 base64 编码的,这通常会发生。要解决这个问题:const [name, ...value] = current.split('='); prev[name] = value.join('=')
            【解决方案10】:

            一种使用诸如URLSearchParamsObject.fromEntries 等本机方法解析cookie 的方法,避免循环和临时变量。

            解析document.cookie:

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

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

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

            【讨论】:

            • 不鼓励只回答代码,你应该解释你在做什么以及为什么
            【解决方案11】:

            我想到的第一件事,我将它保留为原始版本,但cookie不应为空,否则会出现json解析错误

            JSON.parse(`{"${document.cookie.replace(/=/g,'":"').replace(/; /g,'","')}"}`)
            

            快速可靠的版本 - cookie 到对象

            let c=document.cookie.split('; '),i=c.length,o={};
            while(i--){let a=c[i].split('=');o[a[0]]=a[1]}
            

            获取单个cookie的短函数

            getCookie=e=>(e=document.cookie.match(e+'=([^;]+)'),e&&e[1])
            

            【讨论】:

            • 也许for (let a of c) 会更好。更具可读性并避免创建临时 i 变量。
            【解决方案12】:

            上述大多数解决方案都因 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('=')
            • 还需要去掉前导空格,如prev[name.slice(1)] = value.join('=')
            【解决方案13】:
            function getCookie(){
               var o=document.cookie.split("; ");
               var r=[{}];
               for(var i=0;i<o.length;i++){
                  r[o[i].split("=")[0]] = o[i].split("=")[1];
               }
               return r;
            }
            

            只需调用getCookie(),它就会返回当前网站的所有cookies。 如果您有一个名为“mycookie”的cookie,您可以运行getCookie()['mycookie'];,它将返回cookie“mycookie”的值。 还有一个单行选项:

            function getCookie(){var o=document.cookie.split("; ");var r=[{}];for(var i=0;i<o.length;i++){r[o[i].split("=")[0]] = o[i].split("=")[1];}return r;}
            

            这个可以和上面一样使用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-01-14
              • 2011-08-02
              • 2016-06-10
              相关资源
              最近更新 更多