那些被瀏覽器阻止的模擬事件...

瀏覽器裏面我們並不能愉快的用js模擬鼠標和鍵盤事件, 連最常用的click方法都收到許多限制, 比如在init函數中執行file_input.click()之類的. 我們可以快速查看使用HTML和JavaScript的文件上傳。如今,許多網站不再顯示原始<input type="file">元素。以Facebook爲例:

Facebook發佈表格

當您單擊上面突出顯示的照片按鈕時,將打開本機文件對話框:

Mac OS X上的文件選擇對話框

在現代瀏覽器中使這些功能發揮作用並不難。從本質上講,<input type="file">只要點擊照片按鈕,它就可以在隱藏時觸發點擊事件。這是一個很小但卻有效的HTML示例,可以重現該功能:

<html>
  <body>
    <input type="file" style="display: none" />
    <button>Open File Dialog</button>

    <script src="https://code.jquery.com/jquery-2.2.4.js"></script>
    <script>
      $("button").on("click", function() {
        $("input").trigger("click");
      });
    </script>
  </body>
</html>

事實上,如果我們嘗試一下,單擊“打開文件對話框”按鈕將打開文件對話框,正如我們所期望的那樣。現在讓我們嘗試在頁面加載後立即自動打開文件對話框:

<script>
  $("input").trigger("click");
</script>

這似乎不起作用。會不會是頁面構建過程一些api沒有準備好呢, 於是我settimeout之後再調用:

<script>
  setTimeout(function() {
    $("input").trigger("click");
  }, 1000);
</script>

這似乎也不起作用。爲什麼在第一個例子中,文件對話框已成功打開?第一個示例有效的原因是click事件是在代碼塊中觸發的,該代碼塊是用戶啓動的事件處理程序

當我們單擊按鈕時,已執行已註冊的處理程序功能,並且瀏覽器會跟蹤啓動該按鈕單擊事件的用戶的事實,而不是某些代碼。在此類用戶啓動的事件之外,無法以編程方式打開文件對話框。

類似地,當window.open()未在用戶啓動的事件的處理程序內調用時,現代瀏覽器通常不會打開新窗口。相反,他們會顯示如下警告:

谷歌瀏覽器:“彈出窗口被阻止”警告

諷刺的是, 在console接口中是可以愉快的模擬的, 因爲此時的你是用戶, 不過話又說回來了, 就算在初始化總共模擬了打開文件對畫框或者彈出一個新的頁面並不會造成什麼安全問題, 我們甚至可以給body監聽一個mouseenter事件(發生概率99%)然後讓瀏覽器以爲是用戶觸發了我們想要執行的代碼, 或者通過其他欺騙用戶的無聊手段, 但仔細想想也沒什麼意義....

總之這是一個坑把, 在以後的chromium中應該會改善, 至少目前是不能在網頁打開的時候立刻啓動文件對話框的..

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章