Ember.js POST请求从服务器返回400(Grape API),但成功存储到本地存储中

Bot*_*oke 3 ruby-on-rails ruby-grape ember.js ruby-on-rails-4 grape-api

我一直试图让一个简单的Ember.js应用程序现在发布到Grape API后端几个小时,但我似乎无法让它工作.我知道API有效,因为我可以通过Swagger文档向它发布新记录,并且它们是持久的.我知道API和Ember说得很好,因为我可以从服务器获取所有记录并在页面上与它们进行交互,我知道Ember在真空中工作正常,因为我的记录持久存储到本地存储.

但是,我似乎无法获得POST请求.它总是回来400.我已经正确配置了Rack-Cors,我在前端设置了ActiveModelAdapter,后端设置了ActiveModelSerializer.

这是模型

Contact = DS.Model.extend {
  firstName: DS.attr('string'),
  lastName:  DS.attr('string'),
  email:     DS.attr('string'),
  title:     DS.attr('string'),
  createdAt: DS.attr('date'),
  updatedAt: DS.attr('date')
}
Run Code Online (Sandbox Code Playgroud)

和控制器

ContactsNewController = Ember.ObjectController.extend(
  actions:
    save: ->
      @get('model').save()
    cancel: ->
      true
)
Run Code Online (Sandbox Code Playgroud)

API的相关部分如下所示

desc 'Post a contact'
  params do
    requires :first_name, type: String, desc: 'First name of contact'
    requires :last_name , type: String, desc: 'Last name of the contact'
    requires :email     , type: String, desc: 'Email of the contact'
    requires :title     , type: String, desc: 'Title of the contact'
  end
  post do
    Contact.create!(
      first_name: params[:first_name],
      last_name:  params[:last_name],
      email:      params[:email],
      title:      params[:title]
    )
  end
Run Code Online (Sandbox Code Playgroud)

我正在使用的表格是......

<form {{action 'save' on='submit'}}>
  <h2>{{errorMessage}}</h2>

  <label>First Name</label>
  {{input value=firstName placeholder='First Name' type='text' autofocus=true}}

  <label>Last Name</label>
  {{input value=lastName placeholder='Last Name' type='text'}}

  <label>Email</label>
  {{input value=email placeholder='Email' type='text'}}

  <label>Job Title</label>
  {{input value=title placeholder='Job Title' type='text'}}

  <hr>

  <input type='submit' value='Save'>
</form>
Run Code Online (Sandbox Code Playgroud)

我得到的回应是......

{"error":"first_name is missing, last_name is missing, email is missing, title is missing"}
Run Code Online (Sandbox Code Playgroud)

任何接受者?对不起,我是新来的.有些事情没有受到约束,但我不知道为什么.


UPDATE

更多调查......

IMAGE:对API cURL的POST请求(通过Postman)工作正常..

但是,当我从Ember POST时,服务器响应仍然存在

{"error":"first_name is missing, last_name is missing, email is missing, title is missing"}
Run Code Online (Sandbox Code Playgroud)

IMAGE:来自Chrome开发工具的POST请求的输出如下所示

我还将控制器更改为...,它在上面的chrome dev工具日志中给出了输出.

`import Ember from 'ember'`

ContactsNewController = Ember.ObjectController.extend(
  actions:
    createContact: ->
      firstName = @get('firstName')
      lastName  = @get('lastName')
      email     = @get('email')
      title     = @get('title')

    newRecord = @store.createRecord('contact', {
                   firstName: firstName,
                   lastName:  lastName,
                   email:     email,
                   title:     title
                 })

    self = this

    transitionToContact = (contact) ->
      self.transitionToRoute('contacts.show', contact)

    newRecord.save().then(transitionToContact)
   )

`export default ContactsNewController`
Run Code Online (Sandbox Code Playgroud)

Mar*_*lon 5

我对Ember.js一无所知,但我一直在使用Grape构建API一段时间,所以我想我可以帮助你.查看您附加的图像,似乎Ember.js在Payload中创建了一个不正确的JSON,而您的Grape API并不期望以这种方式形成JSON格式.正如你在第二张图片中看到的,它正在创建一个这样的JSON:

{ contact: {...} }
Run Code Online (Sandbox Code Playgroud)

但是,您的API期望像这样的JSON格式:

{ first_name: "" ... }
Run Code Online (Sandbox Code Playgroud)

现在,看看您是如何通过Chrome开发工具发送相同的请求...您正在使用"表单数据"选项来创建正文请求,这就是为什么在这种特定情况下它正在工作.尝试将其更改为"raw"并将不正确的JSON置于上方,您将获得使用Ember.Js时遇到的相同错误.

我没有具体的解决方案,因为我没有专业知识来帮助你使用Ember.Js ......但是你必须改变你的Amber.js应用程序中的某些东西,它会创建一个像这样的JSON请求:

{ first_name: "", last_name: "", email: "" }
Run Code Online (Sandbox Code Playgroud)

代替:

{ contact: { first_name: "" ... } }
Run Code Online (Sandbox Code Playgroud)

希望它能帮到你!

UPDATE

您问题的另一个解决方案是更改Grape API.在这种情况下,您必须在params块中创建一个块,如下所示(考虑到联系人字段现在存储在params [:contact] Hash中):

desc 'Post a contact'
params do
    group :contact, type: Hash do
        requires :first_name, type: String, desc: 'First name of contact'
        requires :last_name , type: String, desc: 'Last name of the contact'
        requires :email     , type: String, desc: 'Email of the contact'
        requires :title     , type: String, desc: 'Title of the contact'
    end
end
post do
    Contact.create!(
        first_name: params[:contact][:first_name],
        last_name:  params[:contact][:last_name],
        email:      params[:contact][:email],
        title:      params[:contact][:title]
    )
end
Run Code Online (Sandbox Code Playgroud)