【原生JS】如何优雅地读、改location.search(queryString或GET参数)

应用场景

location.search完全由JS脚本管理,并且需要不刷新页面地修改其内容。例如在Oauth2授权中,如果是前端取参提交给后端API向平台方请求accessToken,需要及时删除GET参数中的code,以防用户刷新浏览器导致用失效的code处理登录。

实现思路

将queryString转为对象并用ES6的Proxy代理,在set、delete钩子中调用history.replaceState更新地址,将代理对象添到window上。这样业务代码中就能像PHP中访问全局变量$_GET一样读和改地址栏的GET参数了。

代码

// 定义被代理对象,如果需要响应用户操作引起的更新,只更新这个原对象即可,Proxy中的target是浅显拷贝,修改原对象会影响到代理对象
const GET_TARGET=location.search?Object.fromEntries(location.search.substring(1).split('&').map(part=>part.split('='))):{};
// 添加toString,便于对其直接使用字符串相关运算
Object.defineProperty(
  GET_TARGET,
  'toString',
  {
    value(){
      const entries=Object.entries(this);
      if(!entries.length) return '';
      entries.sort(([pre],[cur])=>pre.localeCompare(cur));
      return '?'+entries.map(([k,v])=>k+'='+v).join('&');
    }
  }
);
// 代理对象
window.$_GET=new Proxy(
  GET_TARGET,
  {
    set(target,prop,val){
      if(target[prop]!==val){
        target[prop]=val;
        // 这里的 String + target + String 依赖给原对象添加的toString方法
        window.history.replaceState(null,'',location.pathname+target+location.hash);
      }
      return true;
    },
    deleteProperty(target,prop){
      if(prop in target){
        delete target[prop];
        window.history.replaceState(null,'',location.pathname+target+location.hash);
      }
      return true;
    }
  }
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值