【问题标题】:`Page not found (404)` in POST endpoint with JSON data带有 JSON 数据的 POST 端点中的“找不到页面 (404)”
【发布时间】:2019-06-22 14:58:36
【问题描述】:

我正在尝试使用POST 端点,它接受来自HTML 表单的JSON 数据,但结果只能得到404 - Page not found,除非我添加另一个没有负载的端点。

所以我可以从模板创建一个演示项目并进行一些小改动来测试这个问题:

cd /tmp
dotnet new websharper-web --name Demo --language F#
cd Demo
dotnet run   ## Ok!

编辑main.html 以添加表单:

<div class="container">
    ...
</div>
<form method="post" action="/demo" enctype="application/x-www-form-urlencoded">
    <label>Name</label>
    <input type="text" name="name" />
    <button type="submit">Post</button> 
</form>
<footer class="footer">
...
</footer>

Site.fs添加处理表单请求的代码:

type Data = { name: string }

type EndPoint =
    | [<EndPoint "GET /">] Home
    | ...
    | [<EndPoint "POST /demo"; Json "data">] Demo of data: Data
    | [<EndPoint "POST /demo">] DemoFallback

[<Website>]
    let Main =
        Application.MultiPage (fun ctx endpoint ->
            match endpoint with
            | ...
            | EndPoint.Demo data ->
                printfn "Data: %A" data
                Content.Text "Ok demo with post data"
            | EndPoint.DemoFallback ->
                Content.Text "I don't expect this route"
        )

再次运行项目:

dotnet run

我从浏览器得到I don't expect this route,但来自curl

curl -i -H "Content-Type: application/json" \
  -XPOST "http://localhost:5000/demo" \
  -d '{ "name": "me" }'

或者用不同的content-type:

curl -i -H "Content-Type: application/x-www-form-urlencoded" \
  -XPOST "http://localhost:5000/demo" \
  -d '{ "name": "me" }'

两者都有:

HTTP/1.1 200 OK
Date: Tue, 29 Jan 2019 12:57:19 GMT
Server: Kestrel
Transfer-Encoding: chunked

Ok demo with post data

我在这里错过了什么?

【问题讨论】:

  • @AMieres:不完全是,因为如果我删除DemoFallback 路径,浏览器会在提交表单后返回(404) Page not found
  • 你是对的,根据文档,它会按照声明的顺序尝试选项并使用第一个匹配的选项。这意味着浏览器发送的 JSON 格式不是 { "name" : "..."}
  • @AMieres:表单和类型已经有一个字段:(&lt;input type="text" name="name" /&gt;) 和type Data = { name: string }
  • 根据这篇文章:stackoverflow.com/questions/22195065/… 除非您以这种方式序列化,否则表单不会以 Json 格式发送。
  • @AMieres:您最后的评论是正确的。它使用文档中的[&lt;FormData("arg1", "arg2", ...)&gt;],而不是[&lt;Json "data"&gt;]。将其添加到答案中,以便我批准。

标签: forms post f# websharper


【解决方案1】:

HTML 表单不会以 Json 格式发送信息,而是使用 url 编码,这类似于 url 中的查询参数,只是它们进入请求的正文而不是 URL,例如,如果你有2 个字段用户和密码:

User=John&Password=123456

为了从表单接收数据,您需要使用[&lt; FormData &gt;] 属性:

type Data = { [< FormData >] name: string }

并在此处指明端点:

 | [< EndPoint "POST /demo" >]  Demo of data: Data

【讨论】:

  • 我对那些form参数感到困惑,所以非常感谢你帮助我理解和解决它。
  • 没问题,这也有助于我理解。
猜你喜欢
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 2021-10-27
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 2022-01-11
相关资源
最近更新 更多