基本 .ajax 发布到 rails 3.2.2 脚手架,生成“警告:无法验证 CSRF 令牌真实性”

Posted

技术标签:

【中文标题】基本 .ajax 发布到 rails 3.2.2 脚手架,生成“警告:无法验证 CSRF 令牌真实性”【英文标题】:Basic .ajax post to a rails 3.2.2 scaffold generating "WARNING: Can't verify CSRF token authenticity" 【发布时间】:2012-04-28 22:25:51 【问题描述】:

我正在尝试学习如何使用 $.ajax 通过 jquery 将一些数据发布到一个简单的 rails 脚手架项目。有一个标准的脚手架创建控制器 => 图片

class ImagesController < ApplicationController
  # GET /images
  # GET /images.json
  def index
    @images = Image.all

    respond_to do |format|
      format.html # index.html.erb
      format.json  render json: @images 
    end
  end

  # GET /images/1
  # GET /images/1.json 
  def show
    @image = Image.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json  render json: @image 
    end
  end

  # GET /images/new
  # GET /images/new.json
  def new
    @image = Image.new

    respond_to do |format|
      format.html # new.html.erb
      format.json  render json: @image 
    end
  end

  # GET /images/1/edit
  def edit
    @image = Image.find(params[:id])
  end

  # POST /images
  # POST /images.json
  def create
    @image = Image.new(params[:image])

    respond_to do |format|
      if @image.save
        format.html  redirect_to @image, notice: 'Image was successfully created.' 
        format.json  render json: @image, status: :created, location: @image 
      else
        format.html  render action: "new" 
        format.json  render json: @image.errors, status: :unprocessable_entity 
      end
    end
  end

  # PUT /images/1
  # PUT /images/1.json
  def update
    @image = Image.find(params[:id])

    respond_to do |format|
      if @image.update_attributes(params[:image])
        format.html  redirect_to @image, notice: 'Image was successfully updated.' 
        format.json  head :no_content 
      else
        format.html  render action: "edit" 
        format.json  render json: @image.errors, status: :unprocessable_entity 
      end
    end
  end

  # DELETE /images/1
  # DELETE /images/1.json
  def destroy
    @image = Image.find(params[:id])
    @image.destroy

    respond_to do |format|
      format.html  redirect_to images_url 
      format.json  head :no_content 
    end
  end
end

只有一条路线 => 资源:图像。数据库模式由一个字段 => t.string :name 组成。 我最初的测试 html 文件是:

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js">    </script>
</head>
<body>
    <script>
    $(document).ready(function()
        $.ajax(
            type: 'POST', url: "localhost:3000/images",
            data:  name: "johngalt" 
        );
    );
    </script>
</body>

webrick 的结果是:

Started POST "/images" for 127.0.0.1 at 2012-04-17 09:50:19 -0500
Processing by ImagesController#create as */*
  Parameters: "name"=>"johngalt"
WARNING: Can't verify CSRF token authenticity
   (0.1ms)  begin transaction
   SQL (63.5ms)  INSERT INTO "images" ("created_at", "name", "updated_at") VALUES (?, ?,  ?)  [["created_at", Tue, 17 Apr 2012 14:50:21 UTC +00:00], ["name", nil], ["updated_at",  Tue, 17 Apr 2012 14:50:21 UTC +00:00]]
   (2.0ms)  commit transaction
 Redirected to http://localhost:3000/images/7
 Completed 302 Found in 81ms (ActiveRecord: 65.6ms)

我不确定为什么名称不包含“johngalt”。这是否与“警告:无法验证 CSRF 令牌真实性”有关?

编辑 当我使用 curl 时:

curl -d "image[name]=johngalt"  localhost:3000/images.json

记录已创建,名称字段包含“johngalt”。从本质上讲,我试图找出 .ajax 相当于做我在 curl 中能够做的事情?

【问题讨论】:

【参考方案1】:

当您使用 Rails form_for 帮助程序创建表单时,CSRF 令牌会自动添加到您的帖子表单中,旨在保护用户免受 cross-site request forgery attacks 的侵害。因此,如果您尝试在 javascript 文件中发布,您将无法访问令牌。

如果您愿意,您可以为特定操作禁用 CSRF 令牌身份验证,只要您了解后果即可。

有几种方法可以做到这一点,这里列出:Turn off CSRF token in rails 3

编辑 查看您的 CURL 示例,您似乎在 ajax 发布错误的数据。您正在省略“图像”参数命名空间。试试:

<script>
$(document).ready(function()
    $.ajax(
        type: 'POST', url: "localhost:3000/images",
        data:  image:  name: "johngalt"  
    );
);
</script>

【讨论】:

是 CSRF 令牌问题,阻止值 => "johngalt" 在字段 => 名称中更新? 你的问题是你需要发布data: image : name: "johngalt" ,就像你在 curl 请求中所做的那样 允许上传字段谢谢。出现这个错误,XMLHttpRequest 无法加载localhost:3000/images.json。 Access-Control-Allow-Origin不允许Origin null,围绕跨域问题? 听起来像。尝试将其粘贴在您的控制器中,看看会发生什么:skip_before_filter :verify_authenticity_token 感谢您的回复,但这并没有解决问题。

以上是关于基本 .ajax 发布到 rails 3.2.2 脚手架,生成“警告:无法验证 CSRF 令牌真实性”的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4 中的 AJAX、HTML5 历史 API 和缓存

Rails 控制器方法在 Ajax 调用后不重新加载页面

无法在 Rails 5 中将 Json 数据获取到 Ajax

Rails 复选框 AJAX 调用,不想渲染任何东西

Rails AJAX 远程:true 与动态 id

如何将延迟的ajax数据获取到rails视图