React - useEffect cleanup with fetch abort

前言 前陣子在公司開發一個搜尋網站,參考第三方開源專案 searchkit 的設計架構,嘗試使用 GraphQL 搭配 Elasticsearch 來透過一次 request 獲取大量 resource 的搜尋資料,前端則使用 React 搭建 SPA 網頁,但在使用頁籤跳頁時卻出現 React 的警告: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. 大概知道是 useEffect 要 cleanup 的問題,但卻不知道 callback funtion 該怎麼做,debug 了好一陣子也未果,後來因緣際會下看到幾篇技術文章才恍然大悟,原來 fetch 就有 abort 可以處理,因此簡單以 pagination 的情境來重現上述問題,順手作個紀錄 重現問題 為了重現當初遇到的問題,找了 jsonplaceholder 上的 open data,來做一個文章(posts) pagination 的 demo...

<span title='2023-02-21 09:32:04 +0800 +0800'>February 21, 2023</span>&nbsp;·&nbsp;4 min&nbsp;·&nbsp;745 words&nbsp;·&nbsp;Madi

Node.js - Socket.io 實作多人聊天室

前言 前幾天研究了一下 Client Pull 和 Server Push 的幾種方式,其中屬於 Server Push 的 SSE(Server Send Event)已經在之前的文章 資料實時更新的方式 - Client Pull vs Server Push 中實作過,這次來研究另一種 Server Push 的方式,同時也是較常聽到的 WebSocket,來研究看看如何實作一個簡單的多人聊天室 簡介 Socket.io 因為待會 demo 的前後端會使用 Socket.io 套件來實作,所以開始前先來介紹一下 Socket.io 這個套件 (以下內容整理自官網介紹) Socket.IO is a library that enables low-latency, bidirectional and event-based communication between a client and a server. Socket.io 也是為了解決網路即時通訊而誕生,但是他並不像 WebSocket 一樣屬於通用協定,而是將底層 WebSocket 抽象化的 JavaScript Library(包含前端與後端的 npm 套件),所以 Socket.io 是建於 WebSocket 之上,有自己定義的溝通格式。 Socket.IO is NOT a WebSocket implementation....

<span title='2023-02-10 00:49:13 +0800 +0800'>February 10, 2023</span>&nbsp;·&nbsp;3 min&nbsp;·&nbsp;585 words&nbsp;·&nbsp;Madi

密碼學中的 Encode(編碼)、Encrypt(加密) 跟 Hash(雜湊) 差異

前言 前陣子用 Node.js 開發時需要用一組加解密的 key 來將某個 url 的 query parameters 加密,就重新回頭研究一下對稱加密與非對稱加密的差異和手段,最後統一用 Node.js 的套件來簡單實作,留下此篇文章以供未來參考 密碼學在學什麼? 密碼學的目標可以簡單列出底下三個: 資訊保密: 確保只有授權者才能取得訊息 完整性驗證: 確保資訊沒有遭到算改 身分驗證: 驗證傳送方與接受方的身分 密碼學主要分為三種,先講結論: Encode(編碼) Two way 的轉換,只是編碼格式的轉換,不需要密碼,所以不算加密,沒有任何資安防護能力 Encrypt(加密) Two way 的轉換,需要密碼介入,可分成對稱加密與非對稱加密,前者是同一把金鑰,後者是有一組公私鑰,有防護資安的能力 Hash(雜湊) One way 的轉換(不可逆),應用 Hashing 的演算法將待加密的字串轉換成一個獨一無二的 hash digest Encode(編碼) 只是換個方式來呈現資料 沒有加密,所以沒有安全性 只是各種平台使用數據的載體,ex: QRCode、UTF-8 為了配合網路傳輸的標準規範(RFC,Requests For Comment),有時就必須透過編碼後才能傳送 Base64 是一種基於 64 個字符來表示的方法 Base64 中的 64 其實是有含意的,他會把資料轉成: a~z (26) A~Z (26) 0~9 (10) + (1) / (1) base64 的 64 就是上面五種字元的所有可能(26+26+10+1+1=64) 打開瀏覽器的 console 介面,用 Web API 就可以開箱及用...

<span title='2023-02-06 19:49:13 +0800 +0800'>February 6, 2023</span>&nbsp;·&nbsp;3 min&nbsp;·&nbsp;521 words&nbsp;·&nbsp;Madi

DNS紀錄 - CNAME vs A record vs ACME-Challenge

前言 一直以來都只知道 DNS 是負責將域名(domain name)轉換成 ip 的網路服務,讓人類不需要去記又臭又長又難記的 ip,可以更輕鬆地透過類似門牌的域名來記憶網址.但隨著開發經驗愈來愈多之後,碰到各種網路上的問題,這時候就覺得自己懂的太少了,所以有了這篇來督促自己更深入的了解一下 DNS,以及它背後的其他元件. 主要的四種 DNS servers 圖片參考:cloudflare DNS server 又分成四種,各司其職的來完成 DNS Lookup Recursive Resolver 是 DNS Lookup 的第一步 當 client 遞迴的發送請求給 Recursive Resolver,他就會繼續往下一個 DNS server 發送請求來獲取 DNS record,直到 timeout 拋出錯誤或是成功找到 DNS record 為了避免同個 DNS record 每次都被 client 反覆請求,DNS 會有快取的機制以迅速回應相同的 DNS Lookup 若以圖書館來比喻,Recursive Resolver 就像是圖書館的管理員 Root Nameserver 是 DNS Resolve(Translate)的第一步 遵照 Recursive Resolver 想查找的 DNS record,去問下一個 TLD Nameserver 若以圖書館來比喻,Root Nameserver 就像是圖書館的索引(index),指向不同書架上的書 TLD Nameserver TLD(top level domain)是一個網域的頂級網域,以 example....

<span title='2023-02-05 00:49:13 +0800 +0800'>February 5, 2023</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;386 words&nbsp;·&nbsp;Madi

Docker: PostgreSQL Backup & Restore

前言 前陣子因為專案需求,需要把某個 docker 的 PostgreSQL container 資料備份到另一台 docker container 內,因此紀錄一下整體過程 簡例 首先,先拉取 postgresql 14.6 版的 image docker pull postgres:14.6 docker image | grep postgres # 取得image id 再來準備一份測試的 seed.csv,等等要匯入 postgresql 中 title,content Eric,Hello Madi,Hi Danny,GoAhead Kyle,Looks grood 將 postgresql 的 container 跑起來,並 bind mount 掛載剛剛的 csv 檔 docker run -itd --rm --name example -p 5432:5432 -v "$(pwd)"/seed.csv:/seed.csv -e POSTGRES_PASSWORD=postgres <image_id> 接著,跳進去 container 內,把 csv 的內容匯入 postgresql 中 docker exec -it example psql -U postgres -d postgres /* 要先依照csv的內容建立table */ CREATE TABLE article(title text, content text); /* 將csv匯入table */ COPY article (title, content) FROM '/seed....

<span title='2023-01-31 00:49:13 +0800 +0800'>January 31, 2023</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;328 words&nbsp;·&nbsp;Madi