JS 監聽用戶頁面訪問&頁面關閉併進行數據上報操作

来源:https://www.cnblogs.com/risheng/p/18209237
-Advertisement-
Play Games

用戶在頁面訪問時發送數據到後臺,頁面關閉時也發送數據到後臺。 第一次進入頁面時觸發頁面訪問 刷新當前頁面時觸發頁面訪問 新 tab 進入頁面時觸發頁面訪問 當前頁面點擊 nav 進入其他模塊時,觸發頁面關閉&頁面訪問 關閉頁面時觸發頁面關閉 ...


JS 監聽用戶頁面訪問&頁面關閉操作併進行數據上報

前言

最近在做安全方面的項目,有個需求是在用戶訪問頁面和關閉頁面的時候,發送對應的數據。

剛拿到需求的時候,覺得沒啥東西,init 的時候發送一次,頁面 unload 的時候發送一次就行了,很簡單,後面開發了一下,又根據當前項目,發現沒這麼簡單

一、需求背景

1、項目需求

用戶在頁面訪問時發送數據到後臺,頁面關閉時也發送數據到後臺。

2、需求解析

很簡單的一句話

但是我們前面說了,沒有這麼簡單,那是因為我們的項目比較複雜

  1. 項目是一個龐大的項目,內部有好多子系統,子系統是通過 iframe 內嵌的

  2. 點擊 nav 模塊進入到子系統,當前頁面的 hash 不會改變,只會改變 location.pathname document.title,但是這兩個改變有沒有事件監聽到

  3. 點擊進入子系統時,也需要對之前的模塊進行關閉上報和當前模塊的訪問上報

  4. iframe 內嵌的項目不需要單獨上報,在 top 層進行上報即可

  5. iframe 內嵌的項目單獨通過 URL 訪問,則和當前項目一樣,需要訪問上報和關閉上報

3、需求概括

經過分析,整體需求分為如下幾個點:

  1. 第一次進入頁面時觸發頁面訪問

  2. 刷新當前頁面時觸發頁面訪問

  3. 新 tab 進入頁面時觸發頁面訪問

  4. 當前頁面點擊 nav 進入其他模塊時,觸發頁面關閉&頁面訪問

  5. 關閉頁面時觸發頁面關閉

二、技術要點

主要包含以下幾點:

  1. cookie 存儲

  2. sessionStorage 存儲

  3. addEventListener 事件監聽

  4. navigator.sendBeacon 數據發送

1、Cookie 存儲

使用 cookie 主要是因為項目的 domain 都一樣,存儲不同頁面的 titlehrefreferrer 等數據

【Cookie】

2、SessionStorage 存儲

這個主要是對在當前 tab 頁下的跳轉進行判斷,用來區分是否首次進入當前 tab

【SessionStorage】

3、addEventListener 事件監聽

事件監聽,註意是用來監聽 unload 事件。

【addEventListener MDN】

4、navigator.sendBeacon 數據發送

這個我們後面在水一篇文章,單獨講講,本期只講用法

navigator.sendBeacon() 方法可用於通過 HTTP POST 將少量數據非同步傳輸到 Web 伺服器。

4.1. 語法

navigator.sendBeacon(url);
navigator.sendBeacon(url, data);

4.2. 參數

4.2.1. url

url 參數表明 data 將要被髮送到的網路地址。

4.2.2. data 可選

data 參數是將要發送的 ArrayBufferArrayBufferViewBlobDOMStringFormDataURLSearchParams 類型的數據。

4.3. 返回值

當用戶代理成功把數據加入傳輸隊列時,sendBeacon() 方法將會返回 true,否則返回 false

【navigator.sendBeacon】

三、需求實現

1、實現思路

1.1. 第一次進入頁面

  1. sessioncookie

  2. 調用 urlDetectChange 函數

  3. 觸發 openPage() 進行頁面訪問上報

  4. 設置 session 欄位

  5. setTimeout 輪詢,設置 cookie 欄位,監聽 URL 變化

