Rails Rails 默认没有防止表单重复提交功能?

hmilym · 2015年05月14日 · 最后由 bastengao 回复于 2016年02月02日 · 4297 次阅读

偶然发现,好像 Rails 默认没有防止表单重复提交的功能。

  1. rails new repeat_test
  2. rails g scaffold user name:string age:integer
  3. add sleep 5 in create user action.
# POST /users
# POST /users.json
def create
  sleep 5
  @user = User.new(params[:user])

  respond_to do |format|
    if @user.save
      format.html { redirect_to @user, notice: 'User was successfully created.' }
      format.json { render json: @user, status: :created, location: @user }
    else
      format.html { render action: "new" }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end
  1. 连续多次重复点击 create user 按钮
  2. 发现新建了很多的相同的 user

讲过查找文档 guide,form 中只有 authenticity_token 用来防止 CSRF 攻击,也不是防止表单重复提交。请问 Rails 中没有类似于 java structs 这种功能吗?

一般是给 users 表的 username 或 emails 字段(取决于你的设计)加唯一索引。

structs 防止重复提交的原理是什么?

一般做法是点击提交按钮之后,把按钮 Disabled

  1. sql 加 index 索引
  2. model 文件加 validates uniqueness 验证
data: {disable_with: "提交中..."}

我记得坛子里有个非常好的方案是:用 etag 判断 post 的资源是否已经改变。

#6 楼 @est 用摘要算法。哈。

用 disable_with 是常规做法,大部分情况足够了,应该符合楼主的需求。 但是,这个防不了恶意重复提交,因为只是表现层的实现。

几种防止表单重复提交的方法:

  1. 禁掉提交按钮。
  2. 在 session 中存放一个特殊标志,看这里:http://blog.csdn.net/emerald0106/article/details/7673232
  3. 在数据库里添加约束
  4. Post/Redirect/Get模式
需要 登录 后方可回复, 如果你还没有账号请 注册新账号