【问题标题】:SyntaxError: Unexpected token e in JSON at position 1 || 400 Bad RequestSyntaxError:位置 1 处 JSON 中的意外标记 e || 400 错误请求
【发布时间】:2019-10-31 14:54:46
【问题描述】:

我正在尝试在我的 Vue 应用程序中提交表单数据。我有一个快速的后端 API。我试图发布到的端点在邮递员上完美运行。我不断收到“SyntaxError: Unexpected token g in JSON at position 0”或“400: Bad Request”

我尝试使用 JSON.parse(this.description)。我没有解析 this.description 就试过了。

在我的 axios 配置文件中,我尝试在我的 axios 响应拦截器中将响应标头更改为“application/json”。我也试过没有这样做。

这是表格

<v-dialog v-model="dialog" persistent max-width="600px">
      <template v-slot:activator="{ on }">
        <v-tooltip top>
          <v-btn small fab color="white" dark v-on="on" slot="activator">
            <v-icon color="primary">add</v-icon>
          </v-btn>
          <span>Add Task</span>
        </v-tooltip>
      </template>
      <v-card>
        <v-card-title>
          <span class="headline">Add Task</span>
        </v-card-title>
        <v-card-text>
          <v-form>
            <v-textarea v-model="description" label="Description"></v-textarea>
          </v-form>
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="blue darken-1" flat @click="dialog = false">Close</v-btn>
          <v-btn color="blue darken-1" flat @click="addTask">Save</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

这里是 axios 请求

methods: {
    ...mapActions(["fetchTasks"]),
    addTask() {
      console.log(this.description);
      axios
        .post("tasks", JSON.parse(this.description))
        .then(response => {
          dialog = "false";
        })
        .catch(err => console.log(err));
    }
  }

这是我的 axios 配置文件

"use strict";

import Vue from 'vue';
import axios from "axios";
import store from '../store';

// Full config:  https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = '';
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

let config = {
  baseURL: "http://localhost:3000/",
  timeout: 60 * 1000, // Timeout
  withCredentials: false, // Check cross-site Access-Control
};

const _axios = axios.create(config);

_axios.interceptors.request.use(
  function (config) {
    // Do something before request is sent
    let token = store.getters.getToken;

    if (token) {
      config.headers.common.Authorization = token;
    }

    return config;
  },
  function (error) {
    // Do something with request error
    return Promise.reject(error);
  }
);

// Add a response interceptor
_axios.interceptors.response.use(
  function (response) {
    // Do something with response data
    return response;
  },
  function (error) {
    // Do something with response error
    return Promise.reject(error);
  }
);

Plugin.install = function (Vue, options) {
  Vue.axios = _axios;
  window.axios = _axios;
  Object.defineProperties(Vue.prototype, {
    axios: {
      get() {
        return _axios;
      }
    },
    $axios: {
      get() {
        return _axios;
      }
    },
  });
};

Vue.use(Plugin)

export default Plugin;

这里是终点

router.post('/tasks', auth, async (req, res) => {
  const task = new Task({
    ...req.body,
    owner: req.user._id
  });

  try {
    await task.save();
    res.status(201).send(task);
  } catch (err) {
    res.status(400).send();
  }
});

这是谷歌浏览器网络标签下的标题数据

【问题讨论】:

  • 您的后端在请求正文中期望什么数据类型? JSON 或 application/x-www-form-urlencoded?
  • 期待 JSON。当我将内容类型更改为“application/json”时,我得到 400 Bad Request
  • 那你为什么要设置Axios发送application/x-www-form-urlencoded?我也不明白你对JSON.parse(this.description) 的使用。您是否希望您的用户在 Description 字段中输入有效的 JSON?您想在请求 JSON 中发送哪些字段? 究竟您的后端期望什么?
  • 啊。愚蠢的错误。后端期待一个对象。我没有将对象传递给发布请求。

标签: javascript node.js express vue.js axios


【解决方案1】:

如果您的 API 需要 JSON 请求(根据您的评论),您需要从以下位置更改您的 axios 配置:

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

到:

axios.defaults.headers.common['Content-Type'] = 'application/json';

如果您期望收到 JSON 作为回报,我也会推荐这些:

axios.defaults.headers.common['Accept'] = 'application/json';

并明确声明请求的带有标头:

axios.defaults.headers.common['X-Requested-With'] = 'XmlHttpRequest';

关于 axios post 调用,假设 this.description 是输入到输入字段或 textarea 中的文本,您将需要像这样构建 JSON 请求:

.post("tasks", {
  'description': this.description
})

或者设置一个数据对象,例如:

data () {
    return {
        formFields: {
            description: null
        }
    }
}

并将 v-model 更新为:

<v-textarea v-model="formFields.description" label="Description"></v-textarea>

然后你可以使用:

.post("tasks", this.formFields.description)

【讨论】:

  • 我仍然收到 400(错误请求)错误 POST localhost:3000/tasks 400(错误请求)AddTaskForm.vue?09b5:47 错误:请求在 createError 时失败,状态码为 400(createError.js ?2d83:16) 在 XMLHttpRequest.handleLoad (xhr.js?b50d:59) 处解决 (settle.js?467f:18)
  • 您需要发布您的 API 代码,因为错误源自 API 未正确处理响应。或者它需要你没有提供的东西。
  • 你也可以张贴回复标签的图片吗?
  • @Milad 很高兴我们能够解决您的问题。
  • @Phil 并没有太多可以开始的内容......可能不需要/不需要显式设置默认值,但肯定会在 Axios 插件(或任何与此相关的插件)中显式设置默认值不会伤害任何东西,并且可以提出一个论点,即它可以帮助稍后在代码库中跟随您的前端开发人员更好地理解 API 和 VueJS 代码库的预期行为。
猜你喜欢
  • 2016-08-29
  • 1970-01-01
  • 2020-10-07
  • 2021-03-21
  • 1970-01-01
  • 2021-08-28
  • 2019-01-04
相关资源
最近更新 更多