response_type
概述
response_type 标签用于设置模板的响应类型,告诉控制器应该以什么格式返回响应内容。当需要返回非 HTML 格式的响应(如 Turbo Stream、JSON、XML)时,通常需要配合 {% layout none %} 使用。语法
{% response_type "类型" %}
支持的响应类型
html- HTML 格式(默认值)turbo_stream- Turbo Stream 格式,用于 Hotwire Turbo 的流式更新json- JSON 格式,用于 API 接口xml- XML 格式
使用示例
1. 返回 Turbo Stream 格式
Turbo Stream 用于实现无刷新的页面局部更新,常用于表单提交、动态内容更新等场景。
{% response_type "turbo_stream" %}
{% layout none %}
<turbo-stream action="replace" target="content">
<template>
<div id="content">更新后的内容</div>
</template>
</turbo-stream>
Turbo Stream 操作类型:
append- 在目标元素内部末尾追加内容prepend- 在目标元素内部开头插入内容replace- 替换目标元素的整个内容update- 更新目标元素的 innerHTMLremove- 移除目标元素before- 在目标元素之前插入内容after- 在目标元素之后插入内容
多操作示例:
{% response_type "turbo_stream" %}
{% layout none %}
{%# 移除旧元素 %}
<turbo-stream action="remove" target="old-element"></turbo-stream>
{%# 更新内容区域 %}
<turbo-stream action="replace" target="content-area">
<template>
<div id="content-area">
{% render 'updated_content', data: data %}
</div>
</template>
</turbo-stream>
{%# 追加新元素 %}
<turbo-stream action="append" target="list-container">
<template>
{% render 'list_item', item: new_item %}
</template>
</turbo-stream>
2. 返回 JSON 格式
用于创建 API 接口端点,返回结构化数据。
{% response_type "json" %}
{% layout none %}
{
"status": "success",
"message": "操作成功",
"data": {
"id": 123,
"name": "示例"
}
}
动态 JSON 示例:
{% response_type "json" %}
{% layout none %}
{
"articles": [
{% for article in articles %}
{
"id": {{ article.id }},
"title": {{ article.title | json }},
"created_at": {{ article.created_at | date: "%Y-%m-%d" | json }}
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]
}
3. 返回 XML 格式
用于返回 XML 格式的数据。
{% response_type "xml" %}
{% layout none %}
<?xml version="1.0" encoding="UTF-8"?>
<response>
<status>success</status>
<message>数据已更新</message>
<data>
<item id="1">内容1</item>
<item id="2">内容2</item>
</data>
</response>
4. 使用默认 HTML 格式
如果不设置
response_type,或者设置为 html,模板会以 HTML 格式返回。{% response_type "html" %}
<!-- 或者不设置 response_type -->
<h1>页面标题</h1>
<p>页面内容</p>
实际应用场景
场景 1:Turbo Stream 表单提交
表单提交后,使用 Turbo Stream 更新页面内容,显示验证错误或成功消息。
{% response_type "turbo_stream" %}
{% layout none %}
{%# 替换表单,显示验证错误 %}
<turbo-stream action="replace" target="comment-form">
<template>
{% render 'comment_form', comment: comment, errors: errors %}
</template>
</turbo-stream>
{%# 如果成功,追加新评论 %}
{% if comment.persisted? %}
<turbo-stream action="append" target="comments-list">
<template>
{% render 'comment', comment: comment %}
</template>
</turbo-stream>
{% endif %}
场景 2:API JSON 响应
在静态模板中创建 API 接口端点。
{% response_type "json" %}
{% layout none %}
{
"articles": [
{% for article in articles %}
{
"id": {{ article.id }},
"title": {{ article.title | json }},
"excerpt": {{ article.excerpt | json }},
"created_at": {{ article.created_at | date: "%Y-%m-%d" | json }}
}{% unless forloop.last %},{% endunless %}
{% endfor %}
],
"total": {{ articles.size }}
}
场景 3:错误响应
结合
response_status 返回错误信息。{% response_status 422 %}
{% response_type "json" %}
{% layout none %}
{
"status": "error",
"message": "验证失败",
"errors": {
"email": ["邮箱格式不正确"],
"password": ["密码长度至少8位"]
}
}
注意事项
- 类型验证:只接受
html、turbo_stream、json、xml四个值,其他值会被忽略,使用默认的 HTML 格式 - 必须配合 layout none:当使用非 HTML 格式时,通常需要配合
{% layout none %}禁用布局,避免布局的 HTML 结构(如<html>、<head>、<body>等标签)污染响应内容 - 优先级:布局(layout)中设置的
response_type会覆盖模板中的设置,因此建议在模板中设置响应类型,而不是在布局中 - 标签顺序:将
response_type标签放在模板的最前面,确保在渲染过程中正确设置响应类型 - 内容格式:确保响应内容符合指定的格式要求(如有效的 JSON、XML 或 Turbo Stream),否则可能导致解析错误
常见错误
错误 1:忘记禁用布局
{%# ❌ 错误示例 %}
{% response_type "json" %}
<!-- 没有设置 layout none -->
{
"status": "success"
}
问题:响应会被布局的 HTML 结构包装,导致 JSON 解析失败。
解决:
{%# ✅ 正确示例 %}
{% response_type "json" %}
{% layout none %}
{
"status": "success"
}
错误 2:响应类型拼写错误
{%# ❌ 错误示例 %}
{% response_type "turbo-stream" %} <!-- 应该是 turbo_stream -->
问题:类型值不匹配,会被忽略,使用默认的 HTML 格式。
解决:
{%# ✅ 正确示例 %}
{% response_type "turbo_stream" %}
错误 3:在布局中设置响应类型
{%# ❌ 不推荐的做法 %}
{%# 在模板中 %}
{% response_type "json" %}
{% layout "custom" %}
<!-- 在 layout/custom.liquid 中又设置了 -->
{% response_type "html" %}
问题:布局中的设置会覆盖模板中的设置,可能导致意外的响应格式。
建议:响应类型应该在模板中设置,而不是在布局中。
最佳实践
- 始终配合 layout none:当使用非 HTML 响应类型时,始终配合
{% layout none %}禁用布局 - 标签顺序:将
response_type和layout标签放在模板的最前面 - 类型验证:确保响应类型值拼写正确,使用下划线而不是连字符(
turbo_stream而不是turbo-stream) - 内容格式:确保响应内容符合指定的格式要求(如有效的 JSON、XML 或 Turbo Stream)
- 测试验证:在浏览器开发者工具中检查响应的 Content-Type 和内容格式,确保符合预期
- 错误处理:对于 API 响应,结合
response_status返回适当的状态码
总结
response_type 标签是控制模板响应格式的关键标签,支持 HTML、Turbo Stream、JSON、XML 四种格式。当使用非 HTML 格式时,必须配合 {% layout none %} 禁用布局,以确保响应内容的格式正确。正确使用此标签可以实现丰富的交互效果,如无刷新页面更新、API 接口、流式响应等。