分割并解析window.location.hash

26
我在正确分割和解析window.location.hash时遇到了问题。
首先,我们在hash中获取了一些参数,例如:
#loc=austria&mr=1&min=10&max=89

正如你所看到的,它是为搜索而创建的。当用户点击分页链接时,页面会重新加载并带有哈希值。到目前为止,一切都很好。
我创建了一个名为initialise()的函数,每当URL中有哈希值时就会调用它。
if (window.location.hash) {
    var params = (window.location.hash.substr(1)).split("&");

    for (i = 0; i < params.length; i++)
    {
        var a = params[i].split("=");
        // Now every parameter from the hash is beind handled this way
        if (a[0] == "loc")
        {
            locationList(a[1]);
        }
    }
}

       

每件事情都几乎运行正常... 当我选择所有搜索参数时,哈希值被截断了。对我来说原因未知。我尝试使用if( params.indexOf('loc') )而不是a[0] == "loc",但没有任何运气。
你能帮我一下吗? 编辑
当然,我在循环中使用了var a = ...,这只是复制粘贴错误。

当我选择所有搜索参数时,哈希被截断了。我不理解这句话... - Felix Kling
当我有这样的哈希值 #loc=austria&mr=1&min=10&max=89,在页面重新加载后它变成了 #loc=austria&mr=1 - user948438237
你尝试过 if( params[i].indexOf('loc') ) 吗? - Clyde Lobo
4个回答

44
如果你只需要哈希表中的loc的值,就不需要使用循环。这个方法也可以。
var lochash    = location.hash.substr(1),
    mylocation = lochash.substr(lochash.search(/(?<=^|&)loc=/))
                  .split('&')[0]
                  .split('=')[1];
if (mylocation) {
   locationList(myLocation);
}

关于页面重新加载后哈希值截断的问题:我个人认为这与你的循环无关。
编辑:一种更现代和更准确的方法:

const result = document.querySelector("#result");
const hash2Obj = "loc=austria&mr=1&test123=test=123&min=10&max=89"
      .split("&")
      .map(v => v.split(`=`, 1).concat(v.split(`=`).slice(1).join(`=`)) )
      .reduce( (pre, [key, value]) => ({ ...pre, [key]: value }), {} );
          
result.textContent += `loc => ${hash2Obj.loc}
----
*hash2Obj (stringified):
${JSON.stringify(hash2Obj, null, ' ')}`;
<pre id="result"></pre>


你是对的。现在我意识到我有一个逻辑错误(即使哈希已经存在,仍调用buildRequestHash()函数)。谢谢。 - user948438237
从技术上讲,如果在值字符串中未转义使用'=',则存在一个小错误...考虑这种情况“#key1=foo=bar,alloc=true&loc=...”。 这不是什么大问题,只是我偶然发现了它。干杯! - Dave Dopson
也匹配 #bloc=thing - Hugo
1
@Hugo:你说得对。"更现代的方法"并不... - KooiInc
小心使用 /(?<=^|&)loc=/ 正则表达式,在 Firefox 和 Safari 上会出现错误。 - Félix Paradis
要处理@DaveDopson报告的问题,您可以将.map(v => v.split("="))替换为.map(v => { const id = v.indexOf('='); return id>-1?[v.slice(0,id),v.slice(id+1)]:[v,true];}) - undefined

19

这是一个比较简单从location.hash读取的方式:

    var hash = window.location.hash.substring(1);
    var params = {}
    hash.split('&').map(hk => { 
      let temp = hk.split('='); 
        params[temp[0]] = temp[1] 
    });
    console.log(params); //Here are the params to use

然后,您可以使用

params.access_token //access_token 
params.id //id 

以及哈希内可用的其他参数。


0

params.indexOf('loc')不会返回任何值,因为loc不存在于params数组中。在所提供的示例中,您要查找的项是loc=austria。如果您仅按键选择,则需要一些循环来检查每个键值对。


0
解析哈希时,可能需要处理未转义的=字符。在这种情况下,不建议使用split。此外,您还可以处理空哈希、空值(通常被解释为真)并使用decodeURIComponent来处理编码值。
const hash2Obj = function (hash) {
  // remove first char if necessary
  hash = (hash && (hash.charAt(0) === '#' || hash.charAt(0) === '?') ? hash.slice(1) : hash);
  // return empty object if empty
  if (!hash) return {};
  const obj = {};
  hash
  .split("&")
  .forEach(v => {
    // seek only first '=' char
    const id = v.indexOf('=');
    const [key, value] = id > -1 ? [v.slice(0, id), decodeURIComponent(v.slice(id + 1))]
    // handle absence of value as true
    : [v, true];
    if (key in obj) {
      // repeating values are usually intepreted as array
      if (!(obj[key] instanceof Array)) obj[key] = [obj[key]];
      obj[key].push(value);
    } else {
      obj[key] = value;
    }
  });
  return obj;
};

const getSearch = function () {
  return hash2Obj(window.location.search);
};
const getHash = function () {
  return hash2Obj(window.location.hash);
};

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