likes
comments
collection
share

JS获取H5页面前向url及跨域场景下的解决方案

作者站长头像
站长
· 阅读数 27

最近做了这样一个功能, 有两个同类的商品售卖页面, 为了用户能方便对比两个商品, 在两个页面顶部放了个长得一样的tab切换组件, 标签就会跳转到另一个产品

JS获取H5页面前向url及跨域场景下的解决方案

为了避免用户频繁切换时页面加载时间过长, 我们做了这样一个优化: 如果A跳转了B, 现在想从B再跳到A, 那么就返回到A页面, 而不是跳转一个新页面, 这样A页面就不用重新加载了, 而且也不会累积过多的页面栈

返回上一个页面可以用window.history.go(-1)或者window.history.()

History - Web API | MDN (mozilla.org)

判断从哪个页面跳转过来的(即前向页面)可以用document.referrer

Document.referrer - Web API | MDN (mozilla.org)

代码如下

    // 点击tab切换按钮(A页面跳转到B页面)
    clickTabBtn() {
      const urlB = 'https://mall.demo.com/page/b'
      // 如果从另一个页面来, 直接返回
      if (document.referrer.indexOf(urlB) !== -1) {
        return window.history.go(-1)
      }
      location.href = urlB
    }

看起来没有问题, 但是部署之后发现实际逻辑没有生效

排查后发现是因为两个页面的域名不同导致的:

当站点处于不同的域(即跨域)时,浏览器会阻止访问 Document.referrer 的信息

那么怎么在跨域的场景下拿到前向页面的url呢

<a> 标签可以使用Referrer-Policy属性控制跳转过去的页面能拿到什么样的Referer

  • no-referrerReferer 标头将不会被发送。
  • no-referrer-when-downgrade:如果没有 TLS(HTTPS)Referer 头将不会被发送到源上。
  • origin:发送的 referrer 将被限制在其页面的来源:协议、主机和端口。
  • origin-when-cross-origin:发送到其他源的 referrer 将只包含协议、主机和端口,而导航到相同的源仍将包括路径。
  • same-origin:将向同源地址发送 referrer,但跨源请求不包含 referrer 信息。
  • strict-origin:当协议安全级别保持不变(HTTPS→HTTPS)时,只将文档的来源作为 referrer 发送,但不要将其发送到安全性较低的目的地(HTTPS→HTTP)
  • strict-origin-when-cross-origin(默认):在执行同源请求时发送完整的 URL,在协议安全级别保持不变时只发送源(HTTPS→HTTPS),对安全性较低的目的地不发送标头(HTTPS→HTTP)
  • unsafe-url:表示 referrer 将会包含源和路径(但是不包含片段、密码或用户名)。此值是不安全的,因为它可能会将受 TLS 保护的资源的源和路径泄露到不安全的源中。

为了能在js中使用这个属性, 就要构造一个 <a> 标签然后触发点击事件实现跳转:

// 点击tab切换按钮(A页面跳转到B页面)
    clickTabBtn() {
      const urlB = 'https://mall.demo.com/page/b'
      // 如果从另一个页面来, 直接返回
      if (document.referrer.indexOf(urlB) !== -1) {
        return window.history.go(-1)
      }
      // 解决因跨域或其他原因导致跳转的页面取到的referrer不完整
      // 构建总是发送完整referrer的a标签
      const referLink = document.createElement('a')
      referLink.href = urlB
      referLink.setAttribute('referrerpolicy', 'unsafe-url') 
      // 总是发送完整的referrer
      referLink.style.visibility = 'hidden' // 以防影响页面展示
      document.body.appendChild(referLink)
      referLink.click() // 跳转
    }

总结: 本文介绍了如何获取H5页面前向页面的URL, 以及存在跨域时可以通过<a>标签的referrerpolicy属性控制跳转过去的页面能拿到完整的Referer

转载自:https://juejin.cn/post/7378459137418084352
评论
请登录