【问题标题】:Getting invalid JSON on API call在 API 调用中获取无效的 JSON
【发布时间】:2018-08-30 21:25:58
【问题描述】:

我正在尝试使用 GoToMeeting 的 API 并发出 POST 请求来创建会议。目前,我只是在尝试对会议正文进行硬编码并发送标题,但我收到了无效的 JSON 错误,不知道为什么。这是该路线的代码:

app.post('/new-meeting', (req, res) => {

  const headers = {
    'Content-Type': 'application/json',
    Accept: 'application / json',
    Authorization: 'OAuth oauth_token=' + originalToken
  };

  console.log('-----------------------------------------------------------')
  console.log('Acess Token:');
  console.log('OAuth oauth_token=' + originalToken);
  console.log('-----------------------------------------------------------')

  const meetingBody = {
    subject: 'string',
    starttime: '2018-03-20T08:15:30-05:00',
    endtime: '2018-03-20T09:15:30-05:00',
    passwordrequired: true,
    conferencecallinfo: 'string',
    timezonekey: 'string',
    meetingtype: 'immediate'
  };

  return fetch('https://api.getgo.com/G2M/rest/meetings', {
    method: 'POST',
    body: meetingBody,
    headers: headers
  }).then(response => {

    console.log('response:');
    console.log(response);


    response
      .json()
      .then(json => {
        res.send(json);
        console.log(req.headers);
      })
      .catch(err => {
        console.log(err);
      });
  });
});

当我点击那个路由器时,我收到以下错误:

{
  "error": {
    "resource": "/rest/meetings",
    "message": "invalid json"
  }
}

任何建议将不胜感激!

【问题讨论】:

  • 在放入body选项之前尝试JSON.stringify()你的meetingBody对象,我不认为fetch会自动将对象解析为json
  • @PatrickEvans 对正文进行字符串化意味着需要更改标头,而且 api 很可能在正文中接受 json
  • @mast3rd3mon,不,它没有。标头只是告诉服务器会发生什么,并且由于 JSON 是文本并且对对象进行字符串化会产生文本,因此标头不需要更改
  • stringifying json 将其转换为文本,因此标题变为 text/plain
  • @mast3rd3mon — 不,它没有。 JSON.stringify 输出 JSON 文本。 JSON 文本不是 纯文本 文本。

标签: javascript json api express


【解决方案1】:

tl;博士

您正在向 fetch 传递一个由 JavaScript 对象表示的 body 的值。它通过(隐式)调用其.toString() 方法将其转换为字符串。这不会给你 JSON。然后,您调用的 API 会抱怨并告诉您它不是 JSON。

您需要使用以下方法将对象转换为 JSON:

body: JSON.stringify(meetingBody), 

测试用例

这说明了问题和解决方案。

服务器

这是一个非常原始且不完整的 GoToMeeting API 模拟。它只是回显请求正文。

const express = require("express");
var app = express();
var bodyParser = require('body-parser');

app.use(bodyParser.text({ type: "*/*" }));

app.post("/", (req, res) => {
    console.log(req.body);
    res.send(req.body)
});

app.listen(7070, () => console.log('Example app listening on port 7070!'))

客户

这代表您的代码,但去掉了 Express 服务器。仅保留与向 GoToMeeting 的 API 发送请求相关的代码。

const url = "http://localhost:7070/";
const fetch = require("node-fetch");

const headers = {
    'Content-Type': 'application/json',
    Accept: 'application / json',
    Authorization: 'OAuth oauth_token=foobarbaz'
};

const meetingBody = {
    subject: 'string',
    starttime: '2018-03-20T08:15:30-05:00',
    endtime: '2018-03-20T09:15:30-05:00',
    passwordrequired: true,
    conferencecallinfo: 'string',
    timezonekey: 'string',
    meetingtype: 'immediate'
};


fetch(url, {
        method: 'POST',
        body: meetingBody,
        headers: headers
    })
    .then(res => res.text())
    .then(body => console.log(body));

运行测试用例的结果

服务器和客户端的日志显示:

[object Object] 

这是您致电meetingBody.toString() 时得到的信息。

如果您按照此答案顶部的说明更改代码,您会得到:

{"subject":"string","starttime":"2018-03-20T08:15:30-05:00","endtime":"2018-03-20T09:15:30-05:00","passwordrequired":true,"conferencecallinfo":"string","timezonekey":"string","meetingtype":"immediate"}

这是 JSON,这是 API 所期望的。


一边

MIME 类型中没有空格。 Accept: 'application / json', 应该是 Accept: 'application/json',。不过,这可能不会给您带来任何问题。

【讨论】:

  • 谢谢昆汀。成功了!
【解决方案2】:

我认为标题不正确。

你需要 'Accept: application/json' 没有空格。

【讨论】:

  • AcceptAuthorization需要引用
  • @mast3rd3mon — 它们是有效的标识符名称。他们不需要引用。
  • Content-Type 被引用了
  • @mast3rd3mon — 其中有一个 -。它不是有效的标识符名称。因此,在对象字面量中,它必须表示为字符串。
猜你喜欢
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
相关资源
最近更新 更多