Skip to main content

2-2


判斷瀏覽器環境是否為 IE

  • 主要從兩個方式去判斷:navigator.userAgent、HTML 內插入註解的 [if IE]..![endif] 語法
  • HTML 插入註解的判斷語法只適用到 IE 9 為止,IE 10 以上至 Edge 就無法用此語法判斷。
<!--[if lte IE 9]>
IE 瀏覽器版本小於等於 9
<![endif]-->
  • 判斷式成立時其裡面的 HTML 將會渲染,可用作顯示瀏覽器版本不相容等等的提示介面
  • IE 10 以上只能用 navigator.userAgent 做判斷了
// IE 10
// ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';

// IE 11
// ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';

// Edge 12 (Spartan)
// ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0';

// Edge 13
// ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586';

S3 物件存取公開權限設定

  • 封鎖公有存取權 (儲存貯體設定),為控制此 S3 可以開放哪些權限,若要寫 s3 policy,此“封鎖透過新的公開儲存貯體或存取點政策授予的對儲存貯體和物件的公開存取權” (第三個)需開放。
  • 要公開存取 S3 的檔案需將“封鎖公有存取權“全開(經實測),還需要將 S3 的檔案 make public,但一個個設定不實際,故 S3 policy 設定公開 policy 後,就能直接存取檔案,不用再一個個設定 public 了。(可以想像 policy 套用全部一個個的檔案。)(先後順序,晚定義 policy,前面已有的檔案就不會吃到 policy 設定,但還是可以手動公開。)(非公開但開放其他服務或帳戶存取的 policy 就沒有先後順序的問題了,只有公開才需注意。)

CloudFront 設定靜態網站路徑頁面

  • 以往 CloudFront 搭配 S3 架設的 SPA 網站,都是在 CF 做設定 403、404 導回 index.html 才能使 SPA 路由正確跳轉,S3 只需設定好 policy 允許 CF 存取。(只有一個根目錄的 index.html)
  • 現在用 Hexo 建立的部落格專案架設後,除了根目錄外,還有許多子目錄有 index.html,上述設定無法使用在純靜態網站上。
  • 因 CloudFront 主要作用為快取分發資源與內容,故要存取子目錄下的 index.html 得要打上完整的路徑與檔案名稱:https://cloundfront-example-domain/about/index.html
  • 但在實務上不可能這樣使用,故根據下面文章提供的方法:將 S3 開啟靜態網站功能,並設定存取公開,設定 CF 的源為 S3 靜態網站的路徑,非以前的 S3 bucket 資源名稱。
  • 此方法是直接使用 S3 本身的靜態網站功能做使用,404 頁面等設定就在 S3 的靜態網站功能內做設定就行了, CF 只負責將 domain 流量導到 S3 靜態網站路徑,缺點是該 S3 bucket 內的資源必須公開存取。
  • 資料來源:https://www.mark-gilbert.co.uk/serving-index-pages-from-non-root-locations-with-aws-cloudfront/

IE 不支援 Blob arrayBuffer()

跨域請求在IE下報錯


APP webview

  • 在手機 APP 內點擊網頁連結,不會叫出預設的瀏覽器(chrome、safari ),而會使用內建瀏覽器,專有名詞叫做 In-App browser,或是 webView。
  • 內建瀏覽器不像常見的瀏覽器支援較多實作,網頁常會在 webView 中發生錯誤。
  • navigator.userAgent 來判斷也只是一時之計,因為 webView 一更新改動會變,或每家的 APP 要判斷的也都不一樣,只能見招拆招。
// 判斷常用 APP
var u = navigator.userAgent,
ua = navigator.userAgent.toLowerCase(),
isLineApp = u.indexOf("Line") > -1, // Line 內建瀏覽器
isFbApp = u.indexOf("FBAV") > -1, // FB App 內建瀏覽器
isWeixinApp = ua.match(/MicroMessenger/i) == "micromessenger"; // 微信內建瀏覽器
  • 分享到 Line 上的網址加上 ?openExternalBrowser=1,可強制外部開啟。

webview 會發生的額外問題:

  • alert() :無法出現對話提醒視窗
  • confirm() :對話確認視窗無法出現
  • 下載圖片(儲存影像):無法使用
  • window.open 或 window.opener:與電腦上完全不同的顯示行為。
  • window.close 或 self.close :失效。

參考資料:https://www.wfublog.com/2018/06/mobile-detect-webview-fb-line-in-app.html


JS 語法

  • 能用模板字符串語法呼叫 function,函式第一個參數為被變數分割的字串陣列,第二個參數之後為模板變數,按照順序。