1.2. 刷新當前頁面

  1. sessioncookie

  2. 觸發頁面訪問上報

  3. setTimeout 輪詢,監聽 URL 變化

1.3. 點擊 nav 進入其他模塊

  1. sessioncookie

  2. setTimeout 輪詢,當前 document 中的 titlehrefcookie 中的不一致時,進行之前頁面關閉上報和當前頁面訪問上報

  3. 設置新的 cookie

  4. 繼續 setTimeout 輪詢,監聽 URL 變化

1.4. 新 tab 進入頁面

  1. cookiesession

  2. 觸發頁面訪問上報

  3. 設置新的 cookie

  4. 繼續 setTimeout 輪詢,監聽 URL 變化

1.5. 關閉 tab

  1. 觸發 unload 監聽事件
  2. 進行頁面關閉上報

2、頁面訪問->頁面關閉流程圖

image

3、頁面訪問&頁面關閉數據上報流程圖

image

4、數據上報

/**
* 上報介面
* @param {object} data 上報介面參數
* @returns {boolean} sendBeacon 介面返回信息
*/
export const sendBeaconMessage = (data: object): boolean =>
  window.navigator.sendBeacon(
    'xxx',
    JSON.stringify(data)
  )
// Cookies 使用 js-cookie
/**
 * 設置 cookie 值
 * 設置 href、pageTitle、referrer 欄位
 * key 為 ACCESS_CLOSE_COOKIE_NAME
 * domain 為 '.xxx.com'
 */
export const setAccessPageCookie = () =>
  Cookies.set(
    'ACCESS_CLOSE_COOKIE_NAME',
    JSON.stringify({
      href: location.href,
      pageTitle: document.title,
      referrer: document.referrer
    }),
    { domain: '.xxx.com', expires: 30 }
  )

6、頁面訪問發送消息

/**
 * 頁面訪問發送消息
 * @param {object} data 上報介面參數
 * 設置 sessionStorage 的值,
 */
export const openPageSendBeacon = async (data: object) => {
  sessionStorage.setItem('ACCESS_CLOSE_SESSION_NAME', 'ISTRUE')
  const sendBeaconSusscess = sendBeaconMessage(data)
  // 列印 sendBeaconSusscess 的值
  console.log(
    '%c client:sendDataToRemote use sendBeacon access page: %o',
    'color: green;',
    sendBeaconSusscess
  )
}

7、頁面關閉發送消息

/**
 * 頁面關閉發送消息
 * @param {object} data 上報介面參數
 */
export const closePageSendBeacon = async (data: object) => {
  const sendBeaconSusscess = sendBeaconMessage(data)
  // 列印 sendBeaconSusscess 的值
  console.log(
    '%c client:sendDataToRemote use sendBeacon close page: %o, ',
    'color: red;',
    sendBeaconSusscess
  )
}

8、URL 改變進行監聽&頁面關閉監聽

/**
 * URL 改變事件
 */
export const urlDetectChange = () => {
  const accessPageData = Cookies.get('ACCESS_CLOSE_COOKIE_NAME')
    ? JSON.parse(Cookies.get('ACCESS_CLOSE_COOKIE_NAME'))
    : null
  const sessionAccessData = sessionStorage.getItem('ACCESS_CLOSE_SESSION_NAME')
  // 第一次進入頁面 和 新 tab 進入頁面
  if (!accessPageData || !sessionAccessData) {
    openPageSendBeacon({})
  }
  setTimeout(() => {
    if (
      accessPageData &&
      location.href !== accessPageData.href &&
      document.title !== accessPageData.pageTitle &&
      sessionAccessData
    ) {
      // 點擊 nav 進入其他模塊
      closePageSendBeacon({})
      openPageSendBeacon({})
    }
    setAccessPageCookie()
    urlDetectChange()
  }, 1000)
}
// 加這個是針對 iframe 內部的項目不進行監聽,只在 top 層進行數據上報
if (window.top === window.self) {
  // 頁面訪問上報 刷新頁面
  sessionStorage.getItem('ACCESS_CLOSE_SESSION_NAME') && openPageSendBeacon({})
  urlDetectChange()
  window.addEventListener('unload', () => closePageSendBeacon({}))
}

