---
title: "ボディを書き換える"
language: "ja"
documentation_version: "3.x"
channel: "development"
release_context: null
source_revision: "10297d1e28653321d6996609fc53718d3b7c8278"
working_tree_clean: true
source_path: "docs/ja/guides/body-filter.md"
source_sha256: "7bd6a0546ccbdd1f0d7b8cd3271012b6d62b7d4bbb01b965bb74ff60a48704a3"
source_at_revision: true
source_url: "https://github.com/matsumotory/ngx_mruby/blob/10297d1e28653321d6996609fc53718d3b7c8278/docs/ja/guides/body-filter.md"
html_url: "https://ngx.mruby.org/ja/guides/body-filter/"
markdown_url: "https://ngx.mruby.org/markdown/ja/guides/body-filter.md"
last_updated: "2026-10-29"
---

# ボディを書き換える

ボディフィルタは、nginxがレスポンスを送る間に動きます。レスポンスを作ったのがどのハンドラでも、upstreamでも同じです。[`mruby_output_body_filter`](/ja/reference/directives/#mruby_output_body_filter-mruby_output_body_filter_code-mruby_output_header_filter-and-mruby_output_header_filter_code)を使うと、Rubyのスクリプトは`Nginx::Filter#body`でボディを読み、`Nginx::Filter#body=`でボディを置き換えます。ヘッダフィルタの`mruby_output_header_filter`はその前に動き、レスポンスのヘッダを変えられます。

## サンプル

このlocationは、ディスクにあるテキストファイルを送ります。ヘッダフィルタは`Content-Type`を`text/html`にし、ボディフィルタは`&`、`<`、`>`をエスケープして、テキストをHTMLのページで包みます。

```nginx title="test/conf/conf.d/76-guide-body-filter.conf"
server {
    listen 18167;

    # A text file from disk, sent as an HTML page.
    location = /notes {
        alias html/guide_notes.txt;
        mruby_output_header_filter_code 'Nginx::Request.new.content_type = "text/html"';
        mruby_output_body_filter build/nginx/html/guide_body_filter.rb;
    }
}
```

```ruby title="test/html/guide_body_filter.rb"
f = Nginx::Filter.new
text = f.body.gsub("&", "&amp;").gsub("<", "&lt;").gsub(">", "&gt;")
f.body = "<!doctype html>\n<title>notes</title>\n<pre>\n#{text}</pre>\n"
```

```http title="test/html/guide_body_filter.request：ケースが送るリクエスト"
GET /notes HTTP/1.1
Host: 127.0.0.1:18167
Connection: close
```

```http title="test/html/guide_body_filter.response：ケースが比べるレスポンス"
HTTP/1.1 200 OK
Content-Type: text/html

<!doctype html>
<title>notes</title>
<pre>
Notes from disk.
The filter escapes &lt;b&gt; and &amp;.
</pre>
```

<p class="caption sample-caption">CIが動くたびに、ケースの<code>test/t/cases/guides.rb</code>がこのリクエストを送ります。ケースは、ステータス行、ここに載せたヘッダ、ボディ全体を比べます。<span class="nowrap">5個</span>のファイルを最後に変えたのは、<span class="nowrap">2026-10-29</span>のコミット<span class="nowrap"><code>32219e53</code>です。</span></p>

## 気をつけること

- ボディフィルタは、ディスクのファイルのような長さの分かるレスポンスを、1つのバッファとして読みます。`Content-Length`の無いレスポンスは、フィルタが読まないまま、nginxが先へ渡します。詳しくは[Nginx::Filter](/ja/reference/ruby/#nginxfilter-class)にあります。
- ngx_mrubyは、新しいボディの長さを`Content-Length`に入れて送ります。
- [ユースケース](/ja/guides/use-cases/)の[MarkdownをHTMLに変換する出力フィルタ](/ja/guides/use-cases/#markdownをhtmlに変換する出力フィルタ)は、同じ場所で、gemのmruby-discountを使ってMarkdownを変換します。
