【问题标题】:Rails API - Expecting json showing created object. Getting 302 status code with no objectRails API - 期望 json 显示创建的对象。获取没有对象的 302 状态码
【发布时间】:2015-07-30 17:50:55
【问题描述】:

我有 2 个应用程序。一个普通 Ruby 应用程序和一个 Rails 应用程序,用于侦听普通 Ruby 应用程序的 POSTS 并显示已发布的数据。

我正在尝试为我的 Rails 应用程序设计一个基本 API。我使用法拉第 POST 一些 JSON 到我的应用程序。这部分正在工作,因为我可以看到在POST 之后正在创建对象。

在我的resp 中,我期待看到与我刚刚创建的对象相关的内容。相反,我确实看到了status=302

我怎样才能得到一个显示success 的回复,也许一些带有创建对象的 json 会很好。真的,我只是想要一个指示 POST 正确运行。

--- 来自 plain Ruby 应用程序 的代码发布到我的 Rails 应用程序

conn = Faraday.new(:url => 'http://localhost:3000/api/v1/tests') do |faraday|
  faraday.request  :url_encoded             # form-encode POST params
  faraday.response :logger                  # log requests to STDOUT
  faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
end   

resp = conn.post do |req|
  req.headers['Content-Type'] = 'application/json'
  req.body = data.to_json
end  

当我检查resp 时,我得到了这个

[1] pry(#<Object>)> resp => #<Faraday::Response:0x007fb8c3a317d0 @env= #<struct Faraday::Env method=:post, body="<html><body>You are being <a href=\"http://localhost:3000/tests/2\">redirected</a>.</body></html>", url=#<URI::HTTP:0x007fb8c34176b0 URL:http://localhost:3000/api/v1/tests>, request= #<struct Faraday::RequestOptions params_encoder=nil, proxy=nil, bind=nil, timeout=nil, open_timeout=nil, boundary=nil, oauth=nil>, request_headers={"User-Agent"=>"Faraday v0.9.1", "Content-Type"=>"application/json"}, ssl= #<struct Faraday::SSLOptions verify=nil, ca_file=nil, ca_path=nil, verify_mode=nil, cert_store=nil, client_cert=nil, client_key=nil, certificate=nil, private_key=nil, verify_depth=nil, version=nil>, parallel_manager=nil, params=nil, response=nil, response_headers= {"x-frame-options"=>"SAMEORIGIN", "x-xss-protection"=>"1; mode=block", "x-content-type-options"=>"nosniff", "location"=>"http://localhost:3000/tests/2", "content-type"=>"text/html; charset=utf-8", "cache-control"=>"no-cache", "x-request-id"=>"62da5fdc-6f00-4f2a-9c93-c80f6e08c4f8", "x-runtime"=>"0.219049", "server"=>"WEBrick/1.3.1 (Ruby/2.2.0/2014-12-25)", "date"=>"Thu, 30 Jul 2015 16:54:07 GMT", "content-length"=>"95", "connection"=>"close", "set-cookie"=> "request_method=POST; path=/, _cimportal_session=QjdTN0lOaXBMSTZYT0hvOCsyOVozeW43VTRiSHZXTTBlakJFMmllTTNmdTYvbnd5QllWZnRnSDJhN2lHSDJxM3phSHZWU1VGcElSWEY0V0N3dXd6RHdzTW5leHFtY3hoNDNaTHRCZ2l3ODVaZTVIcXc0eDBnMHdKelhhN2lZeEdIYXNlWU9ZaThETkUvYnRTL293c0lKRGU1N3FrY2liN2t6anBCNlJMaXJFPS0tZmhIQmN0VXVvVEJ4VE5rQ3JLdWphZz09--965190ef9f588d95347f2ee25044eb79f3b5d289; path=/; HttpOnly"}, status=302>, @on_complete_callbacks=[]>

如您所见,底部有一个 status=302。如何在此处获取success 以及一些代表对象的 json?

这里是 Rails create 方法的主要部分

@test = Test.new(test_params)

respond_to do |format|
  if @test.save
    format.html { redirect_to @test, notice: 'Test was successfully created.' }
    format.json { render :show, status: :created, location: @test }
  else
    format.html { render :new }
    format.json { render json: @test.errors, status: :unprocessable_entity }
  end

我错过了什么? POST 正在运行,但我希望看到它成功的响应。

【问题讨论】:

    标签: ruby-on-rails ruby json rails-api


    【解决方案1】:

    你有一行说:

    format.json { render :show, status: :created, location: @test }
    

    这会导致您看到的 302。

    试试类似的东西

    format.json { render status: :created, json: @test }
    

    这应该返回一个 201 状态代码并以创建的新对象的 JSON 响应。

    【讨论】:

    • 请注意,它正在呈现“已创建”状态,这是一个 200 级 HTTP 响应。重定向响应在 300 范围内。我认为这不会解决问题,因为它不是导致重定向的原因。
    【解决方案2】:

    尝试在 URL 中添加“.json”,这样控制器就不会认为该请求是常规 HTML 请求。

    如果这样可以解决问题,那么您可以将其添加到所有 URL 或将控制器配置为 respond_to :json(并从控制器中删除 format.html 行)。

    我通常在应用程序控制器中执行此操作,因此所有控制器方法都会继承它:

    class ApplicationController < ActionController::Base
    
      respond_to :json
    
    end
    

    你也可以在你的路线中做一些事情来进一步锁定它,但我的记忆有点模糊:

    resources :users, defaults: { format: :json }
    

    编辑

    上面我建议删除format.html 行,但实际上你可以删除所有这些格式的东西,只让方法返回一些 JSON 而无需关心格式是什么:

    if @test.save
      # assuming there is a jBuilder view for this and that you have the
      # respond_to :json in the controller or application controller
      render :show, status: :created, location: @test
    else 
      render json: @test.errors, status: :unprocessable_entity
    

    【讨论】:

      【解决方案3】:

      我使用了这两个答案来提供帮助。主要是我将 .json 添加到 URL 的末尾,它几乎开始工作了。我也改成这个format.json { render status: :created, json: @test }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 2016-05-09
        • 1970-01-01
        相关资源
        最近更新 更多