詳解JavaScript發(fā)送埋點(diǎn)請(qǐng)求的兩種方式
對(duì)于統(tǒng)計(jì)頁面數(shù)據(jù)這樣的情景(俗稱埋點(diǎn)),我們常用的方式就是動(dòng)態(tài)創(chuàng)建<img>或<script>,至于原因,一般有以下幾點(diǎn):
1.埋點(diǎn)一般不用關(guān)心請(qǐng)求的結(jié)果
2.可以實(shí)現(xiàn)跨域請(qǐng)求
3.無需使用ajax就能達(dá)到發(fā)請(qǐng)求的目的
4.都是原生實(shí)現(xiàn),兼容性好
現(xiàn)就兩種方式做一下對(duì)比和總結(jié):
一、用法
1.動(dòng)態(tài)創(chuàng)建<img>
方式1:通過img標(biāo)簽
function sendByImg(src) {
var img = document.createElement("img");
img.src = src;
}方式2:通過Image對(duì)象
function sendByImage(src) {
var img = new Image();
img.src = src;
}2.動(dòng)態(tài)創(chuàng)建<script>
只有一種方式:通過<script>標(biāo)簽
function sendByScript(src){
var script = document.createElement("script");
script.src = src;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
}二、區(qū)別
區(qū)別1
如果要觸發(fā)請(qǐng)求,動(dòng)態(tài)創(chuàng)建的<script>必須要插入到DOM中,而動(dòng)態(tài)創(chuàng)建的<img>則不需要
演示代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Img VS Script</title>
</head>
<body>
<h3>
請(qǐng)觀察瀏覽器中的Network和Elements!
</h3>
<script>
function sendByScript(src){
var script = document.createElement("script");
script.src = src;
}
function sendByScriptInsertDOM(src){
var script = document.createElement("script");
script.src = src;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
}
function sendByImage(src) {
var img = new Image();
img.src = src;
}
function sendByImg(src) {
var img = document.createElement("img");
img.src = src;
}
function sendRequest(src) {
//一、通過script:
//不插入DOM,不會(huì)觸發(fā)請(qǐng)求
sendByScript(src + '/byScript');
//插到DOM中,會(huì)觸發(fā)請(qǐng)求
sendByScriptInsertDOM(src + '/byScriptDOM');
//二、通過img:
//不插入DOM,不會(huì)觸發(fā)請(qǐng)求
sendByImage(src+ '/byImage');
//不插入DOM,不會(huì)觸發(fā)請(qǐng)求
sendByImg(src+ '/byImg');
}
sendRequest('https://wwww.baidu.com')
</script>
</body>
</html>用chrome瀏覽器打開此HTML文件,查看network:

可以看到,插入DOM中的<script>觸發(fā)來請(qǐng)求,而未插入DOM中則沒有發(fā)起請(qǐng)求;動(dòng)態(tài)創(chuàng)建的<img>的兩種方式?jīng)]有插入DOM,都觸發(fā)請(qǐng)求。
那么問題來了,為什么動(dòng)態(tài)創(chuàng)建的<script>必須要插入DOM中才會(huì)觸發(fā)請(qǐng)求,而動(dòng)態(tài)創(chuàng)建的<img>則不用?關(guān)于這個(gè)問題,在網(wǎng)上查了很久也沒有找到特別強(qiáng)有力的解釋。有人說是因?yàn)檫@兩種標(biāo)簽本身的特性決定的:<img>作為展示性標(biāo)簽加載的是圖片資源,其對(duì)應(yīng)的地址可以直接訪問就能得到資源;<script>往往加載的是JavaScript代碼,需要網(wǎng)頁這樣的執(zhí)行環(huán)境。個(gè)人覺得此解釋有些牽強(qiáng),但也沒有找到更權(quán)威的解釋。如果有更好的觀點(diǎn),歡迎留言。
區(qū)別2
動(dòng)態(tài)創(chuàng)建的<script>可以對(duì)請(qǐng)求結(jié)果進(jìn)行處理,而動(dòng)態(tài)創(chuàng)建的<img>做不到
JSONP的實(shí)現(xiàn)原理就是借助動(dòng)態(tài)創(chuàng)建<script>標(biāo)簽,并對(duì)返回結(jié)果進(jìn)行處理。
至此,我當(dāng)時(shí)在想,那么借助jQuery發(fā)送JSONP請(qǐng)求,豈不是每發(fā)一次就要在頁面上創(chuàng)建一個(gè)<script>標(biāo)簽?觀察結(jié)果顯示并沒有。于是去看了下jQuery的源碼:

