2025年6月12日 星期四

如何防止測試網站被 Google 搜尋引擎收錄?完整指南

在網站開發過程中,通常會有測試環境(例如 staging.example.com),用來驗證功能、佈署流程或設計樣式。但你絕對不希望這些測試網站被 Google 收錄,否則可能會影響 SEO 或洩漏未公開資訊。

這篇文章將完整介紹幾種有效的方式,防止測試網站被搜尋引擎(如 Google)收錄與索引,並提供實作範例,讓你輕鬆上手。

為什麼測試網站會被收錄?

Googlebot(Google 的爬蟲)會自動搜尋網路上的網站,只要:

  • 網站能連上
  • 沒有阻擋爬蟲
  • 有外部連結指向

那麼就可能被收錄。即使沒有主動提交,只要一個連結出現在別的頁面,就可能進入 Google 索引。

方法一:使用 robots.txt 阻擋爬蟲

在網站根目錄新增 robots.txt 檔案,加入以下內容:

User-agent: *
Disallow: /

這代表對所有搜尋引擎「禁止抓取整個網站」。

⚠️ 注意:
robots.txt 僅告訴搜尋引擎「不要抓」,但它 不會阻止網址被收錄。如果某個網址被外部連結指向,網址還是可能出現在搜尋結果中。

方法二:使用 <meta name="robots"> 阻擋索引

在 HTML 頁面的 <head> 區塊加入:

<meta name="robots" content="noindex, nofollow">

這告訴搜尋引擎「不要索引這個頁面,也不要追蹤裡面的連結」。Google 必須能成功抓到頁面,才能讀取這段設定。

方法三:用 HTTP Header 傳送 X-Robots-Tag(適用 Nginx)

如果你使用 Nginx,也可以透過 HTTP header 傳送禁止收錄的資訊。

Nginx 設定範例(整站禁止收錄):

location / {
    add_header X-Robots-Tag "noindex, nofollow" always;
    proxy_pass http://backend;
}

使用 always 是為了讓所有狀態碼(不只是 200)都加上這個 header。

用 curl 驗證:

curl -I https://your-site.com

預期輸出:

X-Robots-Tag: noindex, nofollow

方法四:帳號密碼保護(最有效)

透過 HTTP Basic Auth 保護測試站,搜尋引擎無法登入,自然也無法索引。

Apache .htaccess 範例:

AuthType Basic
AuthName "Restricted"
AuthUserFile /var/www/.htpasswd
Require valid-user

Nginx Basic Auth 範例:

location / {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

這種方法最保險,Google 連抓都抓不到

附加提醒:Google Search Console 移除已收錄內容

  1. 前往 Google Search Console
  2. 使用「移除網址」工具
  3. 提交要移除的網址

方法總結

方法 可防止被收錄 可防止被抓取 備註
robots.txt 只是建議,可能仍被列出
<meta name="robots"> Google 要能抓到才有效
X-Robots-Tag 適用靜態檔、API
密碼保護 最安全有效

結語

建議:測試環境最好同時使用「密碼保護」與「noindex」設定,確保不被搜尋引擎收錄與解析,避免意外曝光未發佈內容。

2025年6月1日 星期日

C# 非同步背景任務完整攻略:async/await、ThreadPool、SemaphoreSlim 與協程並發控制(含範例)

在現代 C# 開發中,如何有效執行背景任務、限制併發數量、與 UI 協作已成為必備技能。本篇文章整理各種方式的特性、應用場景,並附上實用程式碼範例。

🧩 為何需要多種背景任務執行方式?

背景任務可避免 UI 卡頓、提升效能並允許多工操作。常見需求包括:

  • 執行不阻塞主線程(UI)
  • 控制同時併發的數量
  • 可 await 等待完成
  • 與 WinForms / WPF UI 結合

✅ 背景任務方式比較(含執行類型)

技術控制併發數支援 async/await適用場景UI 支援執行方式
BackgroundWorker舊式 WinForms/WPF 背景任務Thread
ThreadPool快速提交背景任務Thread
Task / Task.Run一般非同步任務Thread
Task + SemaphoreSlim控制併發數、IO 密集任務Thread + Coroutine
Parallel.ForEachCPU 密集型處理Thread
TPL Dataflow複雜資料管線與佇列Thread
async/await✅(手動限制)非同步 API / DB / IO 流程Coroutine

🧪 範例程式碼

1️⃣ BackgroundWorker

var worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
    Thread.Sleep(2000);
    e.Result = "任務完成";
};
worker.RunWorkerCompleted += (s, e) =>
{
    MessageBox.Show((string)e.Result);
};
worker.RunWorkerAsync();

2️⃣ ThreadPool

ThreadPool.QueueUserWorkItem(state =>
{
    Console.WriteLine("背景任務開始");
    Thread.Sleep(1000);
    Console.WriteLine("任務完成");
});

3️⃣ Task / Task.Run


await Task.Run(() =>
{
    Thread.Sleep(1000);
    Console.WriteLine("Task 執行完成");
});

4️⃣ Task + SemaphoreSlim(控制併發數)

var semaphore = new SemaphoreSlim(3);
var tasks = new List<Task>();

for (int i = 0; i < 10; i++)
{
    int index = i;
    tasks.Add(Task.Run(async () =>
    {
        await semaphore.WaitAsync();
        try
        {
            Console.WriteLine($"工作 {index} 開始");
            await Task.Delay(2000);
            Console.WriteLine($"工作 {index} 結束");
        }
        finally
        {
            semaphore.Release();
        }
    }));
}

await Task.WhenAll(tasks);

5️⃣ Parallel.ForEach

Parallel.ForEach(Enumerable.Range(0, 5), i =>
{
    Console.WriteLine($"執行任務 {i} - 線程 {Thread.CurrentThread.ManagedThreadId}");
    Thread.Sleep(1000);
});

6️⃣ TPL Dataflow

var block = new ActionBlock<int>(async i =>
{
    Console.WriteLine($"處理 {i}");
    await Task.Delay(500);
}, new ExecutionDataflowBlockOptions
{
    MaxDegreeOfParallelism = 3
});

foreach (var i in Enumerable.Range(0, 10))
{
    block.Post(i);
}

block.Complete();
await block.Completion;

📦 需安裝: System.Threading.Tasks.Dataflow

7️⃣ async/await Coroutine

async Task<string> DownloadAsync(string url)
{
    using var client = new HttpClient();
    var result = await client.GetStringAsync(url);
    return result;
}

var html = await DownloadAsync("https://example.com");
Console.WriteLine(html);

🧠 Thread vs Coroutine

類型說明
Thread作業系統層級,適合同步或 CPU 密集任務
Coroutine由 .NET 控制流程(Task + await),讓出執行緒等 IO

💡 小結

  • Taskasync/await 是現代開發主力
  • SemaphoreSlim 控制併發數
  • ⚠️ BackgroundWorker 僅建議用於舊 UI 專案