express写的前端接口,请求路径都对,还是返回404。

场景:我在腾讯云服务器centos的2020端口(任意端口)运行 express写的前端接口,想将这个端口通过服务器nginx反向代理到 443端口,供微信公众号(或者小程序)调用。

问题:express接口完全没问题,可是配置好之后,请求接口都返回404,但是我在express接口文件中设置app.get('/*', (req,res) => {res.json({code: 400, data: '哈哈哈哈哈哈哈'})}),请求接口返回了 ‘哈哈哈’,其他接口都是404

express 接口文件:

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

app.get('/api/getname', (req, res) => {
  console.log('aaaaaa')

  res.json({
    code: 200,
    data: 'aaaaaaaaa',
  })
})

app.post('/api/get', (req, res) => {
  console.log('post====get')

  res.json({
    code: 200,
    data: 'namenannnaaa',
  })
})

app.get('/*', (req, res) => {
  console.log('get*///')

  res.json({
    code: 400,
    data: '哈哈哈哈哈',
  })
})

app.listen(2020, () => {
  console.log('Server has started.port on 2020')
})

nginx配置:

server {
    listen       443 ssl;
    server_name  program.test.com;

    # ....省略配置

    ssl_prefer_server_ciphers  on;

    location / {
        root   html;
        index  index.html index.htm;
    }
    location /program/ { # 微信公众平台接口测试
        proxy_pass http://127.0.0.1:2020; # !!!重点,就是这里导致出了问题!!!
        proxy_redirect off;
    }
}

如上配置,在浏览器中输入 https://program.test.com/program/api/getname  只能返回接口配置中 /* 的内容,而不能正确匹配 /api/getname 中的内容

这个问题困扰了整个周六,做了如下尝试:

1. 开始以为是express接口文件写得不对,反复审查了好多遍,还从官网扒了demo尝试了一遍,都是 404,排除这个原因;

2.换成 koa 框架 写接口,也不管用,接口也是全部返回 404,只有配上 /* 之后才会返回 /* 的内容,排除框架问题;

3.将端口开放,直接使用2020端口,不走nginx的代理,这里需要在服务器防火墙中放开2020端口,并在服务器控制台的安全组中 开放 2020端口,配置好后,直接用 http://program.test.com:2020/program/api/getname,发现直接无法访问,

nginx配置api默认请求地址_nginx配置api默认请求地址

哈哈哈,这里因为这时候的路径不对了,去掉标红的 program 即可,http://program.test.com:2020/api/getname,到这里,终于访问到了自己的数据,成功返回了 ‘aaaaaa’,说明api完全没问题,那么问题肯定出在了 nginx配置上,(是我错怪了 express)

4. 解决问题

再次查询了 nginx 配置,发现了端倪,大家看上边 nginx配置的这里:

nginx配置api默认请求地址_nginx配置api默认请求地址_02

这里,在 proxy_pass http://127.0.0.1:2020 后边需要加个 / , 至于为什么,参考  看这里

改为:

location /program/ { # 微信公众平台接口测试
    proxy_pass http://127.0.0.1:2020/; # 以 / 结尾,就不会匹配接口文件中以 /program/ 开头
    proxy_redirect off;
}

这样,记得运行 nginx -s reload  重启一下nginx

然后,再通过 https://program.test.com/program/api/getname  终于能正常返回  ‘aaaaaa’ 了,!!!