如圖所示,在<script>加載完成或出錯(cuò)后將標(biāo)簽移除。所以,我們?cè)谟脛?dòng)態(tài)創(chuàng)建<script>方式發(fā)送請(qǐng)求也可以參考這種方式。
三、選擇哪種方式
單純從發(fā)送請(qǐng)求的角度看,理論上兩者沒有特別大的差異,但有一點(diǎn)一定要注意:動(dòng)態(tài)創(chuàng)建<img>的方式在瀏覽器禁用圖片模式下不會(huì)觸發(fā)請(qǐng)求。
例如,在chrome瀏覽器中設(shè)置禁圖模式(設(shè)置>高級(jí)設(shè)置>隱私設(shè)置和安全性>網(wǎng)站設(shè)置>圖片>顯示全部 去掉),結(jié)果:

只有動(dòng)態(tài)創(chuàng)建<script>的方式有請(qǐng)求,動(dòng)態(tài)創(chuàng)建<img>的方式?jīng)]有任何請(qǐng)求記錄。
綜上,從擴(kuò)展性和兼容性上看,動(dòng)態(tài)創(chuàng)建<script>的方式是首選。
四、總結(jié)
對(duì)于發(fā)送埋點(diǎn)請(qǐng)求這種應(yīng)用場(chǎng)景,我們有兩種簡單的處理方式:動(dòng)態(tài)創(chuàng)建<script>和<img>兩種方式,兩者最大的差異是:動(dòng)態(tài)創(chuàng)建的<script>必須插入到DOM中才能觸發(fā)請(qǐng)求,而動(dòng)態(tài)創(chuàng)建<img>的方式則不需要。但動(dòng)態(tài)創(chuàng)建<img>的方式有個(gè)致命缺陷:瀏覽器設(shè)置了禁止圖片顯示時(shí),無法觸發(fā)請(qǐng)求。所以,對(duì)于封裝埋點(diǎn)庫的時(shí)候,動(dòng)態(tài)創(chuàng)建<script>的方式是首選,而且可以參考jQuery,在請(qǐng)求記載完成后對(duì)<script>進(jìn)行清除。
以上就是詳解JavaScript發(fā)送埋點(diǎn)請(qǐng)求的兩種方式的詳細(xì)內(nèi)容,更多關(guān)于JavaScript發(fā)送埋點(diǎn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
實(shí)現(xiàn)圖片首尾平滑輪播(JS原生方法—節(jié)流)
下面小編就為大家?guī)硪黄獙?shí)現(xiàn)圖片首尾平滑輪播(JS原生方法—節(jié)流)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
使用JavaScript實(shí)現(xiàn)一個(gè)炫酷的羅盤時(shí)鐘
在探究前端動(dòng)畫時(shí),想到之前在鎖屏壁紙看到的羅盤時(shí)鐘,看著很是炫酷,于是說干就干,下面就跟隨小編一起來學(xué)習(xí)一下如何使用JS實(shí)現(xiàn)一個(gè)炫酷的羅盤時(shí)鐘效果吧2024-02-02
ThingJS粒子特效一鍵實(shí)現(xiàn)雨雪效果
在做3D項(xiàng)目時(shí),我們經(jīng)常需要模擬下雨,下雪的天氣,有時(shí)也會(huì)模擬噴泉、著火等效果。這些效果需要使用名為粒子系統(tǒng)(particle)的技術(shù)來實(shí)現(xiàn)。使用ThingJS可以快速編寫粒子效果,本文就來看看如何實(shí)現(xiàn)2021-05-05
ES6使用export和import實(shí)現(xiàn)模塊化的方法
這篇文章主要介紹了ES6使用export和import實(shí)現(xiàn)模塊化的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
深入理解Javascript中的循環(huán)優(yōu)化
這篇文章介紹了Javascript中的循環(huán)優(yōu)化,有需要的朋友可以參考一下2013-11-11
JavaScript實(shí)現(xiàn)將圖片地址轉(zhuǎn)成文件流并上傳
這篇文章主要為大家詳細(xì)介紹了如何使用JavaScript實(shí)現(xiàn)將圖片地址轉(zhuǎn)成文件流并上傳,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
JavaScript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包
這篇文章主要介紹了javascript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包的相關(guān)資料,需要的朋友可以參考下2015-12-12

