场景: spa应用需要添加埋点,参数需要获取当前页面的上一页url。
相关技术栈:react
+react-router
常规场景可以通过document.referrer
拿到,但spa应用中切换路由document.referrer
不会改变。
查看了react-router
和history
的API,都没有提供监听路由变化的函数。因此采取的方案是,添加一个生命周期钩子,在location.pathname
改变时,将旧的url
保存在全局变量中。
// util.js
export const setReferrerUrl = (prevPath) => {
window.referrerUrl = window.referrerUrl ? `${window.location.origin}${prevPath}` : document.referrer
}
// layout.js
import React, { useState, useEffect, useRef } from 'react'
import { Link, useHistory } from 'react-router-dom'
const history = useHistory()
// ...
/** TODO: 收集埋点需要的上一页路径 */
const usePrevious = (value) => {
const ref = useRef()
useEffect(() => {
ref.current = value
})
return ref.current
}
const prevPath = usePrevious(history.location.pathname)
useEffect(() => {
setReferrerUrl(prevPath)
}, [history.location.pathname])
通过window.referrerUrl
获取上一页路径
ps:无法获取 referrer 信息的情况
下面的场景无法获得 referrer 信息,以下前8条属于【张鑫旭】:
- 直接在浏览器中输入地址
- 使用
location.reload()
刷新(location.href
或者location.replace()
刷新有信息) - 在微信对话框中,点击进入微信自身浏览器 扫码进入微信或QQ的浏览器
- 直接新窗口打开一个页面
- 协议降级:从
https
的网站直接进入一个http
协议的网站(可以在https网站header加上meta标签<meta content="always" name="referrer">
) - a标签设置
rel="noreferrer"
(兼容IE7+) - meta标签来控制不让浏览器发送referer
- 点击 flash 内部链接
- Chrome4.0以下,IE 5.5+以下返回空的字符串
- 使用 修改 Location 进行页面导航的方法,会导致在IE下丢失 referrer,这可能是IE的一个BUG
- 跨域
<meta content="never" name="referrer">
参考: