精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何在用戶離開頁面時可靠地發送 HTTP 請求

網絡 通信技術
您可能希望該請求的分派是同步的,之后我們將繼續導航離開頁面,而其他服務器成功地處理該請求。但事實證明,情況并非總是如此。

有幾次,當用戶執行導航到不同頁面或提交表單等操作時,我需要發送帶有一些數據的 HTTP 請求以進行記錄??紤]這個在點擊鏈接時向外部服務發送一些信息的人為示例:

<a href="/some-other-page" id="link">Go to Page</a>

<script>
document.getElementById('link').addEventListener('click', (e) => {
fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
some: "data"
})
});
});
</script>

這里沒有什么非常復雜的事情發生。該鏈接可以正常運行(我沒有使 e.preventDefault()),但在該行為發生之前,會在單擊時觸發 POST 請求。無需等待任何形式的響應。我只是希望它被發送到我正在訪問的任何服務。

乍一看,您可能希望該請求的分派是同步的,之后我們將繼續導航離開頁面,而其他服務器成功地處理該請求。但事實證明,情況并非總是如此。

瀏覽器不保證保留打開的HTTP請求

當瀏覽器中發生終止頁面的情況時,并不能保證進程內的HTTP請求會成功(參見更多關于“終止”和頁面生命周期的其他狀態)。這些請求的可靠性可能取決于幾個方面——網絡連接、應用程序性能,甚至外部服務本身的配置。因此,在這些時刻發送數據可能是不可靠的,如果您依賴這些日志來做出數據敏感的業務決策,那么這可能會帶來一個潛在的重大問題。為了幫助說明這種不可靠性,我使用上面包含的代碼設置了一個帶有頁面的小型 Express 應用程序。單擊鏈接時,瀏覽器會導航到 /other,但在此之前,會觸發 POST 請求。當一切都發生時,我打開了瀏覽器的網絡選項卡,并且我使用的是“慢 3G”連接速度。一旦頁面加載并且我已經清除了日志,事情看起來很安靜:

圖片

1.webp

但是一旦鏈接被點擊,事情就會出錯,當導航發生時,請求被取消。

圖片

2.webp

這使得我們對外部服務是否能夠處理請求缺乏信心。為了驗證這種行為,當我們使用window.location以編程方式導航時也會發生這種情況:

document.getElementById('link').addEventListener('click', (e) => {
+ e.preventDefault();

// Request is queued, but cancelled as soon as navigation occurs.
fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
some: 'data'
}),
});

+ window.location = e.target.href;
});

無論導航以何種方式或何時發生,以及活動頁面何時終止,那些未完成的請求都有被放棄的風險。

但是為什么被取消了呢?

問題的根源在于,默認情況下,XHR 請求(通過 fetch 或 XMLHttpRequest)是異步且非阻塞的。一旦請求被排隊,請求的實際工作就會被移交給幕后的瀏覽器級 API。由于它與性能有關,這很好——你不希望請求占用主線程。但這也意味著當頁面進入“終止”狀態時,它們有被遺棄的風險,無法保證任何幕后工作都能完成。以下是 Google 對特定生命周期狀態的總結:

一旦頁面開始被瀏覽器卸載并從內存中清除,頁面就處于終止狀態。在這種狀態下沒有新的任務可以啟動,并且正在進行的任務如果運行時間過長可能會被殺死。

簡而言之,瀏覽器的設計假設當一個頁面被關閉時,沒有必要繼續處理它排隊的任何后臺進程。

那么,我們有哪些選擇呢?

避免這個問題最明顯的方法可能是,盡可能地延遲用戶操作,直到請求返回響應。在過去,通過使用XMLHttpRequest中支持的同步標志來實現這一點是錯誤的。使用它會完全阻塞主線程,導致大量的性能問題——我在過去寫過一些這方面的文章——所以這個想法甚至不應該被接受。事實上,它正在退出平臺(Chrome v80+已經刪除了它)。相反,如果您打算采用這種類型的方法,那么最好在響應返回時等待Promise解析。在它回來之后,您可以安全地執行該行為。使用我們之前的代碼片段,它可能看起來像這樣:

document.getElementById('link').addEventListener('click', async (e) => {
e.preventDefault();

// Wait for response to come back...
await fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
some: 'data'
}),
});

// ...and THEN navigate away.
window.location = e.target.href;
});

這可以完成工作,但也有一些不小的缺點。首先,它會延遲所需行為的發生,從而損害用戶體驗。收集分析數據肯定會給業務(以及未來的用戶)帶來好處,但讓當前用戶為實現這些好處而支付成本并不理想。更不用說,作為一個外部依賴項,服務本身的任何延遲或其他性能問題都會暴露給用戶。如果分析服務的暫停導致客戶無法完成一項高價值的行動,那么所有人都是輸家。其次,這種方法并不像它最初聽起來那么可靠,因為一些終止行為無法通過編程延遲。例如, e.preventDefault() 無法延遲某人關閉瀏覽器選項卡。因此,它充其量只能涵蓋為某些用戶操作收集數據,但不足以全面信任它。

指示瀏覽器保留未完成的請求

值得慶幸的是,有一些選項可以保留絕大多數瀏覽器中內置的未完成的 HTTP 請求,并且不需要損害用戶體驗。

使用Fetch的keepalive標志

如果在使用fetch()時將keepalive標志設置為true,那么相應的請求將保持打開狀態,即使發起該請求的頁面被終止。使用我們最初的例子,它的實現如下所示:

<a href="/some-other-page" id="link">Go to Page</a>

<script>
document.getElementById('link').addEventListener('click', (e) => {
fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
some: "data"
}),
keepalive: true
});
});
</script>

當點擊該鏈接并進行頁面導航時,不會發生請求取消:

圖片

3.webp

相反,我們得到的是一個(未知)狀態,原因很簡單,活動頁面從來沒有等待接收任何響應。像這樣的一行程序很容易修復,特別是當它是常用瀏覽器API的一部分時。但是,如果您正在尋找一種功能更集中、界面更簡單的選擇,那么還有另一種方法,它實際上具有相同的瀏覽器支持。

使用 Navigator.sendBeacon()

Navigator.sendBeacon() 函數專門用于發送單向請求(beacon)。一個基本的實現看起來像這樣,發送一個帶有字符串化 JSON 和“text/plain” Content-Type 的 POST:

navigator.sendBeacon('/log', JSON.stringify({
some: "data"
}));

但是此 API 不允許您發送自定義標頭。因此,為了讓我們以“application/json”的形式發送數據,我們需要做一些小調整并使用 Blob:

<a href="/some-other-page" id="link">Go to Page</a>

<script>
document.getElementById('link').addEventListener('click', (e) => {
const blob = new Blob([JSON.stringify({ some: "data" })], { type: 'application/json; charset=UTF-8' });
navigator.sendBeacon('/log', blob));
});
</script>

最后,我們得到了相同的結果——即使在頁面導航之后也允許完成的請求。但是還有一些事情可能使它比 fetch() 更有優勢:beacon以低優先級發送。為了演示,當同時使用帶有 keepalive 的 fetch() 和 sendBeacon() 時,Network 選項卡中顯示的內容如下:

圖片

4.webp

默認情況下,fetch() 獲得“高”優先級,而beacon(上面稱為“ping”類型)具有“最低”優先級。對于對頁面功能不重要的請求,這是一件好事。直接取自 Beacon 規范:

該規范定義了一個接口,[…]最大限度地減少與其他時間關鍵操作的資源爭用,同時確保此類請求仍然被處理并交付到目的地。

換句話說,sendBeacon() 確保它的請求不會妨礙那些對您的應用程序和用戶體驗真正重要的請求。

因為ping屬性而被光榮提及

