一些網站能自動添加 URL 到 Safari 的閱讀列表,這是如何實現的?

隨著 Ad Blocker 插件的普及,惡意廣告也在利用瀏覽器功能的進化而不斷創新。


初步分析,應該人人影視上的廣告JS的行為。通過測試,發現廣告JS似乎對用戶做了標記,第一次訪問時會隨機添加一個遊戲網站到用戶的閱讀列表,並給用戶打上標記,後續一段時間的訪問不會繼續自動添加URL到閱讀列表。

啟用無痕瀏覽模式,繼續分析,中間過程略過,抓到核心代碼,位於http://p.btyou.com/view.php?uid=15142第96-106行(網址無法直接打開,伺服器進行referer驗證了)。

核心代碼以及注釋如下:

a.hrefopen = function(a) {
//容錯代碼, 不用管
try{
//下面三行代碼是創建一個超鏈接, 指向一個URL: a.
var c = document.createElement("a");
c.setAttribute("href", a);
c.setAttribute("style", "display:none;");
//下面三行代碼是模擬滑鼠去點擊上面創建的超鏈接
var b = document.createEvent("MouseEvents");
b.initMouseEvent("click", false, false, window, 0, 0, 0, 0, 0, false, false, true, false, 0, null);
c.dispatchEvent(b);
return true;
//容錯代碼, 不用管
}catch(q){return false;}
}

這段代碼的大意就是自動創建一個URL為a的超鏈接,並模擬用滑鼠去點它,是一個典型的彈窗代碼。但是這段代碼,在Safari中,卻莫名其妙的變成了向閱讀列表中添加條目了,實在是廣告商無心插柳之作(@孫北吉 的回答以及評論都說明了這可能就是廣告商針對Safari瀏覽器的特殊動作)。 的我把這段代碼放在了Edit fiddle - JSFiddle上,有興趣的朋友可以去訪問下。Safari下是將百度首頁添加到閱讀列表,而其他瀏覽器下是彈出百度首頁的窗口(而且很有可能被瀏覽器攔截)。

======Update: @2014-02-03 20:29:58=====

目前暫時修復這個Bug的辦法:

在Safari中添加AdBlock插件,點擊AdBlock圖標,點選「選項」,進入「自訂」標籤頁,在「手動編輯您的過濾規則」旁點擊「編輯」,複製

http://p.btyou.com/view.php?uid=*

到文本框並保存。

這個辦法只能避免http://p.btyou.com上的JS文件往你的閱讀列表中添加網頁,但無法避免其他域下的類似代碼進行類似的操作。我已經把這個Bug提交到蘋果開發者中心,最本質的修復只能等蘋果來做了。


補充 @王磊 的答案。核心在於人人影視的廣告模擬了一個點擊事件:

b.initMouseEvent(
"click",
false,
false,
window,
0,
0,
0,
0,
0,
false,
false,
true,
false,
0,
null
)

參看定義:

void initMouseEvent(
String typeArg,
boolean canBubbleArg,
boolean cancelableArg,
org.w3c.dom.views.AbstractView viewArg,
int detailArg,
int screenXArg,
int screenYArg,
int clientXArg,
int clientYArg,
boolean ctrlKeyArg,
boolean altKeyArg,
boolean shiftKeyArg,
boolean metaKeyArg,
short buttonArg,
EventTarget relatedTargetArg
)

注意倒數第四個為「true」的參數「boolean shiftKeyArg」,指「是否在 Event 期間按下 shift 鍵」。

也就是說:這個點擊事件模擬了一個「按下 shift 鍵點擊鏈接」的事件。而在 Safari 中,按住 shift 鍵點擊一個鏈接,就是將該鏈接添加到閱讀列表的快捷鍵。(這應當不是無心之舉)

瀏覽器應當區分事件是由腳本模擬觸發還是人為實際觸發,並對前者進行限制。在 Chrome 中,人為按住 shift 點擊鏈接是用新窗口打開,但是用腳本模擬按住 shift 點擊鏈接的事件則會被視為彈出窗口予以攔截。但是,Safari 沒有做到這種區分。

問題很好修正,等蘋果了。


前面的分析已經不錯了,我來說說這個「特性」是不是有意針對 Safari 閱讀列表而設計的問題。

是否是無心之舉要看是否做了 Safari 瀏覽器的判斷。沒有這個代碼,那就不是

為什麼要模擬 Shift 按鈕呢?這是因為目前用戶使用的瀏覽器絕大多數都是支持多 Tab 瀏覽 (tabbed browsing) 的。在這些瀏覽器中,Shift + click 的功能是開新窗口打開頁面,而不是開新 Tab. 因為新 Tab 可能會在後台打開 (background, 即打開而不切換過去) ,而新窗口就直接彈出來了。顯然,開新窗口的「展示效果」更好。

什麼,用戶體驗不好?流氓會跟你談體驗?


謝謝分析,js blocker很好用


把http://p.btyou.com加入hosts里屏蔽就行了


推薦閱讀:

有哪些目前流行的前端框架?
ES6的class關鍵字有沒有實現真正的面向對象?
關於JS中this作為方法調用?
如何評價 TypeScript 1.7?
npm、bower、jamjs 等包管理器,哪個比較好用?

TAG:Mac | 互聯網 | JavaScript | Safari |