必须绕过dify默认json解析,改用原始二进制流+手动解包处理multipart表单:前端用enctype="multipart/form-data"提交,关闭「自动解析为json」开关,再通过代码节点调用email模块或模板转换+base64解码解析字段。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

要在Dify工作流中正确解析用户通过Web端提交的含文件、多级嵌套字段、重复name属性的Multipart表单数据,必须绕过默认的JSON自动解析机制,改用原始二进制流+手动解包方式处理,否则会丢失文件内容或解析出空对象。
确认表单提交方式与Dify接收机制
前端必须使用 <form enctype="multipart/form-data"></form> 提交,且不能依赖 data-format="json" 属性——该属性仅适用于纯文本表单,对 multipart 请求会直接忽略并返回空 payload。
进入工作流编辑页→点击「开始」节点→在右侧「输入字段」区域关闭「自动解析为JSON」开关(若存在),【此开关默认开启,不关闭会导致整个 multipart body 被丢弃】。
此时 Dify 将原始 HTTP 请求体(含 boundary 分隔符)作为字符串传入,后续需自行解析。
方法一:用代码节点调用内置 multipart 解析器
添加「代码执行」节点→语言选 Python→在代码区粘贴以下内容:
```python
import email
from email.policy import default
from io import BytesIO
def main(input_data):
# input_data 是原始 bytes 类型请求体
if not isinstance(input_data, bytes):
input_data = input_data.encode('utf-8')
msg = email.message_from_bytes(input_data, policy=default)
result = {}
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
name = part.get_param('name', header='Content-Disposition')
if not name:
continue
content = part.get_payload(decode=True)
if part.get_content_maintype() == 'text':
result[name] = content.decode('utf-8').strip()
else:
result[f"{name}_binary"] = content # 保留原始二进制
return result
```
注意:此方法依赖 Dify 沙箱内置的 email 模块,无需额外安装依赖,但要求 input_data 确实为完整 multipart 字节流——若上游节点做过字符串截断或编码转换,将无法解析。
方法二:用模板转换节点预处理为标准 JSON
第一步:在「开始」节点后立即接一个「模板转换」节点。
第二步:模板内容填写为:
<script type="application/json">{{input}}</script>
第三步:勾选「启用 HTML 渲染」,并设置输出格式为「纯文本」——这会强制 Dify 将原始 multipart 请求体原样包裹进 script 标签,避免被自动转义或截断。
第四步:将该节点输出连接至「代码执行」节点,此时 input_data 已是完整原始字节的 base64 编码字符串,需先解码再解析:
```python
import base64
import email
from email.policy import default
from io import BytesIO
def main(input_data):
raw_bytes = base64.b64decode(input_data)
msg = email.message_from_bytes(raw_bytes, policy=default)
# 后续解析逻辑同方法一
```
【关键点:不能直接对 base64 字符串调用 email.message_from_string,必须先 decode 成 bytes】
提取特定字段并传递给下游节点
完成解析后,在代码节点的「输出」配置中显式声明需透传的变量:
{"user_name": "{{parsed_data.username}}", "avatar": "{{parsed_data.avatar_binary}}", "tags": "{{parsed_data.tags}}"}
其中 parsed_data 是上一步代码节点返回的字典键名;【若未在此处声明,下游所有节点均无法访问该变量】。
后续 LLM 或 API 节点中引用时,直接使用 {{node_code_1.user_name}} 即可,无需加 form. 前缀——因为该数据已脱离表单输入层,属于代码节点的自定义输出。










