You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过请求体传值发送POST请求?含Play框架相关疑问

问题解答

1. 路由中_ids的下划线含义

Play框架路由里的下划线_就是普通的URL路径字符,没有特殊语法作用。它只是用来做语义化标识,说明这个接口是通过ID列表导出数据,你完全可以换成/games/export/ids这类名称,框架只会把整个/games/export/_ids当作匹配的URL路径,不会对下划线做额外解析。

2. Form表单向请求体传值的方法

你的Action用parse.tolerantText解析纯文本请求体,但默认HTML表单提交的是application/x-www-form-urlencoded格式,两者不兼容,有两种解决思路:

方法一:适配表单格式修改Action解析器

把Action的解析器改成parse.formUrlEncoded,从表单参数中提取ID列表:

def exportByIds = Action.async(parse.formUrlEncoded) { req =>
  val ids = req.body.get("ids")
    .flatMap(_.headOption)
    .map(_.split(','))
    .getOrElse(Array.empty[String])
  download(ids)
}

对应的表单需要添加隐藏输入框来传递ID列表:

form(
  noFollow,
  cls := "button",
  action := s"${routes.Game.exportByIds}",
  method := "POST"
) {
  input(
    `type` := "hidden",
    name := "ids",
    value := "1,2,3" // 替换为实际的ID列表字符串
  )
  button(`type` := "submit", "导出")
}

方法二:通过JS让表单提交纯文本

如果坚持用parse.tolerantText,需要用JavaScript拦截表单提交,手动构造纯文本请求体:

form(
  noFollow,
  cls := "button",
  action := s"${routes.Game.exportByIds}",
  method := "POST",
  onsubmit := "handleSubmit(event)"
) {
  input(
    `type` := "hidden",
    id := "idsInput",
    value := "1,2,3"
  )
  button(`type` := "submit", "导出")
}

配套的JS代码:

function handleSubmit(event) {
  event.preventDefault();
  const form = event.target;
  const ids = document.getElementById('idsInput').value;
  fetch(form.action, {
    method: 'POST',
    body: ids,
    headers: {
      'Content-Type': 'text/plain'
    }
  }).then(response => {
    if (response.ok) {
      response.blob().then(blob => {
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'export.csv'; // 替换为你的导出文件名
        a.click();
        URL.revokeObjectURL(url);
      });
    }
  });
}

3. WS发送POST请求的类型不匹配问题

大概率是请求体类型和parse.tolerantText解析器不兼容,正确的WS发送纯文本请求写法如下:

import play.api.libs.ws._

ws.url(routes.Game.exportByIds.url)
  .withHttpHeaders("Content-Type" -> "text/plain")
  .post("1,2,3") // 直接传递ID列表字符串,与Action解析器对应
  .map { response =>
    // 处理响应逻辑
  }

如果之前传的是JSON或表单格式参数,就会和纯文本解析器冲突,导致类型错误,确保请求体是纯文本字符串且设置正确的Content-Type头。


内容的提问来源于stack exchange,提问作者Erdogan Seref

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:45:08