值得一提的是,越來越多的瀏覽器支持 ping 屬性。當附加到鏈接時,它會觸發一個小的 POST 請求:

<a href="http://localhost:3000/other" ping="http://localhost:3000/log">
Go to Other Page
</a>

這些請求標頭將包含單擊鏈接的頁面(ping-from),以及該鏈接的 href 值(ping-to):

headers: {
'ping-from': 'http://localhost:3000/',
'ping-to': 'http://localhost:3000/other'
'content-type': 'text/ping'
// ...other headers
},

它在技術上類似于發送beacon,但有一些明顯的限制:

它嚴格限制在鏈接上的使用,如果您需要跟蹤與其他交互相關的數據,例如按鈕點擊或表單提交,這將使其無法啟動。

瀏覽器支持很好,但不是很好。在撰寫本文時,Firefox 特別沒有默認啟用它。

您無法隨請求一起發送任何自定義數據。正如前面提到的,您最多只能得到幾個 ping-*頭文件,以及隨程序一起出現的任何其他頭文件。

綜合考慮,如果您可以發送簡單的請求并且不想編寫任何自定義 JavaScript,那么 ping 是一個很好的工具。但是,如果您需要發送更多實質內容,則可能不是最好的選擇。

那么,我應該選擇哪一個呢?

使用 fetch 和 keepalive 或 sendBeacon() 發送您的最后一秒請求肯定存在權衡。為了幫助辨別哪種方法最適合不同的情況,需要考慮以下幾點:

如果出現以下情況,您可能會使用 fetch() + keepalive:

  • 您需要輕松地隨請求傳遞自定義標頭。
  • 您想向服務發出 GET 請求,而不是 POST。
  • 您正在支持較舊的瀏覽器(如 IE)并且已經加載了 fetch polyfill。

但在以下情況下 sendBeacon() 可能是更好的選擇:

  • 您正在進行簡單的服務請求,不需要進行太多定制。
  • 您更喜歡更簡潔、更優雅的 API。
  • 您希望確保您的請求不會與應用程序中發送的其他高優先級請求競爭。

原文:https://css-tricks.com/send-an-http-request-on-page-exit/作者:Alex MacArthur

責任編輯:武曉燕 來源: 前端全棧開發者
相關推薦

2022-03-24 14:49:57

HTTP前端

2025-07-21 06:10:00

瀏覽器HTTPJavaScript

2009-11-09 09:11:17

2023-10-11 17:58:22

2019-11-18 15:50:11

AjaxJavascript前端

2018-05-17 16:25:27

2021-03-10 13:19:09

LinuxCPU程序

2020-06-17 14:40:49

用戶頁面前端

2025-09-25 13:51:13

2025-06-30 07:20:00

Web開發API

2025-02-04 09:58:08

2025-07-15 09:08:36

2025-02-06 08:09:20

POSTGET數據

2018-01-30 17:00:10

Linuxscp命令排除文件

2025-11-18 02:00:11

2021-06-02 15:30:44

智能安防物聯網智能建筑

2020-03-27 15:10:23

SpringJava框架

2017-04-28 09:04:32

移動應用開發反饋

2021-08-26 06:58:14

Http請求url

2023-07-18 12:50:48

C 語言用戶輸入
點贊
收藏

51CTO技術棧公眾號