四、總結

  1. 頁面訪問&頁面關閉數據上報能清楚的掌握用戶的使用數據,對營銷活動或者畫像分析很有幫助
  2. 整體沒有難點,就是不同項目不同分析
  3. 如果你的項目是 hash 改變,那就可以針對 hash 進行監聽
  4. 主要就是使用 navigator.sendBeacon 進行可靠的數據傳輸

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 剛進公司接觸到了Oracle,記錄一下他們的區別,面試的時候也有問到過,而且上來就是千萬級別的數據調優,嘻嘻,我只是一個3年java。題外話,甚至有一些公司會問我java跟C、python的區別,以及具體區別的例子,然後我如果回答上來了,他們會告訴我,這邊只做後端而且只用java,笑嘻了 就本人最近 ...
  • 引言 近期我們註意到很多學生朋友通過郵件嚮導師申請報名,請註意!!!​這是無效的,請必須通過“開源之夏”官方後臺申請報名,請仔細參考這篇【報名攻略】 所以,我們特此舉辦這次宣講會,目的是向所有感興趣的學生詳細介紹Apache DolphinScheduler社區在開源之夏中提供的項目,並且解答學生朋 ...
  • @目錄前言需求:拼接函數:截取函數:總結 前言 請各大網友尊重本人原創知識分享,謹記本人博客:南國以南i、 提示:以下是本篇文章正文內容,下麵案例可供參考 需求: 將資料庫中的某一個欄位的前6位替換成一個新的字元串,其它位置不變。 拼接函數: CONCAT(A,B):將A和B拼接起來。 截取函數: ...
  • 前言 應用上下文(Context)是應用程式的全局信息的介面。它是一個抽象類,提供了訪問應用程式環境的方法和資源的方法。應用上下文可以用於獲取應用程式的資源、啟動Activity、發送廣播等。每個應用程式都有一個應用上下文對象,它在整個應用程式的生命周期內都是唯一的。通過應用上下文,我們可以獲得 ...
  • 前言 組件容器是一種用於管理和組織組件的工具或環境。它可以提供一些基本的功能,如組件的註冊、創建、銷毀和查找。組件容器通常會維護一個組件的依賴關係,並負責將這些依賴註入到組件中。它還可以提供一些其他的功能,如生命周期管理、事件通知、配置管理等。通過使用組件容器,開發者可以更方便地管理和使用組件, ...
  • ADB Remote ATV Android TV 的遙控器,基於 ADB Shell 命令 ADB Remote ATV 是一個 Android TV 的遙控器,基於 ADB Shell 命令,泛用性更高。 下麵的 shell 命令,是軟體的基本原理,通過 shell 命令可模擬物理遙控器的基本按 ...
  • 版本控制在軟體開發中至關重要,而 Git 是廣泛使用的代碼管理工具。有時,我們可能需要在多個平臺 (如 GitHub、GitLab 和 Gitee) 上同步同一 Git 倉庫,以便備份、協作等。 本文將帶你玩轉此操作,其中關鍵是“配置 SSH” 和“遠程倉庫”。首先,我們來講述 SSH 的配置。 配 ...
  • 一、卡片數據交互 HarmonyOS卡片數據交互是指在基於鴻蒙操作系統的設備上,卡片界面之間進行數據的傳輸和交互。 HarmonyOS的卡片是一種輕量級的應用界面,可以在設備的屏幕上顯示信息和提供操作功能。卡片可以包含各種類型的內容,如文本、圖片、按鈕、輸入框等,並可以根據用戶的操作進行相應的響 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...