国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

sendBeacon 刷新/關閉頁面之前發送請求

gxyz / 1849人閱讀

摘要:背景有一個任務非常耗時會消耗后臺大量算力,所以在退出頁面的時候,要求前端這邊發送一個請求來殺死任務。小結本文總共講了三個,和,這個估計知道的人比較少,以后遇到前端埋點和頁面卸載前發送請求的需求,記得使用這三個。

背景:

有一個任務非常耗時會消耗后臺大量算力,所以在退出頁面的時候,要求前端這邊發送一個請求來殺死任務

一開始以為這個需求非常簡單,就是在進入其他路由前,發送一下請求,殺死一下任務就好了。

然而現實狠狠的打了我的臉,因為退出頁面的場景不止切換路由~

退出頁面場景:

還在本網站,跳到其他路由

刷新頁面/關閉頁面也需要發送請求來殺死任務

還在本網站,跳到其他路由

這個比較簡單,在Vue中可以通過路由離開的鉤子beforeRouteLeave來實現:

 beforeRouteLeave(to, from, next) {
    if (任務運行中) {
        // 發送請求
    }else{
        next(true) // 用戶離開
    }
 }

刷新頁面/關閉頁面的情況:

然而在刷新頁面的時候,beforeRouteLeave并不會執行,接著想到了下面這兩個API.

beforeunloadunload beforeunload 當瀏覽器窗口關閉或者刷新時觸發:

介紹

使用這個API可以阻止頁面直接關閉,用戶通過點擊確定/取消按鈕,來決定是否不關閉/刷新當前頁面。

在 chrome 下長這個樣子,你們肯定都見過:

如何使用

這個 API 的使用非常簡單,只要在頁面加載的時候監聽一下此事件,在需要出現彈窗的時候return 一個可以轉化為 true 的值,就可以了。

// 頁面卸載之前
let killTask = false; // 是否殺死任務
window.onbeforeunload = e => {
  if (任務運行 && 對應頁面) {
    killTask = true;
    return "您可能有數據沒有保存"; // 在部分瀏覽器可以修改彈窗標題
  } else {
    killTask = false;
  }
  // 沒有return一個可以轉化為true的值 就不會出現彈窗
};

出現此彈窗的瀏覽器行為

以下行為是基于 chorme:

焦點:你沒有點擊取消/確定之前,焦點會一直在此彈窗上

你無法在出現彈窗的頁面上執行任何操作

在其他頁面也只能執行簡單的點擊操作,彈窗還是存在頁面中間,無法使用鍵盤,

鍵盤:鍵盤被綁定在彈窗上,只能通過按鍵EscEnter來執行取消/確定操作

彈窗不是頁面的 dom,是瀏覽器的行為

用戶取消/確定,沒有回調 API,無法得知

彈窗標題

chrome 中刷新頁面的標題:重新加載此網站?

chrome 中關閉頁面的標題:離開此網站?

現在大部分瀏覽器都不允許修改彈窗的標題,這個是為了安全考慮,來保證用戶不受到錯誤信息的誤導,

迷茫

一開始我以為既然可以攔截到用戶的刷新/關閉頁面的操作,出現了上面那個彈窗,這個需求就已經做完了的時候。

然后發現,瀏覽器竟然沒有提供用戶點擊確定/取消刷新頁面的回調

到這里我陷入了迷茫,盯著beforeunload這個 API 思考了起了人生的意義(其實是在發呆),盯著盯著,從beforeunloadbefore我也就想到了unload這個 API。

瞬間又燃起了斗志,何不試試這個unload

unload當頁面正在被卸載的時候觸發該事件

介紹

當頁面正在被卸載的時候觸發該事件,該事件不可取消,為不可逆操作。

使用

直接監聽該事件就可以了。

window.onunload = e => {}

結合需求:

killTaskbeforeunload時定義的變量,每次進入回調,都會給killTask賦值,使用這個值就可以判斷什么時候可以發送請求殺死任務。

window.onunload = e => {
  if (killTask && 對應頁面) {
    // 發送請求
  }
};

到這里大家肯定以為已經做出來了該需求,事實上,并沒有!

無法發送異步請求

我使用的是axios來發送請求,請求發出去了,但是被取消了,服務器那邊根本沒有收到請求,如下。

經過一頓分析:發現是axios請求是異步的問題,谷歌之后發現axios不支持同步的請求

最后使用原生的XMLHttpRequest對象,讓請求同步

大功告成! 實際上,上面才是我第一次要發的內容,而下面更好的解決方法!

缺陷與更好的建議:

當我把這篇文章發布在公眾號上,被奇舞周刊轉載了,上面一些大佬給我提了一些建議。

研究了一下,結果...好吧!我承認我是菜雞。

hey~ 不過這正是我寫博客的收獲之一,分享經驗,收獲知識!

性能缺陷:

