---
# System prepended metadata

title: X-Sendfile (Apache) 與 X-Accel-Redirect (NGINX) 的差異

---

拆解 **X-Sendfile (Apache)** 與 **X-Accel-Redirect (NGINX)** 的差異、作用，以及如何在 Laravel 中應用。

---

## 📌 1. 作用

這兩個 header 的用途一樣：**把檔案傳送的工作交給 Web 伺服器本身來處理，而不是由 PHP (Laravel) 讀取後輸出。**

### 🔹 一般情況（沒有用 X-Sendfile / X-Accel-Redirect）

Laravel -> `Storage::get()` 讀取檔案內容 -> PHP 輸出 -> Apache/Nginx 傳給使用者。
❌ 問題：

* PHP 會佔用大量記憶體 (大檔案很危險)。
* PHP 會拖慢回應時間。

---

### 🔹 使用 X-Sendfile / X-Accel-Redirect

Laravel 只回應「檔案在哪裡」，Web 伺服器去讀取並直接送出檔案。
✅ 好處：

* 節省 PHP 記憶體、CPU。
* 利用 Web 伺服器的高效能檔案處理。
* 適合下載大檔案或影音串流。

---

## 📌 2. 差異

* **Apache → X-Sendfile**

  * 需要安裝 `mod_xsendfile` 模組。
  * PHP 設定 response header:

    ```http
    X-Sendfile: /absolute/path/to/file.zip
    ```
  * Apache 會攔截並傳送該檔案內容。

* **NGINX → X-Accel-Redirect**

  * 內建支援，需設定一個內部 `location` 區塊。
  * PHP 設定 response header:

    ```http
    X-Accel-Redirect: /protected/file.zip
    ```
  * NGINX 會將 `/protected/` 映射到實際檔案系統路徑。

---

## 📌 3. 在 Laravel 的應用

Laravel 沒有直接內建，但可以透過 **自訂 Response**。

### 🔹 Apache (X-Sendfile)

在 `app/Http/Controllers/DownloadController.php`:

```php
public function download($filename)
{
    $path = storage_path('app/private/' . $filename);

    if (!file_exists($path)) {
        abort(404);
    }

    return response()
        ->noContent()
        ->header('X-Sendfile', $path)
        ->header('Content-Type', mime_content_type($path))
        ->header('Content-Disposition', 'attachment; filename="' . basename($path) . '"');
}
```

Apache `httpd.conf` 或 vhost：

```apache
XSendFile On
XSendFilePath /var/www/storage/app/private
```

---

### 🔹 NGINX (X-Accel-Redirect)

`app/Http/Controllers/DownloadController.php`:

```php
public function download($filename)
{
    $path = '/protected/' . $filename; // NGINX location 會處理

    return response()
        ->noContent()
        ->header('X-Accel-Redirect', $path)
        ->header('Content-Type', mime_content_type(storage_path('app/private/' . $filename)))
        ->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
}
```

Nginx 設定 (`nginx.conf` 或 site conf)：

```nginx
location /protected/ {
    internal;
    alias /var/www/storage/app/private/;
}
```

這樣 `/protected/file.zip` 只有 Nginx 可讀，外部無法直接訪問，必須經過 Laravel 控制器授權後再回應。

---

## 📌 4. 適用場景

* 大檔案下載（影片、zip、pdf）。
* 使用者授權後才允許下載的檔案。
* 減少 PHP 負擔（避免 memory limit）。

---

👉 總結：

* **X-Sendfile (Apache)** 與 **X-Accel-Redirect (NGINX)** 都是 **「PHP 不傳檔案，讓 Web Server 幫你傳」**。
* Laravel 可以透過回應 header 控制，並配合伺服器設定，達到 **安全且高效的大檔案下載**。
