<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ian chen</title>
    <description>The latest articles on DEV Community by ian chen (@ian_chen_8bfda2699e7263dc).</description>
    <link>https://dev.to/ian_chen_8bfda2699e7263dc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3232307%2F6eb38cd4-15d8-447a-b95a-c259e66c66cf.png</url>
      <title>DEV Community: ian chen</title>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ian_chen_8bfda2699e7263dc"/>
    <language>en</language>
    <item>
      <title>📌 final / readonly 觀念筆記</title>
      <dc:creator>ian chen</dc:creator>
      <pubDate>Tue, 01 Jul 2025 15:40:40 +0000</pubDate>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc/final-readonly-guan-nian-bi-ji-4en5</link>
      <guid>https://dev.to/ian_chen_8bfda2699e7263dc/final-readonly-guan-nian-bi-ji-4en5</guid>
      <description>&lt;h2&gt;
  
  
  📖 Java &lt;code&gt;final&lt;/code&gt; 關鍵字
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;用法&lt;/th&gt;
&lt;th&gt;說明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;final&lt;/code&gt; 變數&lt;/td&gt;
&lt;td&gt;賦值後不可再變更參考，但物件內部內容可改&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;final&lt;/code&gt; 方法&lt;/td&gt;
&lt;td&gt;子類別不能 override 這個方法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;final&lt;/code&gt; class&lt;/td&gt;
&lt;td&gt;這個 class 不能被繼承&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  📌 範例：final 變數
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// ✅ OK，改內容&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt; &lt;span class="c1"&gt;// ❌ 不行，不能改變參考&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📖 C# 對應概念
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;Java&lt;/th&gt;
&lt;th&gt;C#&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;變數賦值後不可改變參考&lt;/td&gt;
&lt;td&gt;&lt;code&gt;final&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;readonly&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;防止子類 override 方法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;final&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sealed&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;防止 class 被繼承&lt;/td&gt;
&lt;td&gt;&lt;code&gt;final&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sealed&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  📌 C# readonly 範例
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;UserRepository&lt;/span&gt; &lt;span class="n"&gt;_userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_userRepository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📖 注意：
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;final&lt;/code&gt; / &lt;code&gt;readonly&lt;/code&gt; 限制的是「參考（reference）不能改」，&lt;strong&gt;物件內部的狀態還是可以改變&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;如果要讓物件內部不可改，需搭配 immutable 類型或資料結構&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📌 延伸觀念：建構子注入搭配 final / readonly
&lt;/h2&gt;