XHR同步請求會阻礙頁面卸載,如果是刷新/跳轉頁面的話,頁面重新展示速度會變慢,導致性能問題

畢竟向網絡發送請求并獲得響應可能會超級慢,有可能是用戶網絡環境比較差,又或者是服務器掛了,請求一直沒返回回來...

基于性能問題,大佬們推薦使用Beacon代替XHR,然后經過一番搜索...

Beacon API

Beacon API用于將少量數據通過post請求發送到服務器

Beacon是非阻塞請求,不需要響應

完美解決性能缺陷問題:

瀏覽器將 Beacon 請求排隊讓它在空閑的時候執行并立即返回控制

它在unload狀態下也可以異步發送,不阻塞頁面刷新/跳轉等操作。

所以Beacon可以完美解決上面提到的因XHR同步請求阻塞而引起的性能缺陷問題

使用:navigator.sendBeacon()

完整API

let result = navigator.sendBeacon(url, data);

Beacon是掛在navigator下面的,上面就是它的完整API。

result是一個布爾值,代表這次發送請求的結果:

如果瀏覽器接受并且把請求排隊了則返回 tru

如果在這個過程中出現了問題就返回 false

navigator.sendBeacon接受兩個參數:

url: 請求的 URL。請求是 POST 請求。

data: 要發送的數據。 數據類型可以是:ArrayBufferView, Blob, FormData,Sting。

來看一個用FormData來傳遞數據的栗子,你就懂了:

// 創建一個新的 FormData 并添加一個鍵值對
let data = new FormData();
data.append("hello", "world");
let result = navigator.sendBeacon("./src", data);
if (result) { 
  console.log("請求成功排隊 等待執行");
} else {
  console.log("失敗");
}
瀏覽器支持:

瀏覽器支持:Edge:14+,Firefox:31+,Chrome:39+,Opera:26+,IE:不支持。

雖然現在瀏覽器對sendBeacon的支持很好,我們對其做一下兼容性處理也是有必要的:

if (navigator.sendBeacon) {
  // Beacon 代碼
} else {
 // 回退到 XHR同步請求或者不做處理
}
web wroker中使用Beacon

因為Beacon是掛在navigator 下面,而web worker也有navigator ,去找了一下,真的給我找到了。

這兒有一個MDN提供的栗子),可以點進去看一下。

PS:對web worker不熟悉的同學可以看我這篇文章

Beacon其他相關

客戶端優化:可以將 Beacon 請求合并到其他請求上,一同處理, 尤其在移動環境下。

Beacon更多的情況是用于做前端埋點,監控用戶活動,它的初衷也基于此。

小結

本文總共講了三個API,beforeunloadunloadBeaconBeacon這個API估計知道的人比較少,以后遇到前端埋點和頁面卸載前發送請求的需求,記得使用這三個API。

以上2019.02.19

博客、前端積累文檔、公眾號、GitHub

參考資料:

MDN

頁面跳轉時,統計數據丟失問題探討

使用 Web Beacon API 記錄活動

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102061.html

相關文章

  • 在單頁應用中,如何優雅的上報前端性能數據

    摘要:本文的介紹的是如何設計一個通用的可以以較小的侵入性,自動上報前端的性能數據。具體的做法可以看我的上一篇文章在單頁應用中,如何優雅的監聽的變化。三如何上報性能數據那么如何上報性能數據呢,我們第一反應就是通過請求的形式來上報前端性能數據。 ??最近在做一個較為通用的前端性能監控平臺,區別于前端異常監控,前端的性能監控主要需要上報和展示的是前端的性能數據,包括首頁渲染時間、每個頁面的白屏時...

    KitorinZero 評論0 收藏0
  • 在單頁應用中,如何優雅的上報前端性能數據

    摘要:本文的介紹的是如何設計一個通用的可以以較小的侵入性,自動上報前端的性能數據。具體的做法可以看我的上一篇文章在單頁應用中,如何優雅的監聽的變化。三如何上報性能數據那么如何上報性能數據呢,我們第一反應就是通過請求的形式來上報前端性能數據。 ??最近在做一個較為通用的前端性能監控平臺,區別于前端異常監控,前端的性能監控主要需要上報和展示的是前端的性能數據,包括首頁渲染時間、每個頁面的白屏時...

    curried 評論0 收藏0
  • 在單頁應用中,如何優雅的上報前端性能數據

    摘要:本文的介紹的是如何設計一個通用的可以以較小的侵入性,自動上報前端的性能數據。具體的做法可以看我的上一篇文章在單頁應用中,如何優雅的監聽的變化。三如何上報性能數據那么如何上報性能數據呢,我們第一反應就是通過請求的形式來上報前端性能數據。 ??最近在做一個較為通用的前端性能監控平臺,區別于前端異常監控,前端的性能監控主要需要上報和展示的是前端的性能數據,包括首頁渲染時間、每個頁面的白屏時...

    beanlam 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<