使用 CURL 时,从 RESTful API 获取数据的 POST 返回有效字符串,但使用 fetch 时“解码失败”

问题描述 投票:0回答:1

我有一个简单的expressjs代理服务器,将请求中继到RESTful API,并将该API的响应中继回来。如果我使用 CURL 来访问它,就像这样:

curl -s "http://localhost:3000/api/findOne" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{ /* request body */ }'

然后我将有效的 JSON 返回到 STDOUT。

但是如果我尝试从 JavaScript 前端

fetch
这样:

fetch("http://localhost:3000/api/findOne", {
  method: "POST",
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: JSON.stringify(/* request body */),
})
  .then((res) => res.json()) // .text() doesn't work either!
  .then((res) => console.log(res))
  .catch((e) => e);

然后我从 catch 块返回这个错误:

最糟糕的部分是,我让代理服务器打印出它接收到的请求以及它生成的从实际 RESTful API 中提取的请求,并且我在进行curl 调用时生成的输出和输出之间进行了比较它是在进行 fetch 调用时生成的,并且它们是“相同的”,逐个字符。这意味着代理服务器每次都做完全相同的事情,只是 fetch 出了问题,导致它无法解析结果,即使是纯文本,这很奇怪。 我在互联网上根本找不到任何关于此的信息,有人可以告诉我吗?谢谢。我对自己的网络开发技能有点生疏(已经脱离圈子好几年了)。

编辑

:好的,我已经更进一步了:似乎发生的事情是我从代理服务器获得的输出被截断,就像,它只是停在输出流的中间,与 API 端点的原始输出进行比较。也许这使得无法解码?即便如此,它也应该可以被解码为文本,因为curl可以做到这一点,但JavaScript似乎无法做到这一点。此外,即使代理服务器的输出“不”至少明显被截断,也会发生解码错误。这是(稍微精简的)服务器代码: import express, { Express, Request, Response } from 'express'; import dotenv from 'dotenv'; import bodyParser from 'body-parser'; import cors from 'cors'; dotenv.config(); const app: Express = express(); const port = process.env.PORT || 3000; const apikey = ...; const pathsToProxy = '/api/'; const MONGODB_URL = ...; const corsOption = { credentials: true, origin: ['http://localhost:8080', 'http://localhost:3000'], }; app.use(cors()); app.use(bodyParser.json()); app.all('/api/*', async (req: Request, res: Response) => { const url = req.url.replace(pathsToProxy, MONGODB_URL); let headers = new Headers(); headers.set('Content-Type', req.get('content-type') || 'application/json'); headers.set('Accept', req.get('accept') || 'application/json'); headers.set('apiKey', apikey!); const mongoReq = { method: req.method, headers: headers, body: ['PUT', 'POST'].includes(req.method) ? JSON.stringify(req.body) : undefined, }; try { const mongoRes = await fetch(url, mongoReq); mongoRes.body?.pipeTo( new WritableStream({ start() { res.statusCode = mongoRes.status; mongoRes.headers.forEach((v, n) => res.setHeader(n, v)); }, write(chunk) { res.write(chunk); }, close() { res.end(); }, }) ); } catch (e) { console.log(e); res.status(500).send(e); } }); app.listen(port, () => { console.log(`[server]: Server is running at http://localhost:${port}`); }); 我在这里没有看到任何明显会导致输出被截断的东西。


为什么不简单地使用标准

.json()
javascript json curl fetch-api
1个回答
0
投票

我没有看到将从 mongodb 代理返回的数据作为整个数据进行分块的逻辑原因。

所以试试这个:

try { const mongoRes = await fetch(url, mongoReq); const status = mongoRes.status; const body = await mongoRes.json(); res.set({ ...mongoRes.headers, }); res .status(mongoRes.status) .json(body); } catch (error) { console.error(error); res .status(500) .json({ message: error.message, }); }

© www.soinside.com 2019 - 2024. All rights reserved.