如何使用fetch发送数组?(Javascript)

6

我正在尝试使用fetch发送一个类似于以下内容的数组:

{"cards":[[189,2],[211,2],[238,2],[778,2],[985,2],[1008,2],[1073,2],[1171,2],[48886,2],[49161,2],[49164,2],[49184,1],[49356,2],[50372,2],[51722,1],[52422,2]],"heroes":[1066],"format":2}

这是我正在尝试的内容:

 getCardsForDeck = deck => {
    var stringifiedDeck = JSON.stringify(deck);
    console.log("stringifiedDeck:" + stringifiedDeck);
    fetch(`http://localhost:3001/api/getCardsForDeck`, {
      method: "PUT",
      body: stringifiedDeck
    })
      .then(cards => cards.json())
      .then(res => this.setState({ cards: res.cards }));
  };

但是我遇到了一个错误:

Unhandled Rejection (SyntaxError): Unexpected token < in JSON at position 0

如果不使用JSON.stringify(),我该如何发送这些数据?还是说我需要编辑数据以删除括号?

在网络标签中检查API后,它给了我以下信息:

     SyntaxError: Unexpected token o in JSON at position 1
[0]     at JSON.parse (<anonymous>)
[0]     at parse (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\body-parser\lib\types\json.js:89:19)
[0]     at C:\Users\User\projects\webapp\deck-editor\backend\node_modules\body-parser\lib\read.js:121:18
[0]     at invokeCallback (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\raw-body\index.js:224:16)
[0]     at done (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\raw-body\index.js:213:7)
[0]     at IncomingMessage.onEnd (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\raw-body\index.js:273:7)
[0]     at IncomingMessage.emit (events.js:194:15)
[0]     at endReadableNT (_stream_readable.js:1125:12)
[0]     at process._tickCallback (internal/process/next_tick.js:63:19)
[0] SyntaxError: Unexpected token o in JSON at position 1
[0]     at JSON.parse (<anonymous>)
[0]     at parse (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\body-parser\lib\types\json.js:89:19)
[0]     at C:\Users\User\projects\webapp\deck-editor\backend\node_modules\body-parser\lib\read.js:121:18
[0]     at invokeCallback (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\raw-body\index.js:224:16)
[0]     at done (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\raw-body\index.js:213:7)
[0]     at IncomingMessage.onEnd (C:\Users\User\projects\webapp\deck-editor\backend\node_modules\raw-body\index.js:273:7)
[0]     at IncomingMessage.emit (events.js:194:15)
[0]     at endReadableNT (_stream_readable.js:1125:12)
[0]     at process._tickCallback (internal/process/next_tick.js:63:19)

1
这个错误信息表明你收到的很可能不是JSON。并且由于它以<开头,通常会发生的情况是你会得到一个错误的页面,因此这是HTML,例如404页面或500之类的错误。检查响应,你应该能看到响应的HTML。 - VLAZ
1
http://localhost:3001/api/getCardsForDeck 是否会通过回显来响应您的 PUT 请求?您的代码似乎假定它会这样做。通常情况下,它会发送自己的响应,可能是 JSON、文本或 HTML... - T.J. Crowder
1
你的 API 函数可能会输出错误:https://www.kevinleary.net/syntax-error-unexpected-token-json-position-0/ - GrafiCode
1
你可能需要指定返回的数据类型,例如API返回XML,而你想要JSON。 - DaveG
2个回答

7
你似乎期望在你向它发送JSON之后,http://localhost:3001/api/getCardsForDeck会向你返回JSON。很可能它响应的是HTML而不是JSON。
那段代码中还有另外两个错误:
  1. You need to say what you're sending, since it's not the default URI-encoded data:

    fetch(`http://localhost:3001/api/getCardsForDeck`, {
      method: "PUT",
      body: stringifiedDeck,
      headers: {                              // ***
        "Content-Type": "application/json"    // ***
      }                                       // ***
    })
    
  2. You need to check the status of the response. (Everyone misses this out.) The simplest way is to check the ok flag on the response:

    fetch(`http://localhost:3001/api/getCardsForDeck`, {
      method: "PUT",
      body: stringifiedDeck,
      headers: {
        "Content-Type": "application/json"
      }
    })
    .then(response => {
      if (!response.ok) {                                  // ***
        throw new Error("HTTP error " + response.status);  // ***
      }                                                    // ***
      // ...use `response.json`, `response.text`, etc. here
    })
    .catch(error => {
      // ...handle/report error
    });
    

在 #2 中的这个调用会在任何其他调用之前执行,对吗?它将是第一个“then”吗? - davidahines
1
其实,我现在明白了,正在进行更改! - davidahines
1
@davidahines - 是的,没错。通常在第一个 then 结束时,你会使用 return response.json();(如果你期望得到 JSON 数据)或者 return response.text();(如果你期望得到文本数据),等等。在我上面写的 "use response.json, response.text, etc. here" 的位置,然后再加一个 then` 来实际使用这些数据。 - T.J. Crowder
如果我告诉它我正在发送JSON,那么我是否仍应将其转换为字符串? - davidahines
1
@davidahines - 是的,因为JSON是文本格式。 (因此,如果您在JavaScript代码中工作,并且没有使用字符串,则您不是在使用JSON。)如果您没有使用JSON.stringify,它将不是JSON,而是一个对象。(这并不能阻止许多库为您转换为JSON,但我99%确定fetch不会。 :-) ) - T.J. Crowder
1
设置完成后,很容易找到问题所在。谢谢! - davidahines

0
今天我遇到了这个问题,但是我想将列表传输到后端而不是接收正确的错误。解决方案非常简单,我简直不敢相信我卡了几个小时。
我的解决方案如下:
const response = await fetch(SERVER_URL + `/api/studyPlan/${plan.userid}`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  credentials: "include",
  body: JSON.stringify({
    plan: planlist,
  }),
});

在列表中,planlist是一个数组。我们可以将此列表作为值发送到后端。 然后在后端,直接使用req.body.plan来获取信息。
希望这有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接