首页 > 解决方案 > 为什么这个对 Ingress (GKE) 的 HTTP GET 请求总是返回 400(错误请求)错误?

问题描述

我正在尝试向 Kubernetes (GKE) 中的应用程序发出 GET 请求,但总是返回 400 Bad Request。

POST、PUT 和 DELETE 方法运行良好。

最奇怪的是,当我直接使用端口转发到 pod 时,GET 请求没有问题。

我试图尽可能地最小化我的应用程序的代码,它看起来像这样:

const express = require('express')
const app = express()
const port = 3000

app.use(express.json())
app.use(express.urlencoded({ extended: true }))

app.get('/', (req, res) => {
  res.send(req.body)
})

app.post('/', function(req, res){
  res.send(req.body);
});

app.put('/', function(req, res){
  res.send(req.body);
});

app.delete('/', function(req, res){
  res.send(req.body);
});

app.listen(port, () => {
  console.log(`Listening to port ${port}`)
})

我认为问题出在我的 Ingress 配置中,因为使用端口转发它运行良好。这是我的入口 yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  tls:
    - hosts:
        - my-test-host
      secretName: tls-secret
  rules:
    - host: my-test-host
      http:
        paths:
        - path: /*
          backend:
            serviceName: my-test-service
            servicePort: 3000

最后,这是始终返回 400 的请求。

curl --location --request GET 'https://my-test-host/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "test": "123"
}'

使用其他方法(POST、PUT 或 DELETE)的相同请求运行良好。请问,我做错了什么?

标签: node.jshttpkubernetesgoogle-kubernetes-enginekubernetes-ingress

解决方案


我设法找到了问题的解决方案。

问题是Ingress 不接受带有正文的 HTTP GET 请求并以错误 400 响应。

最可悲的是,我在任何地方的 Kubernetes 文档中都没有发现任何关于这个问题的信息。

我搜索了有关在 GET 请求中发送正文的良好实践信息,然后找到了这两个链接:

https://www.rfc-editor.org/rfc/rfc7231#section-4.3.1

https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET

据我了解,不禁止发送带有正文的 GET,但不建议这样做。

因此,为了解决我的问题,我更改了代码以从 GET 请求中的“查询”而不是“正文”获取参数:

app.get('/', (req, res) => {
  res.send(req.query)
})

因此,我需要更改 GET 请求中的发送参数:

curl --location --request GET 'https://my-test-host?test=123'

经验教训:为避免出现问题,切勿接受带有正文的 GET 请求。

谢谢。


推荐阅读