function handler(array, var1, var2, var3) {
console.log(array)
console.log(var1)
console.log(var2)
console.log(var3)
}
const fruit = 'apple'
const candy = 'sweet'
handlerThis is a ${fruit} and some ${candy}.
// ['This is a ', ' and some ', '.' ]
// 'apple'
// 'sweet'
// undefined

CORS 相關

  • 瀏覽器 cookie 是分 domain:*.[sample.com](http://sample.com/) !== *.sample2.com
  • 瀏覽器 origin 的定義是 protocol + domain + host 必須相同,否則皆為 cross origin。
  • CORS 是因安全性問題而產生,主要例子為保護伺服器內網
  • CORS 對於簡單請求會擋住伺服器 response (但還是有發出並作用),非簡單請求會先發送預檢請求 (options),如伺服器 response 沒有允許的 header,預檢請求的 response 就會被擋住,進而要發送的 request 會發不出去。
  • CORS 問題主要是後端要配置合適的 header,以符合瀏覽器的安全性設置,允許前端做資料操作。
  • CORS 可以設 cache 的 header ,讓長得一樣 headers 的 request 對同一個資源可以做快取。(*這邊所謂的快取是對於非簡單請求就不會再發送預檢請求了,會直接發主要的 request)
  • no-cors mode,一旦設定這個,正確的 response 就是拿不到。
  • 參考資料:https://blog.huli.tw/2021/02/19/cors-guide-1/

JS 特性小知識

[]!==[]
// 陣列為傳址,故兩個陣列參考的位址不同。
'b' + 'a' + + 'a' + 'a' = 'baNaNa'
// +與+中間有空格時,第一個+解析成運算符,第二個+解析成正號,
// 將後面的值做正數,但後面的 'a' 無法轉數字故會變成 NaN

瀏覽器快取機制

  • Expiresmax-age 負責看快取是否過期。
  • Last-ModifiedIf-Modified-Since (依照時間)、EtagIf-None-Match (依照檔案 hash)負責看取過期後是否能繼續使用。
  • no-cache 會使用快取機制但每次都會問是否有更新。
  • no-store 代表不使用快取機制。
  • http://huli.logdown.com/posts/2223601-http-cache

S3 與 CORS

  • <img><script> 對於資源的請求一般不受跨網域限制 (chorme 有實作檢查該標籤請求資源格式不符合該標籤會 block 掉請求)
  • S3 對於請求資源的 response 為:標籤的一般請求回應不會加 Access-Control-Allow-Origin,對於 CORS 發送的請求會回應。
  • 問題發生在若已用一般請求得到 S3 response,之後有 CORS 請求時,由於 response cache 是看 url,故相同請求網址會 cache 住 (沒過期的情快下),故會用之前一般請求的 response 做回應,但一般請求不會有 Access-Control-Allow-Origin,所以該 CORS 請求被擋住而失敗。
  • 伺服器回應設置 Vary: Origin 的話,若兩次 request 的 origin header 不同,將會再發,不會沿用之前的。
  • 但上述對於 <script> 標籤在下列參考文章的情境中還是沒作用,所以可以用 crossorigin="anonymous" 屬性加在資源請求類的標籤上,使其變為 CORS 請求。
  • 參考資料:https://blog.techbridge.cc/2018/08/18/cors-issue/

CSRF

  • cookie 是跟著 site 而分開存,瀏覽器發送 request 時,根據請求 url 將該 site 的 cookie 給帶上。
  • 假設已在目標網站登入過有 cookie 等資料,點擊在惡意網站的連結,惡網連結實際上是對目標網站發送 request,這時目標網站的 cookie 將會被帶上,惡網就能取得目標網站的回應資料或做攻擊操作。
  • 傳統 server render 的網頁或 SPA 網站的情境下在下列參考資料都有方法可以避免 CSRF 攻擊。
  • 主要都是從:攻擊者無法得知與改寫目標網站的 cookie 與隨機 token 值做防範。
  • 參考資料:https://blog.techbridge.cc/2017/02/25/csrf-introduction/

Mac OS 更新後,Git 壞掉

  • 原因在於 Mac OS 更新後, Xcode 也需要 update。
xcode-select --install

CSS.supports()

  • 能用此方法檢查此瀏覽器環境是否支援該 CSS 功能
result = CSS.supports("text-decoration-style", "blink");
result = CSS.supports("display: flex");
result = CSS.supports("(--foo: red)");

result = CSS.supports(`(transform-style: preserve) or (-moz-transform-style: preserve) or
(-o-transform-style: preserve) or (-webkit-transform-style: preserve)`);

// result is true or false