如何使用Erlang HTTP方法发送MIME多部分消息及解决拼接问题
你当前的问题是没有正确构建multipart/related的请求体,仅传入了JSON数据,缺少二进制部分的拼接,且未为每个数据块指定对应Content-Type。要实现需求,需按照multipart/related的格式规范拼接两个数据部分,具体实现如下:
核心修改步骤
- 单独提取boundary变量,避免硬编码导致请求头与请求体的boundary不一致
- 为JSON和二进制数据分别构建带Content-Type的独立部分
- 用boundary分隔各部分,结尾添加闭合标记完成完整请求体的拼接
修改后的完整代码
-module(MIME_post). -export([send_post_request/0, get_modify_req/0]). send_post_request() -> % ... (现有代码) Url = "http://localhost:8666", JsonData = #{<<"some_val">> => <<"imsi-460886666660006">>}, JsonBody = jsx:encode(JsonData), % 单独定义boundary,确保请求头与请求体使用同一值 Boundary = "-21ba7406cff5fa6c192d6b78fe58e16c5fd0cde4111e10f11c2bf55b45a5", Headers = [{"Content-Type", "multipart/related;boundary=" ++ Boundary}], MimeBinary = <<"2e0a00d1">>, % 构建JSON部分:指定Content-Type为application/json JsonPart = io_lib:format("--~s\r\nContent-Type: application/json\r\n\r\n~s\r\n", [Boundary, JsonBody]), % 构建二进制部分:此处指定为application/octet-stream,可根据实际需求调整类型 BinaryPart = io_lib:format("--~s\r\nContent-Type: application/octet-stream\r\n\r\n~s\r\n", [Boundary, MimeBinary]), % 拼接完整请求体,结尾添加闭合boundary标记 FullBody = lists:flatten([JsonPart, BinaryPart, "--", Boundary, "--\r\n"]), Request = {Url, Headers, "multipart/related", FullBody}, case httpc:request(post, Request, [stream], []) of {ok, {{_, 201, _}, ResponseHeaders, ResponseBody}} -> io:format("HTTP Response Header:~p~n", [ResponseHeaders]), io:format("HTTP Response: ~s~n", [ResponseBody]), {ok, ResponseBody}; {error, Reason} -> io:format("HTTP Request failed with reason: ~p~n", [Reason]), {error, Reason} end.
关键细节说明
- boundary一致性:必须保证请求头中的boundary和请求体里分隔各部分的boundary完全一致,否则服务端无法正确解析多部分数据
- 数据块格式规范:每个数据块都以
--{boundary}开头,随后是该块的头部信息(如Content-Type),空行(\r\n\r\n)分隔头部与内容,最后换行 - 二进制数据处理:如果
<<"2e0a00d1">>是十六进制字符串形式的二进制数据,需先用binary:decode_hex/1转换为原始二进制后再拼接 - 响应头变量修正:原代码误打印请求头,现已改为打印响应头
ResponseHeaders,避免混淆
内容的提问来源于stack exchange,提问作者Kaushik .p
相关产品推荐
相关产品推荐

