Elm中GET请求Body被忽略?对接要求带Body的GET API求助
Elm中GET请求携带Body的问题处理
问题确认
在Elm中使用Http.request发起GET请求时,手动设置的Body会被自动忽略,这是Elm HTTP库的既定行为。
测试代码如下(GET请求无Body):
init : () -> ( Model, Cmd Msg ) init _ = ( Loading , Http.request { method = "GET" , headers = [] , url = "http://127.0.0.1" , body = Http.stringBody "text/plain" "Hello World!" , expect = Http.expectWhatever Sent , timeout = Nothing , tracker = Nothing } )
通过浏览器开发者工具可观察到,该请求没有携带任何Body。
而将请求方法改为POST后,Body可正常携带:
init : () -> ( Model, Cmd Msg ) init _ = ( Loading , Http.request { method = "POST" {- 改为POST -} , headers = [] , url = "http://127.0.0.1" , body = Http.stringBody "text/plain" "Hello World!" , expect = Http.expectWhatever Sent , timeout = Nothing , tracker = Nothing } )
此时请求Body包含"Hello World!"。
解决方案
若需要对接要求GET请求携带application/json格式Body的API,可尝试以下两种方案:
- 调整接口规范:建议与API提供者沟通,改用POST请求传递Body数据。因为HTTP规范中并不推荐GET请求携带Body,多数客户端、服务器及中间件(如代理)都会忽略GET请求的Body,兼容性很差。
- 使用Elm Port调用原生JS:通过Elm的Port功能,让JavaScript发起带Body的GET请求,再将结果传回Elm。示例思路如下:
- 在Elm中定义Port:
port sendGetWithBody : { url : String, body : String } -> Cmd msg port getWithBodyResponse : (Result String String -> msg) -> Sub msg - 在JavaScript中实现请求逻辑:
app.ports.sendGetWithBody.subscribe(async ({ url, body }) => { try { const response = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json' }, body: body }); const data = await response.text(); app.ports.getWithBodyResponse.send({ ok: true, value: data }); } catch (err) { app.ports.getWithBodyResponse.send({ ok: false, error: err.message }); } });
- 在Elm中定义Port:
关于emptyBody文档的歧义
Elm文档中emptyBody的描述:
emptyBody : Body
Create an empty body for your Request. This is useful for GET requests
and POST requests where you are not sending any data.
该描述确实存在歧义,结合Elm的实际行为,正确解读应为:适用于所有GET请求(因为Elm强制GET请求使用空Body),以及不需要发送数据的POST请求,即你提到的第一种解读。
内容的提问来源于stack exchange,提问作者uben
相关产品推荐
相关产品推荐

