首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当从静态包向Express后端代理请求时,NginX未能传递POST请求体

当从静态包向Express后端代理请求时,NginX未能传递POST请求体
EN

Stack Overflow用户
提问于 2020-01-08 08:15:35
回答 3查看 12.2K关注 0票数 5

我正在运行一台托管在数字海洋液滴上的NginX服务器,网址是“袖珍商队”。

目标是构建react包,它将链接到所有css/js/映像,并使用nginx处理服务静态内容。API服务器是一个运行在某个端口上的Express应用程序,我将从静态包到这里的所有请求进行代理。

当我在本地开发时,我能够从前端向我的API发送JSON数据。

当我部署API时,我可以通过Postman发送JSON负载

但问题是,当我通过访问NginX提供的静态文件访问我的应用程序时,我向live发送了一个POST请求,req.body是空的!

我可以检查JS控制台,并看到fetch请求正确地发送了JSON数据体。

请求被正确地路由到活动API,但是数据是空的!NginX代理不传递请求体,我不知道为什么??

我有一个问题--虽然我可以访问所有的静态文件,但是我的API请求被正确地代理并路由到API,但是当Express访问req.body时,它是空的!

/etc/nginx/sites-available/pocket-caravan.com

代码语言:javascript
复制
server {

    root /var/www/pocket-caravan.com/html;
    index index.html index.html index.nginx.debian.html;

    server_name pocket-caravan.com www.pocket-caravan.com;


    location /omni-commerce {
        index index.html;
    }

    location /static {
        try_files /omni-commerce/$uri /omni-commerce/$uri/;
    }

    location /api {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Connection 'upgrade';
        access_log /var/www/pocket-caravan.com/logs/logs.txt;
    }


    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/pocket-caravan.com/fullchain.pem; # m$
    ssl_certificate_key /etc/letsencrypt/live/pocket-caravan.com/privkey.pem; #$
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = www.pocket-caravan.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = pocket-caravan.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    listen 80;
    listen [::]:80;

    server_name pocket-caravan.com www.pocket-caravan.com;
    return 404; # managed by Certbot




}

复制此问题:

我访问我的应用程序:https://pocket-caravan.com/omni-commerce/

发送一个POST请求https://pocket-caravan.com/api/register?pathway=marketplace

示例JSON数据:{ "firstName":"foo","lastName":"bar","email":"foo@bar.com","password":"123123“

}

在端口3001运行的快递应用程序:

代码语言:javascript
复制
import util from 'util';
import helmet from 'helmet';
import express from 'express';
import cookieParser from 'cookie-parser'
import morgan from 'morgan';
import { handleError } from '../lib/utils/logger';
import getEnv from '../lib/utils/get-env';

import { establishMongooseConnection } from '../lib/mongo/mongoose-db';
import { usersRouter } from './router/users';

getEnv()

const app = express();

app.use(morgan('common'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(helmet());

if (app.get('env') === 'development') {
  console.log('Configuring Access Control Allow Origin header for Local Development.');
  app.use('*', (req, res, next) => {
    res.header(
      'Access-Control-Allow-Origin',
      `${req.get('origin')}`,
    );
    res.header(
      'Access-Control-Allow-Headers',
      'Origin, X-Requested-With, Content-Type, Accept, Authorization, Set-Cookie',
    )
    res.header(
      'Access-Control-Allow-Methods',
      'POST, GET, OPTIONS, DELETE, PUT'
    )
    res.header('Access-Control-Allow-Credentials', true);
    next();
  });
}

if (app.get('env') === 'production') {
  // Trust DigitalOcean - NginX Proxy 
  // https://expressjs.com/en/guide/behind-proxies.html
  app.set('trust proxy', 'loopback', process.env.DIGITAL_OCEAN_DROPLET_IP)
}

establishMongooseConnection()
  .then(connection => {
    if (connection.success) {
      console.log(connection.message);
    };
  }).catch(err => {
    console.log("Catching mongoose error...")
    console.log(err);
  })


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

app.get('/api', (req, res) => {
  res.send('GET /api')
});

app.use('/api', usersRouter);

// Universal Error Handler
app.use('*', (err, req, res, next) => {
  handleError(err);
  res.status(err.status || 500).json({ error: err.stack, message: err.message });
})

app.listen(process.env.PORT, () => {
  console.log(`Server listening on port ${process.env.PORT}`);
});

当我将请求发送到https://pocket-caravan.com/api/register?pathway=marketplace时,它在localhost - webpackdevserver上工作得很好。

但是,当从代理请求的同一NginX服务器提供已部署的构建代码时,请求主体将无法由Express访问。

我对NginX没有足够的了解来进行调试,我似乎无法记录请求体,我真的很感谢您的帮助!

以下是来自网络面板的有关失败请求的信息:(由于req.body.email未定义和崩溃中间件,抛出500 )

代码语言:javascript
复制
General
Request URL: https://pocket-caravan.com/api/register?pathway=omni
Request Method: POST
Status Code: 500 Internal Server Error
Remote Address: 67.205.154.96:443
Referrer Policy: no-referrer-when-downgrade

Response Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Set-Cookie
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Origin: https://pocket-caravan.com
Connection: keep-alive
Content-Length: 1633
Content-Type: application/json; charset=utf-8
Date: Wed, 08 Jan 2020 08:52:16 GMT
ETag: W/"661-PIPnVrxYNILoG0ylml9L0Camw1w"
Server: nginx/1.14.0 (Ubuntu)
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Content-Type-Options: nosniff
X-DNS-Prefetch-Control: off
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block

Request-Headers
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 94
Content-Type: text/plain;charset=UTF-8
Cookie: Stuff=random--!; Authorization-Omni=sec0ret%20encu0ingdgin
DNT: 1
Host: pocket-caravan.com
Origin: https://pocket-caravan.com
Referer: https://pocket-caravan.com/omni-commerce/
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36
pathway: omni
{firstName: "asdasda", lastName: "asdas", email: "asdasd@adsda.com", password: "asdasdsdasd"}
firstName: "asdasda"
lastName: "asdas"
email: "asdasd@adsda.com"
password: "asdasdsdasd"
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-08 09:16:23

我解决了问题。很简单。我未能将正确的“Content”标题传递给代理。我查看了请求输出,并在期望传递JSON时看到了这个结果:

Content-Type: text/plain;charset=UTF-8

Express body解析器/json解析器没有解析主体,也没有将其传递给req.body

将其添加到我的/api代理处理程序中:

proxy_set_header content-type "application/json";

代码语言:javascript
复制
    location /api {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $host;
        proxy_set_header content-type "application/json";
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Connection 'upgrade';
        access_log /var/www/pocket-caravan.com/logs/logs.txt;
    }
票数 6
EN

Stack Overflow用户

发布于 2020-12-29 21:35:43

可能会对其他人有所帮助,所以我也遇到了同样的问题,网址是接收到的,但没有数据。按照接受的答案中的建议,编写了nginx配置之后,问题仍然存在。然后,我发现我需要调用服务器,而不是使用http,而是使用https。所以如果你还跟我一样,那就查一下你的网址。

不知道为什么在没有数据的情况下,http调用会被路由,但它做到了。

票数 2
EN

Stack Overflow用户

发布于 2022-01-04 07:56:54

我遇到了这个问题。我发现磁盘已经满了,所以要解决这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59641821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档