GraphQL - 缺少 POST 正文。你忘记使用 body-parser 中间件了吗?

Posted

技术标签:

【中文标题】GraphQL - 缺少 POST 正文。你忘记使用 body-parser 中间件了吗?【英文标题】:GraphQL - POST body missing. Did you forget use body-parser middleware? 【发布时间】:2020-03-30 16:19:43 【问题描述】:

我在graphql 查询中不断收到以下错误,但不确定原因:

POST body missing. Did you forget use body-parser middleware?

我在这里做了什么奇怪的事情吗?我已经尝试过在线使用 body-parser 的不同建议,但似乎仍然无法修复它。

服务器:

require('babel-polyfill')

const express = require('express')
const router = require('./middleware')
const expressStaticGzip = require('express-static-gzip')
const app = express()
const port = process.env.EXPRESS_PORT || 4000
const bodyParser = require('body-parser')

app.use(/\/((?!graphql).)*/, bodyParser.urlencoded( extended: true ))
app.use(/\/((?!graphql).)*/, bodyParser.json())
app.use('/search/data', expressStaticGzip('public'))
app.use('/', router)

app.listen(port, () => 
  console.log(`Server is running on port $port`)
)

路由器


const router = express.Router()
const server = new ApolloServer(
  typeDefs,
  resolvers,
  context: ( req ) => 
    const  authorization = ''  = req.headers
    const universalFetch = (url, opts = ) => 
      return fetch(url, 
        ...opts,
        headers: 
          ...opts.headers,
          authorization,
        ,
      )
    
    const request = createRpcClient(universalFetch)

    const methods = 

    const catalog = Object.keys(methods).reduce((catalog, method) => 
      catalog[method] = params => request(methods[method], params)
      return catalog
    , )
    return  catalog, fetch: universalFetch 
  ,
)

router.use(bodyParser.json())
router.use(bodyParser.text( type: 'application/graphql' ))
router.use('*', renderer)
server.applyMiddleware( app: router )

【问题讨论】:

@DanielRearden 谢谢!就是这样 【参考方案1】:

applyMiddleware 已经为 GraphQL 端点添加了 body-parser - 无需再次应用它,这样做可能会导致您的问题。

此外,我希望applyMiddlewarerouter.use('*', renderer) 之前被调用——否则,我认为通配符路由也将用于/graphql

【讨论】:

【参考方案2】:

这个错误也是由正文中的不正确的json或正文中的一些其他问题引起的,例如不必要的错误不可见字符。因此,请检查生成的 json 是否存在错误以及请求正文中实际存在的内容。

【讨论】:

【参考方案3】:

这个错误也可能因为body太大而引发。

我在 NextJs 的自定义 api 路由中使用 apollo-server-micro 获得它。

可以通过在 apollo 获取请求之前调用来自 microjson 函数来修复:

import  json  from 'micro'
import  ApolloServer  from 'apollo-server-micro'

const server = new ApolloServer(/*config*/)

const raiseBodyLimit: (handler: NextApiHandler) => NextApiHandler = (
  handler
) => async (req, res) => 
  if (req.headers['content-type'] !== 'application/json') 
    return handler(req, res)
  
  
  await json(req,  limit: '1gb' ) // This is the trick to raise body limit
 
  return handler(req, res)


export default raiseBodyLimit(
    server.createHandler(
      path: '/api/graphql',
    )
)


我在apollo-server's github issue 看到了这个。

以下是构建apollo server endpoint with next.js的一些信息

【讨论】:

【参考方案4】:

在我的特殊情况下,客户端只是错过了带有“application/json”值的“Content-type”标头。添加后错误消息消失了。

【讨论】:

【参考方案5】:

我忘记了标题 content-type: application/json

【讨论】:

以上是关于GraphQL - 缺少 POST 正文。你忘记使用 body-parser 中间件了吗?的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Next.js 应用程序中使用 Apollo-client GraphQL 上传文件:缺少 POST 正文

即使缺少所需架构的部分,GraphQL POST 也会通过

Spring post方法“缺少所需的请求正文”

缺少请求正文的 Spring Boot POST 请求?

Power Query 缺少对 Windows 身份验证和 REST API POST 正文的支持

Alamofire POST 请求,正文中有一个简单的字符串作为参数,标头仍然显示缺少的参数值