&lt;p&gt;推薦將依賴透過&lt;strong&gt;建構子注入&lt;/strong&gt;並宣告成 &lt;code&gt;final&lt;/code&gt; (Java) / &lt;code&gt;readonly&lt;/code&gt; (C#)，以保證依賴物件的參考安全、不被覆寫、且易於測試與維護。&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ 小結
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;final&lt;/code&gt; / &lt;code&gt;readonly&lt;/code&gt; 保護的是 &lt;strong&gt;參考&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sealed&lt;/code&gt; 保護的是 &lt;strong&gt;方法與 class 結構&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;操作物件內容不違反 final / readonly 規則，只是不能換參考。&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>csharp</category>
      <category>java</category>
    </item>
    <item>
      <title>Netlify 作為 Proxy 網頁代管平台介紹 + 解決 CORS 問題教學</title>
      <dc:creator>ian chen</dc:creator>
      <pubDate>Wed, 25 Jun 2025 07:36:08 +0000</pubDate>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc/netlify-zuo-wei-proxy-wang-ye-dai-guan-ping-tai-jie-shao-jie-jue-cors-wen-ti-jiao-xue-6p9</link>
      <guid>https://dev.to/ian_chen_8bfda2699e7263dc/netlify-zuo-wei-proxy-wang-ye-dai-guan-ping-tai-jie-shao-jie-jue-cors-wen-ti-jiao-xue-6p9</guid>
      <description>&lt;h2&gt;
  
  
  📌 什麼是 Netlify？
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://app.netlify.com" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt; 是一個現代化的前端部署平台，支援 CI/CD、自動部署、靜態資源託管、Function 無伺服器後端、以及提供 HTTPS、網域綁定等功能，特別適合前端工程或靜態網頁代管。&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 為什麼用來代管 Proxy 頁面？
&lt;/h2&gt;

&lt;p&gt;許多開發者使用 Netlify 來架設簡易 Proxy 或中繼頁面，主要優點如下：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ 免費方案就能支援自定網域與 HTTPS&lt;/li&gt;
&lt;li&gt;🚀 架設簡單，直接將 HTML 上傳即可&lt;/li&gt;
&lt;li&gt;🔧 支援 &lt;code&gt;netlify.toml&lt;/code&gt; 設定 Rewrite/Redirect 規則&lt;/li&gt;
&lt;li&gt;🌍 全球 CDN 分發，速度快且穩定&lt;/li&gt;
&lt;li&gt;🔒 自動產生 Let's Encrypt SSL 憑證&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠 如何建立簡易 Proxy 中繼頁
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;準備 HTML/JS 頁面&lt;/strong&gt;（或用 Function）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;建立 GitHub Repo 或本地專案&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;登入 &lt;a href="https://app.netlify.com" rel="noopener noreferrer"&gt;app.netlify.com&lt;/a&gt;&lt;/strong&gt; → &lt;code&gt;Add new site&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;設定 &lt;code&gt;netlify.toml&lt;/code&gt;：&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;   &lt;span class="nn"&gt;[[redirects]]&lt;/span&gt;
     &lt;span class="py"&gt;from&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/proxy/*"&lt;/span&gt;
     &lt;span class="py"&gt;to&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/.netlify/functions/proxy/:splat"&lt;/span&gt;
     &lt;span class="py"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
     &lt;span class="py"&gt;force&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌐 解決 CORS 問題（使用 Netlify Functions）
&lt;/h2&gt;

&lt;p&gt;若你要從前端 Fetch 其他網域的資料，會遇到 CORS 限制。&lt;br&gt;
這時你可以透過 Netlify 的 Serverless Function 作為後端代理，來避免 CORS 問題。&lt;/p&gt;

&lt;h3&gt;
  
  
  ➕ 步驟一：建立 &lt;code&gt;netlify/functions/proxy.js&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// netlify/functions/proxy.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/.netlify/functions/proxy/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;targetUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 解決 CORS&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Proxy Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ➕ 步驟二：設定 &lt;code&gt;netlify.toml&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build]&lt;/span&gt;
  &lt;span class="py"&gt;functions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"netlify/functions"&lt;/span&gt;

&lt;span class="nn"&gt;[[redirects]]&lt;/span&gt;
  &lt;span class="py"&gt;from&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/proxy/*"&lt;/span&gt;
  &lt;span class="py"&gt;to&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/.netlify/functions/proxy/:splat"&lt;/span&gt;
  &lt;span class="py"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧪 測試方式（JavaScript）
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://你的 netlify 網址/proxy/https%3A%2F%2Fexample.com%2Fapi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔐 安全注意事項
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;僅允許特定網域：你可以在 Function 中加白名單或驗證 Referer&lt;/li&gt;
&lt;li&gt;加上金鑰驗證或 API 防刷機制（避免被濫用）&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📝 結語
&lt;/h2&gt;

&lt;p&gt;Netlify 結合 Functions 可輕鬆打造具有 Proxy 功能的頁面，並解決常見的 CORS 問題，非常適合部署前端測試用的中繼 API 或跨域資料轉發。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 建議使用自己的 domain 加上防濫用機制，避免 proxy 被公用。&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>.NET Core 中的 `IOptions` 介紹</title>
      <dc:creator>ian chen</dc:creator>
      <pubDate>Thu, 19 Jun 2025 16:13:29 +0000</pubDate>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc/net-core-zhong-de-ioptions-jie-shao-k60</link>
      <guid>https://dev.to/ian_chen_8bfda2699e7263dc/net-core-zhong-de-ioptions-jie-shao-k60</guid>
      <description>&lt;p&gt;在 .NET Core（現在統一稱為 .NET）中，&lt;code&gt;IOptions&lt;/code&gt; 是一種用來&lt;strong&gt;讀取設定檔&lt;/strong&gt;的設計模式。它提供強型別的方式，讓你能從 &lt;code&gt;appsettings.json&lt;/code&gt; 或其他來源讀取資料，並注入到你的服務中。&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ 為什麼要用 &lt;code&gt;IOptions&lt;/code&gt;？
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ 強型別支援：比 &lt;code&gt;Configuration["Key"]&lt;/code&gt; 更安全、更容易維護
&lt;/li&gt;
&lt;li&gt;✅ 支援依賴注入（DI）：讓設定更容易測試與使用
&lt;/li&gt;
&lt;li&gt;✅ 支援監控與更新（使用 &lt;code&gt;IOptionsSnapshot&lt;/code&gt; 和 &lt;code&gt;IOptionsMonitor&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠 基本用法
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;appsettings.json&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"MySettings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"SiteName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Cool Site"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"EnableFeatureX"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 建立設定類別
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySettings&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;SiteName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;EnableFeatureX&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 在 Program.cs 或 Startup.cs 中綁定設定
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MySettings&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MySettings"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. 在服務中使用設定
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;MySettings&lt;/span&gt; &lt;span class="n"&gt;_settings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MySettings&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SiteName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔄 &lt;code&gt;IOptions&lt;/code&gt; 相關介面比較
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;介面類型&lt;/th&gt;
&lt;th&gt;功能說明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IOptions&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;一般用途，讀取設定值，啟動後不會變動&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IOptionsSnapshot&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;每次 DI 解析時會重新載入（適合 Scope 生命周期）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IOptionsMonitor&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;支援即時監聽設定變更（適合 Singleton）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ❓ 綁定失敗會怎樣？
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;若 JSON 少了某個欄位，該屬性會使用預設值（如 string 為 null、bool 為 false）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不會拋例外&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;若 JSON 值型別錯誤（如把布林值寫成字串），則會拋例外&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛡️ 加入設定驗證（推薦）
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 使用資料註解（Data Annotations）
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.ComponentModel.DataAnnotations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySettings&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Required&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;SiteName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;EnableFeatureX&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 註冊時啟用驗證
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MySettings&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MySettings"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateDataAnnotations&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ValidateOnStart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 啟動時驗證，錯誤會拋例外&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;這樣可以防止設定漏填，讓錯誤在啟動階段就被發現，而不是等到執行時才出問題。&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 小結
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IOptions&amp;lt;T&amp;gt;&lt;/code&gt; 是強型別、安全、支援 DI 的設定綁定方式&lt;/li&gt;
&lt;li&gt;預設為寬鬆綁定，欄位缺漏不會報錯&lt;/li&gt;
&lt;li&gt;若需強制驗證設定完整性，建議搭配 &lt;code&gt;ValidateDataAnnotations()&lt;/code&gt; 和 &lt;code&gt;ValidateOnStart()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>📘 WAF（Web Application Firewall）介紹與應用說明</title>
      <dc:creator>ian chen</dc:creator>
      <pubDate>Wed, 11 Jun 2025 02:13:07 +0000</pubDate>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc/wafweb-application-firewalljie-shao-yu-ying-yong-shuo-ming-4eo9</link>
      <guid>https://dev.to/ian_chen_8bfda2699e7263dc/wafweb-application-firewalljie-shao-yu-ying-yong-shuo-ming-4eo9</guid>
      <description>&lt;h2&gt;
  
  
  🔰 什麼是 WAF？
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;WAF&lt;/strong&gt; 全名為 &lt;strong&gt;Web Application Firewall（網站應用程式防火牆）&lt;/strong&gt;，是一種專門針對 Web 應用程式層級（第七層）的資安防護機制。&lt;br&gt;&lt;br&gt;
它不像傳統防火牆只檢查 IP、Port、協定，而是能深入檢查 HTTP/HTTPS 請求的內容，防範駭客常用的攻擊手法。&lt;/p&gt;


&lt;h2&gt;
  
  
  🎯 WAF 能防範哪些攻擊？
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;攻擊類型&lt;/th&gt;
&lt;th&gt;說明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SQL Injection&lt;/td&gt;
&lt;td&gt;透過注入惡意 SQL 查詢操控資料庫，例如 &lt;code&gt;1' OR 1=1--&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-Site Scripting（XSS）&lt;/td&gt;
&lt;td&gt;嵌入惡意 JavaScript，例如 &lt;code&gt;&amp;lt;script&amp;gt;alert(123)&amp;lt;/script&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-Site Request Forgery（CSRF）&lt;/td&gt;
&lt;td&gt;偽造使用者請求執行操作，例如偷偷發送刪除帳號請求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command Injection&lt;/td&gt;
&lt;td&gt;注入 OS 指令，例如 &lt;code&gt;; rm -rf /&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File Inclusion（LFI/RFI）&lt;/td&gt;
&lt;td&gt;引入惡意程式碼檔案執行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP Flood、DoS 攻擊&lt;/td&gt;
&lt;td&gt;短時間大量請求癱瘓網站服務&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  🛠️ WAF 的部署方式
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🔁 反向代理（Reverse Proxy）
&lt;/h3&gt;

&lt;p&gt;WAF 通常會部署在 Web Server 之前，扮演流量的代理者，外部訪客的流量會先進到 WAF，再由 WAF 轉發至內部伺服器。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Client]
   ↓
[WAF ← 對外開放 IP/Port]
   ↓
[Web Server（VM）]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📦 WAF 功能總覽
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;說明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;請求內容過濾&lt;/td&gt;
&lt;td&gt;攔截包含惡意 Payload 的參數、Header、Body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IP 控制&lt;/td&gt;
&lt;td&gt;封鎖特定來源 IP 或設白名單&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;負載平衡&lt;/td&gt;
&lt;td&gt;部分 WAF 可做多台主機流量分配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;日誌與警報&lt;/td&gt;
&lt;td&gt;記錄可疑請求與阻擋記錄，供後續分析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL 終止&lt;/td&gt;
&lt;td&gt;可在 WAF 處理 SSL 解密，減少後端負擔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;行為學習&lt;/td&gt;
&lt;td&gt;進階 WAF 有 AI 模型可自動學習並預測異常行為（如 Cloudflare Bot 管理）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🌐 常見的 WAF 方案
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;類型&lt;/th&gt;
&lt;th&gt;代表產品&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;雲端型&lt;/td&gt;
&lt;td&gt;Cloudflare WAF、AWS WAF、Azure WAF、Imperva&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;軟體型&lt;/td&gt;
&lt;td&gt;ModSecurity（支援 Apache/Nginx）、NAXSI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;硬體型&lt;/td&gt;
&lt;td&gt;F5 BIG-IP ASM、Fortinet FortiWeb、Palo Alto WAF&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  👨‍💻 WAF 的實際應用場景
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ 電商平台
&lt;/h3&gt;

&lt;p&gt;保護購物網站避免被植入惡意腳本、SQL 注入造成資料外洩。&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ 政府單位
&lt;/h3&gt;

&lt;p&gt;強制部署資安設備防止駭客攻擊網站介面。&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ API Gateway
&lt;/h3&gt;

&lt;p&gt;攔截非法 API 存取請求，避免敏感資料被未授權使用。&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ SaaS 平台
&lt;/h3&gt;

&lt;p&gt;保護多租戶環境中的各個客戶資料，避免跨站操作。&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 自製簡易 WAF 的方式（學習用途）
&lt;/h2&gt;

&lt;p&gt;你可以用以下技術製作一套基本的 WAF：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;使用 Nginx + Lua（OpenResty）做請求過濾&lt;/li&gt;
&lt;li&gt;在 ASP.NET Core / Django / Node.js 寫 Middleware 分析請求內容&lt;/li&gt;
&lt;li&gt;使用 Regex 或字串比對過濾常見攻擊字樣&lt;/li&gt;
&lt;li&gt;加入封鎖機制與黑名單功能&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;📌 建議參考 &lt;a href="https://coreruleset.org/" rel="noopener noreferrer"&gt;OWASP CRS（Core Rule Set）&lt;/a&gt; 當作 WAF 規則庫基礎&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔚 結語
&lt;/h2&gt;

&lt;p&gt;WAF 是現代網站不可或缺的資安防線。隨著 Web 應用日益複雜，攻擊手法層出不窮，WAF 能有效減少漏洞被濫用的機率。&lt;br&gt;&lt;br&gt;
不論是商業網站、API 系統、或是內部平台，只要有對外服務，都建議部署 WAF 來保障系統與資料安全。&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>learning</category>
    </item>
    <item>
      <title>OOA、OOD、OOP 的區別與關係說明</title>
      <dc:creator>ian chen</dc:creator>
      <pubDate>Sat, 07 Jun 2025 16:20:06 +0000</pubDate>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc/ooa-ood-oop-de-qu-bie-yu-guan-xi-shuo-ming-275a</link>
      <guid>https://dev.to/ian_chen_8bfda2699e7263dc/ooa-ood-oop-de-qu-bie-yu-guan-xi-shuo-ming-275a</guid>
      <description>&lt;h2&gt;
  
  
  1. OOA（物件導向分析）
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;聚焦「分析」階段，了解系統需求與問題域。&lt;/li&gt;
&lt;li&gt;找出系統中的物件（實體）、它們的屬性與行為，及物件間的關係。&lt;/li&gt;
&lt;li&gt;目標是建立一個符合需求的物件模型。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. OOD（物件導向設計）
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;聚焦「設計」階段，基於分析結果，定義系統架構。&lt;/li&gt;
&lt;li&gt;設計類別的結構（類別圖）、方法、繼承關係、介面、物件間的互動。&lt;/li&gt;
&lt;li&gt;確保系統設計能夠良好實作、擴充與維護。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. OOP（物件導向程式設計）
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;聚焦「實作」階段，用程式語言撰寫類別和物件。&lt;/li&gt;
&lt;li&gt;將設計階段的藍圖落實成可執行的程式碼。&lt;/li&gt;
&lt;li&gt;運用封裝、繼承、多型、抽象等物件導向特性。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  OOD 與 OOP 的區別
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OOD 是設計&lt;/strong&gt;，屬於規劃層面：思考怎麼用物件去解決問題，定義類別和物件間的結構與行為。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OOP 是實作&lt;/strong&gt;，屬於程式碼層面：把設計轉成程式碼，實現物件的屬性和方法。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  常見狀況
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;在實務上，很多人會混用 OOD 與 OOP 這兩個詞，因為設計與實作往往緊密結合，界線不一定非常明確。&lt;/li&gt;
&lt;li&gt;特別是小型專案或快速開發時，設計與實作常常同步進行。&lt;/li&gt;
&lt;li&gt;嚴格說來，兩者是不同階段，但都屬於物件導向軟體開發過程的一部分。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  總結
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;階段&lt;/th&gt;
&lt;th&gt;內容&lt;/th&gt;
&lt;th&gt;目的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OOA&lt;/td&gt;
&lt;td&gt;分析需求，找出物件與關係&lt;/td&gt;
&lt;td&gt;理解系統需求與實體&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OOD&lt;/td&gt;
&lt;td&gt;設計系統架構與物件結構&lt;/td&gt;
&lt;td&gt;規劃如何組織與互動&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OOP&lt;/td&gt;
&lt;td&gt;用程式語言撰寫物件與類別&lt;/td&gt;
&lt;td&gt;實作設計、完成功能&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;因此，&lt;strong&gt;OOD 與 OOP 在本質與角色上有明確差異，但在實務中常常交織使用，不會造成衝突。&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>程式設計</category>
      <category>軟體工程</category>
    </item>
    <item>
      <title>處理後端 BigInt 傳到前端時精度丟失的問題</title>
      <dc:creator>ian chen</dc:creator>
      <pubDate>Mon, 02 Jun 2025 09:07:28 +0000</pubDate>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc/jie-jue-qian-duan-json-chuan-bigint-jing-du-diu-shi-wen-ti-wo-du-shi-zhuan-cheng-zi-chuan-lai-chu-li-3hnd</link>
      <guid>https://dev.to/ian_chen_8bfda2699e7263dc/jie-jue-qian-duan-json-chuan-bigint-jing-du-diu-shi-wen-ti-wo-du-shi-zhuan-cheng-zi-chuan-lai-chu-li-3hnd</guid>
      <description>&lt;p&gt;在開發過程中，我經常會遇到後端資料庫的 &lt;code&gt;bigint&lt;/code&gt; 欄位資料，尤其是像 ID 或金額這類數字很大的欄位。這些 &lt;code&gt;bigint&lt;/code&gt; 資料在後端處理沒問題，但當我把它們包成 JSON 丟到前端時，就常常遇到&lt;strong&gt;精度丟失&lt;/strong&gt;的狀況。&lt;/p&gt;




&lt;h2&gt;
  
  
  為什麼會發生 bigint 精度丟失？
&lt;/h2&gt;

&lt;p&gt;這問題的根源主要是在 JavaScript 本身的數字型別限制。JavaScript 的 &lt;code&gt;Number&lt;/code&gt; 是以 &lt;strong&gt;IEEE 754 雙精度浮點數格式&lt;/strong&gt;儲存的，最大安全整數範圍是：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-(2^53 - 1) 到 2^53 - 1
也就是大約 ±9007199254740991
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;當 &lt;code&gt;bigint&lt;/code&gt; 的數值超出這個範圍，JavaScript 就&lt;strong&gt;無法精準表示&lt;/strong&gt;，數字會自動被四捨五入或變形，造成精度丟失。&lt;/p&gt;

&lt;p&gt;這種狀況在 JSON 傳輸過程中也無法避免，因為：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON 標準本身不支援 &lt;code&gt;BigInt&lt;/code&gt; 類型&lt;/li&gt;
&lt;li&gt;JSON 僅支援 &lt;code&gt;number&lt;/code&gt; 或 &lt;code&gt;string&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;當 JSON 解析器看到一個超大的數字，就會轉成 JavaScript 的 &lt;code&gt;Number&lt;/code&gt;，此時就會&lt;strong&gt;失去精度&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  解決方式：丟給前端前先轉成字串
&lt;/h2&gt;

&lt;p&gt;為了解決這個問題，我通常會選擇在後端把 &lt;code&gt;bigint&lt;/code&gt; &lt;strong&gt;先轉成字串（string）&lt;/strong&gt;，再包進 JSON 傳給前端。&lt;/p&gt;

&lt;p&gt;這樣前端收到的就是字串，不會被 JavaScript 的數字型別誤判成不準確的數字。前端如果需要進一步處理這些數字，也可以使用像 &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt" rel="noopener noreferrer"&gt;&lt;code&gt;BigInt&lt;/code&gt;&lt;/a&gt; 或 &lt;a href="https://github.com/MikeMcl/big.js" rel="noopener noreferrer"&gt;big.js&lt;/a&gt;、&lt;a href="https://github.com/MikeMcl/decimal.js" rel="noopener noreferrer"&gt;decimal.js&lt;/a&gt; 等第三方工具來處理精準的數字運算。&lt;/p&gt;




&lt;h2&gt;
  
  
  總結
&lt;/h2&gt;

&lt;p&gt;這個問題其實不是 JSON 本身的問題，而是 JavaScript 數字型別的限制。&lt;/p&gt;

&lt;p&gt;只要我把 &lt;code&gt;bigint&lt;/code&gt; 用 &lt;strong&gt;字串方式傳遞&lt;/strong&gt;，再用相對應的大數字工具處理，就能輕鬆避免精度丟失，讓前後端資料保持一致，避免後續因數字不準確而產生的錯誤。&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>日誌札記</title>
      <dc:creator>ian chen</dc:creator>
      <pubDate>Sat, 31 May 2025 16:18:24 +0000</pubDate>
      <link>https://dev.to/ian_chen_8bfda2699e7263dc/ri-zhi-zha-ji-186</link>
      <guid>https://dev.to/ian_chen_8bfda2699e7263dc/ri-zhi-zha-ji-186</guid>
      <description>&lt;p&gt;這幾天心情有點起伏，公司的老同伴又離開了一位，放假前一天外公走了，真的有點崩潰，希望接下來一切順遂，peace&lt;/p&gt;

&lt;p&gt;紀念我的外公外婆，想念在天上的你們，我愛你們&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmi0a01fry2e6ro7nkh9v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmi0a01fry2e6ro7nkh9v.jpg" alt="Image description" width="800" height="1783"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>mentalhealth</category>
      <category>gratitude</category>
    </item>
  </channel>
</rss>
