ExpressJS 在 POST 请求中显示空 req.body 对象,但 Insomnia 或 cURL 不显示

ExpressJS showing empty req.body object on POST request, but not with Insomnia or cURL

我正在尝试将全球支付网关(GPG 结帐)添加到我的 MERN 网站。

付款过程完成后,GPG 服务器应使用 cURL 向我在 GPG 仪表板中设置的路由发送 post 请求。这个post请求的内容是:PayAmount, PAYID, TransStatus, Signature.

这是我的路线:

router.route('/confirm-payment-detailes').post(async (req,res)=>{
    
    //const {TotalAmount,PAYID,TransStatus,Signature} = req.body;
    //console.log({TotalAmount,PAYID,TransStatus,Signature});

    // show any post request content to this route 
    console.log(req.body)
});

我正在显示我在该路线上获得的所有 POST 字段。

当我在笔记本电脑上使用 insomnia 或 cURL 进行测试时,它向我显示了我在服务器日志中发送的数据,但是当我完成付款过程时它显示空对象(这意味着GPG 结帐服务器知道我的通知 URL 并发送了一个 POST 请求,但它仍然显示为空)。

我打电话给支持团队,他们给我发了一个 PHP 通知页面示例:

<?php
$url = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$url = $_SERVER['REQUEST_URI'];
$my_url = explode('wp-content' , $url); 
$path = $_SERVER['DOCUMENT_ROOT']."/".$my_url[0];

$PayAmount    = $_POST['TotalAmount'];
$PAYID     = $_POST['PAYID'];
$TransStatus   = $_POST['TransStatus'];
$Signature = $_POST['Signature'];

include_once $path . '/wp-config.php';
include_once $path . '/wp-includes/wp-db.php';
include_once $path . '/wp-includes/pluggable.php';

$sign = sha1( $_POST['TransStatus']. $PAYID . "XXXXXXX" );

if($Signature == $sign){
    $order  = wc_get_order( $PAYID );
    switch ( $TransStatus ) {
            
        case '05' : // refus
            $order->update_status( 'wc-failed', $reason );
        break;
        case '00' : // accord
            $order->update_status( 'wc-processing', $reason );
            WC()->cart->empty_cart();
        break;
        case '06' : //annuler
            $order->update_status( 'wc-cancelled', $reason );
        break;
        case '07' : // rembourser
            $order->update_status( 'wc-refunded', $reason );
        break;
        case '08' : // Charge back 
                        
        default :
        break;
    }
    
}
?>

据我所知,这只是一个简单的POST请求!为什么我的服务器显示空对象?虽然当我使用 insomnia 或 cURL 随机字段进行测试时效果很好。

这是我的app.js文件内容:

//imports Here : 
const express = require('express');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const mongoStore = require('connect-mongo');
//declare app here : 
const app = express();
app.disable('x-powered-by');
app.set('view engine','ejs');
app.set('views','Views');
app.use(express.static(__dirname + '/Public'));
app.use(cookieParser());
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.use(cors());

//Clients API Routes :
app.use(process.env.CLIENT_API_PATH,require('./Routes/clientAPIRoutes'));
//Admin Pages Routes :
app.use(process.env.ADMIN_PATH,require('./Routes/adminPageRoutes'));

module.exports = app;

有人知道这个问题吗?

编辑: 我确实在我的服务器上创建了一个 php 文件来接收数据而不是节点应用程序,它确实通过使用 $_POST["field_name"] 来工作,所以我真的对此感到困惑!

在从 php 脚本发送请求时设置内容类型 header。这里 CURL(curl 可能会给你输出但格式错误),邮递员默认为你做。这里服务器需要知道您在请求中发送的数据类型,因此它可以使用适当的方法来获取该编码数据。即 json、xml、x-www-form-urlencoded 和多部分等

可以通过在请求中设置Content-Type header来完成

这样设置Content-Type : application/json(for json data) or xml (for xml data) or x-www-form-urlencoded

$_POST 在请求中使用 application/x-www-form-urlencoded 或 multipart/form-data 作为 HTTP Content-Type。 运行 通过包含这个 echo $_SERVER["CONTENT_TYPE"]; 检查你的 PHP 脚本并且可能的输出可能是 multipart/form-data 基于 application/x-www-form-urlencoded 已经在你的节点服务器中被解析. 用于解析 multipart/form-data 安装 npm multer 中间件包 npm install multer.

//imports Here : 
const express = require('express');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const mongoStore = require('connect-mongo');
const multer= require('multer');
//declare app here : 
const app = express();
app.disable('x-powered-by');
app.set('view engine','ejs');
app.set('views','Views');
app.use(express.static(__dirname + '/Public'));
app.use(cookieParser());
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.use(multer().array()) // parses multipart/form-data
app.use(cors());

//Clients API Routes :
app.use(process.env.CLIENT_API_PATH,require('./Routes/clientAPIRoutes'));
//Admin Pages Routes :
app.use(process.env.ADMIN_PATH,require('./Routes/adminPageRoutes'));

module.exports = app;

我想我发现了问题。

支付网关服务器正在使用 php cURL,将数据发布到 Node/express Js 应用程序似乎不太顺利。

所以我没有办法修复它,因为这是他们的服务器错误。

Made PHP curl POST to nodeJS API but can't read response data

我要报告这个问题。但是现在,我要使用这个 php 脚本,因为我需要完成工作!

<?php
/*
    
   
    Author : Rouissi Iheb ( rouissi2017@gmail.com ) 
    Date : 27/09/2021
    Whosebug qustion : 
    
    
    This script is used to redirect the POST payment detailes recived from GPG checkout servers to the E-commerce Node/expressJs server

    reason : 
      
      
      
      
      
*/
function execInBackground($cmd) {
   if (substr(php_uname(), 0, 7) == "Windows"){
       pclose(popen("start /B ". $cmd, "r")); 
   }
   else {
       exec($cmd . " > /dev/null &");  
   }
}
if(isset($_POST['TotalAmount']) && isset($_POST['PAYID']) && isset($_POST['TransStatus']) && isset($_POST['Signature'])){
   
   //for test only TO REMOVE ON PRODUCTION !!
    //-----------------------------
   $content = "New Post Request from : ".$_SERVER['REMOTE_ADDR']." \n";
   $myfile = fopen("log.txt", "a") or die("Unable to open file!");
   fwrite($myfile, $content);
   fclose($myfile);
    //------------------------------

   $data = "TotalAmount=".$_POST['TotalAmount']."&PAYID=".$_POST['PAYID']."&TransStatus=".$_POST['TransStatus']."&Signature=".$_POST['Signature'];
   execInBackground('curl -X POST -d "'.$data.'" http://nodeserver:nodeport/some-route');
}
?>

关于我需要提供的通知 link 以接收其中的数据,我必须在我的服务器上安装 php,使用 ssl 创建一个新的子域并将此配置添加到我的nginx 配置:

server{
        listen 80;
        server_name gpg-gateway.mywebsite.com;
        root /home/user/php-proxy;
        index index.php;
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        }
}