Javascript 400从我的Vue应用程序到我的Rails API的POST请求存在错误请求问题

Javascript 400从我的Vue应用程序到我的Rails API的POST请求存在错误请求问题,javascript,ruby-on-rails,ruby,vue.js,vuejs2,Javascript,Ruby On Rails,Ruby,Vue.js,Vuejs2,我正在学习Rails和Vue,并创建了一个简单的Rails API和Vue应用程序,以了解如何从我的Vue应用程序获取并发布到我的Rails API。到目前为止,GET请求还可以,但由于发送POST请求的语法错误,我收到了400个错误请求。POST请求在使用失眠(类似于Postman的API测试应用程序)进行测试时起作用,但在使用Vue应用程序进行POST时,我得到400 这是我的Rails控制器: def create @todo = Todo.new(todo_params)

我正在学习Rails和Vue,并创建了一个简单的Rails API和Vue应用程序,以了解如何从我的Vue应用程序获取并发布到我的Rails API。到目前为止,GET请求还可以,但由于发送POST请求的语法错误,我收到了400个错误请求。POST请求在使用失眠(类似于Postman的API测试应用程序)进行测试时起作用,但在使用Vue应用程序进行POST时,我得到
400

这是我的Rails控制器:

def create
    @todo = Todo.new(todo_params)
    if @todo.save
        render :show, status: :created, location: @todo
    else
        render json: @todo.errors, status: :unprocessable_entity
    end
end

...

private

    def set_todo
        @todo = Todo.find(params[:id])
    end

    def todo_params
        params.require(:todo).permit(:title, :description, :finished)
    end
这是我的Vue应用程序,通过简单的文本输入发布到我的Rails:

<template>
<input type="text" v-model="postBody"/>
<button v-on:click="submit()">Submit</button> 
</template>

<script>
import axios from 'axios';
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      todos: [],
      errors: [],
      postBody: ''
    }
  },
methods: {
    submit() {axios.post(`http://localhost:3000/todos/`, { 
        headers: {
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: JSON.stringify(this.postBody) 
      })
      .then(response => response.data)
      .catch(e => {
        this.errors.push(e)
      })
    }
  }
}
</script>
然后,我从浏览器中得到以下错误:

{status: 400, error: "Bad Request",…}
error: "Bad Request"
exception: "#<ActionController::ParameterMissing: param is missing or the value is empty: todo>"
status: 400
traces: {Application Trace: [{id: 1, trace: "app/controllers/todos_controller.rb:51:in `todo_params'"},…],…}
Application Trace: [{id: 1, trace: "app/controllers/todos_controller.rb:51:in `todo_params'"},…]
0: {id: 1, trace: "app/controllers/todos_controller.rb:51:in `todo_params'"}
1: {id: 2, trace: "app/controllers/todos_controller.rb:24:in `create'"}
我知道这可能与我的Rails控制器中的强参数有关,所以当我删除所需的参数
.require(:todo)
时,帖子就完成了,但是JSON字段都是空的

  {
    "id": 6,
    "title": null,
    "description": null,
    "finished": null
  }
我还试图查看它是否与我的Vue应用程序中的表单数据如何发送到Rails端点有关,因此我尝试了
JSON.stringify
正文,但没有帮助


这是我试图解决这个问题的第三天,但没有成功。我做错了什么?非常感谢您的帮助!:)

首先,您在JSON负载的根目录上提交
标题
说明
等,但是Rails希望它们嵌套在
todo

其次,您正在提交axios请求的payload参数中的头-post的第一个参数是payload,第二个参数是configuration

第三,您不需要将数据转换为JSON字符串。axios应该为您解决这个问题

请尝试此axios请求:

axios.post(
  `http://localhost:3000/todos/`,
  { todo: this.postBody },
  { headers: { 'Content-Type': 'application/json; charset=UTF-8' }
)

在经历了来自Rails控制台的各种错误消息之后,我意识到这与Rails API或强参数无关,而是如何构造输入,使其不
POST
将格式错误的JSON发送到我的Rails端点。阅读npm axios文档有助于加载

因此,我在Vue应用程序中创建了一个表单,并将字段名与参数匹配,而不是单个文本输入字段:

<form @submit.prevent="onSubmit">
  <div class="input">
    <label for="title">Title</label>
    <input
       type="text"
       id="title"
       v-model="title">
  </div>
  <div class="input">
    <label for="name">Description</label>
    <input
      type="text"
      id="description"
      v-model="description">
  </div>
  <div class="input">
    <label for="finished">Finished?</label>
    <input
      type="text"
      id="finished"
      v-model="finished">
  </div>
  <div class="submit">
    <button type="submit">Submit</button>
  </div>
</form>

这就成功了!我现在可以发布到我的Rails API了。我的问题是,我仍然不明白它是如何工作的,为什么工作的,除了它真的工作了!因此,任何答案都是值得个人学习的(但对最初的问题并不重要)。

API测试应用程序添加缺失的信息,纠正格式错误的JSON,以帮助开发人员。当然,您正在构建的实际应用程序不会这样做。如果有帮助的话,我会尝试使用一些现成的代码或获取API,或者使用一些现成的API消费库,看看问题出在哪里。@Jay抱歉,我是Rails和Vue的新手,所以我要问noob问题:我应该如何用现成的代码和/或API消费库来解决这个问题?一些粗略的步骤会对我进一步研究非常有帮助!:)如果我是你,我会浏览Vue文档和教程网站,了解其他人是如何进行API调用的。我在node和.NET上工作,它们都有现成的库来完成这项工作。我不使用Vue,但React只使用JavaScript获取。所以,真的,你只需要花点时间看一下Vue官方文档。你试过params.permit(:todo)@SRDP了吗?是的,我试过了,它在发送帖子时起到了作用,但json字段都是空的谢谢@Tim Krins!我尝试了你的代码,并且发布了不同版本的json,得到了500个内部服务器错误。。。我迷路了<代码>命名错误(未定义的方法):app/controllers/todos\u controller.rb:51:in
todo\u params'app/controllers/todos\u controller.rb:24:in
create'Started POST”/todos/“for::1于2020-09-22 10:16:44+0800由TodosController处理创建为JSON参数:{“todo”=>“title\:“Sweets\,“description\”:\“购买cookies\”,\“finished\”:false“}在2ms内完成了500个内部服务器错误(ActiveRecord:0.0ms)`在我的示例中,我假设
这个。postBody
是一个包含todo所有值的对象。
axios.post(
  `http://localhost:3000/todos/`,
  { todo: this.postBody },
  { headers: { 'Content-Type': 'application/json; charset=UTF-8' }
)
<form @submit.prevent="onSubmit">
  <div class="input">
    <label for="title">Title</label>
    <input
       type="text"
       id="title"
       v-model="title">
  </div>
  <div class="input">
    <label for="name">Description</label>
    <input
      type="text"
      id="description"
      v-model="description">
  </div>
  <div class="input">
    <label for="finished">Finished?</label>
    <input
      type="text"
      id="finished"
      v-model="finished">
  </div>
  <div class="submit">
    <button type="submit">Submit</button>
  </div>
</form>
methods: {
    onSubmit() {
      const formData = {
      title: this.title,
      description: this.description,
      finished: this.finished      
      }
      axios({
        method: "POST",
        url: "http://localhost:3000/todos/",
        headers: {"Content-Type": "application/json"},
        data: formData
      })
      .then(response => { 
        console.log(response);
      })
      .catch(e => {
      this.errors.push(e)
      })
    },