中文精品一区二区三区| 久久精品国产清高在天天线| 国产老肥熟一区二区三区| 亚洲高清福利视频| 国产在线精品播放| 国内精品免费视频| 日韩美女网站| 欧美精品系列| 亚洲成人激情自拍| 91色中文字幕| 国产手机在线观看| av日韩国产| 国产电影一区在线| 色偷偷av亚洲男人的天堂| 亚洲 高清 成人 动漫| www日本高清| 欧美r级电影| 在线欧美小视频| 美日韩免费视频| 精品少妇久久久| 国产精久久一区二区| 国产亚洲欧洲一区高清在线观看| 欧美激情一区二区久久久| 91小视频在线播放| shkd中文字幕久久在线观看| 模特精品在线| 美日韩精品免费观看视频| 五月婷婷丁香色| 浮生影视网在线观看免费| 国产精品日韩久久久| 亚洲激情电影中文字幕| 成人午夜精品久久久久久久蜜臀| 亚洲精品国产精品国| 欧美午夜电影在线观看 | 黄网在线观看视频| 国产劲爆久久| 亚洲va欧美va人人爽| 国产精品果冻传媒潘| 日本在线小视频| 精品按摩偷拍| 色综合久久久久网| 日韩欧美99| 91tv国产成人福利| 羞羞色午夜精品一区二区三区| 欧美精品18+| 性生活免费观看视频| 国产精品久久久久久无人区| 香蕉国产精品| 一区二区欧美久久| 亚洲涩涩在线观看| 欧美日韩成人影院| 亚洲色图另类专区| 国产精品v欧美精品v日韩| 国产一级淫片a| 欧美激情1区2区| 国产丝袜一区视频在线观看| 黄色国产小视频| av男人的天堂在线| 国产大片一区二区| 亚洲wwwav| 91视频免费网址| 黄色一区二区三区四区| 亚洲精品在线不卡| 亚洲一级av无码毛片精品| 欧洲成人一区| 一二三四社区欧美黄| 精品乱码一区| 国产一区二区波多野结衣| 日本va欧美va欧美va精品| 久久久国产一区| gogo亚洲国模私拍人体| 中文字幕高清在线播放| 国产精品免费看片| 精品国产乱码一区二区三区四区| 日日躁夜夜躁白天躁晚上躁91| 日本在线观看不卡视频| 国产精品爱久久久久久久| 国产性生活大片| 欧美丝袜足交| 欧美卡1卡2卡| 日韩av福利在线观看| 美女日韩欧美| 亚洲动漫第一页| 欧美色图色综合| 一区二区三区电影大全| 在线视频欧美区| 夜夜夜夜夜夜操| julia中文字幕一区二区99在线| 在线免费视频一区二区| 欧美三级午夜理伦三级富婆| 久久精品一级| 欧美日韩国产另类一区| 国产欧美在线一区| 97超碰免费在线| 91久久精品午夜一区二区| 天堂8在线天堂资源bt| 在线视频1区2区| 一区二区三区蜜桃| 久久无码高潮喷水| av在线国产精品| 欧美日韩在线一区二区| 无码人妻丰满熟妇区毛片18 | 欧美成人午夜免费视在线看片 | 91九色蝌蚪嫩草| 一级特黄免费视频| 一区二区三区精品视频在线观看| 欧美另类高清videos| 极品色av影院| 日韩欧美网址| 有码中文亚洲精品| 免费一级片在线观看| 天天综合精品| www.日本久久久久com.| 殴美一级黄色片| 日本不卡免费一区| 中文在线资源观看视频网站免费不卡| 亚洲乱码国产乱码精品精大量| 成人在线tv视频| 中文在线不卡视频| 天天操天天操天天操天天| 亚洲激情视频| 欧美精品久久久久久久| 少妇又紧又色又爽又刺激视频| 性感少妇一区| 国产69精品久久久久久| 免费在线不卡视频| 韩国精品在线观看| 亚洲在线观看视频网站| 九色视频在线观看免费播放| 国产色产综合产在线视频| 国产又粗又猛又爽又黄的网站| 欧美日韩精品一区二区三区视频| 欧美精品一区二区三区视频 | 久久精品一区四区| 亚洲va韩国va欧美va精四季| yw193.com尤物在线| 五月婷婷激情综合网| 四虎国产精品永久免费观看视频| 成人精品视频| 国产91九色视频| 亚洲av综合一区| 91天堂素人约啪| 日韩免费电影一区二区三区| 鲁鲁在线中文| 欧美日韩国产免费一区二区| 天堂久久精品忘忧草| 五月精品视频| 国产精品永久免费在线| 成人免费视频国产| 久久精品欧美一区二区三区麻豆| 国产乱子伦农村叉叉叉| 久久影院资源站| 国产+人+亚洲| 中文字幕激情视频| 国产精品小仙女| 国内自拍中文字幕| 韩国久久久久久| 亚洲男人天堂网站| 在线免费观看亚洲视频| 国产一区二区三区久久| 久久99精品国产一区二区三区| av中文字幕一区二区三区| 91福利在线观看| 毛片久久久久久| 亚洲毛片视频| 蜜桃999成人看片在线观看| 欧美大片免费观看网址| 欧美成人一区二区三区| 亚洲v在线观看| 欧美日韩精品| 国产丝袜不卡| 国产视频网站在线| 欧美性猛交xxxxxx富婆| 中文字幕一区二区三区四| 成人福利一区| 久久久久久久久久久成人| 狠狠综合久久av一区二区| 亚洲国产一区二区三区青草影视 | 欧美1级日本1级| 高清不卡日本v二区在线| 日韩另类在线| 欧美日韩亚洲激情| 一级做a免费视频| 一区二区三区日本视频| 欧美xxxx18性欧美| 人妻夜夜爽天天爽| 中文字幕中文字幕在线一区| 啊啊啊国产视频| 亚洲青青一区| 久久免费高清视频| 欧美日韩国产中文字幕在线| 欧美国产一区视频在线观看| 欧美日韩在线中文| 影音先锋成人在线电影| 2018中文字幕一区二区三区| 一级片一区二区三区| 日韩毛片一二三区| 国产性xxxx18免费观看视频| 精品国产一区二区三区四区 | 国产69精品久久久久777| 六月婷婷久久| 国产精品字幕| 另类少妇人与禽zozz0性伦| 男人天堂中文字幕| 国产欧美1区2区3区| 四虎精品一区二区| 日本成人中文字幕在线视频| 在线码字幕一区| 99re6热只有精品免费观看| 国产精品9999| 色一情一乱一乱一区91av| 色网站国产精品| 在线观看免费黄色网址| av一区二区三区| 99re8这里只有精品| 免费福利视频一区| 国产精品视频1区| 午夜在线小视频| 精品国产成人系列| 中文字幕在线观看国产| 亚洲成国产人片在线观看| 熟女高潮一区二区三区| 国产高清不卡一区二区| 日本xxxxxxx免费视频| 成人h动漫免费观看网站| 国产精品成人一区二区| 日韩电影免费看| 另类专区欧美制服同性| 精品资源在线看| 欧美成人精品高清在线播放| 91精东传媒理伦片在线观看| 欧美性少妇18aaaa视频| 少妇大叫太粗太大爽一区二区| 国产一区二三区好的| 欧美日韩高清免费| 色在线免费观看| 久久亚洲私人国产精品va| 久久久久久女乱国产| 亚洲成成品网站| 国产免费av电影| 亚洲r级在线视频| 成人做爰视频网站| 国产日韩欧美不卡| 巨胸大乳www视频免费观看| 99久久精品一区二区| 亚洲视频天天射| 国产福利不卡视频| 一道本在线免费视频| 蜜桃视频在线一区| 亚洲精品一区二区三| 亚洲精品aaa| 欧美激情久久久久| 一区二区 亚洲| 欧美午夜免费电影| 中文在线资源天堂| 欧洲精品一区二区| 久久久久99精品成人片我成大片| 午夜视黄欧洲亚洲| 亚洲一区二区91| 成人av手机在线观看| 妓院一钑片免看黄大片| 美日韩精品视频| 欧美国产激情视频| 亚洲视频狠狠| 亚欧无线一线二线三线区别| 一区免费在线| 免费无码毛片一区二三区| 神马久久av| 精品伊人久久大线蕉色首页| 久久影院资源站| 免费99视频| 97久久夜色精品国产| 日本免费在线视频观看| 在线电影一区二区| 精品无码av无码免费专区| 欧美日韩亚洲国产精品| 东北少妇不带套对白| 亚洲成人最新网站| 成人在线观看毛片| 亚洲黄色av| 国内外成人激情视频| 久久精品国内一区二区三区| a级黄色一级片| 麻豆久久精品| 亚欧激情乱码久久久久久久久| 国产成人综合视频| 日本xxxx裸体xxxx| 日本美女一区二区| 黑人无套内谢中国美女| 懂色av一区二区三区蜜臀| 波多结衣在线观看| 亚洲专区一区二区三区| av动漫免费看| 久久精品国产第一区二区三区 | 国产精品夜夜爽| 成人手机在线免费视频| 麻豆精品视频在线| 在线观看中文av| 91丨porny丨在线| 神马午夜精品91| 午夜欧美2019年伦理| 久草视频在线免费| 亚洲激情久久久| 三区四区电影在线观看| 欧美精品久久久久久久免费观看| а√天堂中文在线资源8| 精品国产视频在线| а_天堂中文在线| 日韩一中文字幕| 日本在线视频www鲁啊鲁| 国产精品av电影| 欧美欧美在线| 色噜噜一区二区| 亚洲深夜福利| 国产精品嫩草影视| 91香蕉视频污| 新91视频在线观看| 香蕉乱码成人久久天堂爱免费| 国产乱码在线观看| 精品日韩一区二区三区| 91在线高清| 69av成年福利视频| 成人精品动漫| 欧美影院在线播放| 亚州一区二区| 国产乱码精品一区二区三区中文 | 国产一区啦啦啦在线观看| 欧美视频一区二区三区| 中国一级免费毛片| 日韩欧美成人一区| av网站大全在线观看| 欧美尤物巨大精品爽| 日韩福利视频一区| 国产小视频免费| 久久国产欧美日韩精品| 亚洲无人区码一码二码三码的含义 | 日韩av片在线| 国产精品一区二区免费不卡| www.超碰97| 国产精品美女久久久久aⅴ| 国产无人区码熟妇毛片多| 亚洲成av人乱码色午夜| 国产精品刘玥久久一区| 日韩最新中文字幕电影免费看| 亚洲欧美韩国| 久久国产精品精品国产色婷婷| 亚洲性色视频| 2018国产精品| 综合欧美亚洲日本| 99精品免费观看| 欧美成人午夜视频| 日韩在线影院| 午夜老司机精品| 美女一区二区久久| 国产精品成人一区二区三区电影毛片| 天天色天天爱天天射综合| 日韩精品一区不卡| 日韩av在线免费观看| 黄色国产在线| 91av在线国产| 美女视频亚洲色图| www.日本在线视频| 99久久久免费精品国产一区二区| 中文字幕一区二区三区手机版| 日韩电影在线观看永久视频免费网站| 999av小视频在线| 精品国产一区二区三区麻豆小说| 久久精品免费| 性欧美一区二区| 精品视频色一区| caoporn免费在线| 亚洲r级在线观看| 亚洲精品在线观看91| 色婷婷一区二区三区av免费看| 国产精品高潮久久久久无| 国产精品久久影视| 久久精品国产视频| 一区二区精彩视频| 久久伊人一区| 日本视频在线一区| 国产三级国产精品国产国在线观看| 日韩一级高清毛片| 免费影视亚洲| 91精品中文在线| 午夜国产精品视频| 妖精视频一区二区| 欧洲国内综合视频| 在线观看三级视频| 国产精品综合网站| 欧美精品国产一区| 亚洲欧美在线不卡| 欧美亚洲尤物久久| av网站在线免费| 久久久久久99| 国产一区二区高清| 黄色激情小视频| 日韩精品综合一本久道在线视频| 全亚洲第一av番号网站| 一区二区高清视频| 日本在线观看不卡视频|