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

Phoenix框架如何创建基础表单与POST响应并解决CSRF问题?

解决Phoenix中POST表单的CSRF验证问题

我来帮你解决这个问题,你遇到的CSRF相关错误主要有两个关键点需要修正,结合你的现有代码,我给你一步步的解决方案:

1. 修复表单中的CSRF Token字段

你之前的代码里有两个小问题:

  • Phoenix默认期望的CSRF参数名是_csrf_token(下划线开头),而不是csrf_token
  • 模板中获取CSRF Token的正确方式是使用@csrf_token变量(由Phoenix的browser管道自动注入),而不是csrf_token(@conn)函数

修改你的表单代码为:

<form action="/create" method="post">
  <!-- 修正后的CSRF Token字段 -->
  <input type="hidden" name="_csrf_token" value="<%= @csrf_token %>">
  <input type="text" name="todo">
  <input type="submit">
</form>

2. 更新TodoController处理POST请求

你当前的TodoController.new只是渲染首页,没有实际处理POST参数。我们可以修改它来接收表单数据,做简单处理后重定向(这是POST请求的最佳实践,避免刷新页面重复提交):

defmodule ProjWeb.TodoController do
  use ProjWeb, :controller

  def new(conn, %{"todo" => todo_content}) do
    # 这里可以添加保存Todo到数据库的逻辑,比如:
    # Proj.Todo.create_todo(%{content: todo_content})
    
    # 临时打印到控制台验证是否收到数据
    IO.puts("收到新的Todo内容:#{todo_content}")

    # 添加提示信息并重定向到首页
    conn
    |> put_flash(:info, "Todo创建成功!")
    |> redirect(to: "/")
  end
end

3. 确认Browser管道配置(无需修改,但需要了解)

你的路由已经正确使用了pipe_through :browser,这个管道默认包含了Plug.Session和Plug.CSRFProtection插件,它们负责生成和验证CSRF Token,这是POST请求能正常工作的前提,所以这部分不用改动。

现在启动你的Phoenix应用,访问首页提交表单,应该就能正常处理POST请求了,不会再出现CSRF相关的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:41:20