nodejs post请求 怎么用url

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs post请求 怎么用url相关的知识,希望对你有一定的参考价值。

参考技术A router: post '/test'
controller: req.body

从 Angular/NodeJS/ExpressJS 向 3rd 方 URL 的 POST 请求

【中文标题】从 Angular/NodeJS/ExpressJS 向 3rd 方 URL 的 POST 请求【英文标题】:POST request to 3rd party URL from Angular/NodeJS/ExpressJS 【发布时间】:2020-07-04 16:59:40 【问题描述】:

选项 4.2 对我来说似乎是最好的方向。有人有其他建议吗?

有没有办法在以下任何一种情况下访问响应,或者我需要重写整个逻辑?


我需要使用带有或不带有重定向的 NodeJS/ExpressJS 的 Angular Typescript 向 3rd 方支付提供商执行表单 POST。

流程:

问题是在某些情况下,当我成功执行 URL 重定向时我没有收到来自支付网关的任何响应当用户点击“支付”时 - “Plati”他被重定向到成功页面http://example.com/success,如果出现错误响应页面http://example.com/cancel

预期场景

用户来到网站选择产品并点击购买按钮。此时,她/他会被带到另一个页面,在那里她/他进行付款。付款成功后,用户被重定向回网站,我得到服务器的响应并向用户显示相关消息。

选项 1 - 表单操作 URL

如果我提交标准表单并将支付网关 URL 放入 [action]="'https://test-wallet.example.com/checkout/'" 中,那么用户将被直接重定向到该 URL,并且付款将成功处理。但在这种情况下,我没有收到让我知道向用户显示哪些数据所需的响应 - 成功或错误消息。

<form [action]="'https://test-wallet.example.com/checkout/'" ngNoForm method="POST" target="_blank">
      <button type="submit">Pay with card</button>
      <input name='param1' value='param1'>
      <input name='param2' value='param2'>
      <input name='param3' value='param3'>
      <input name='param4' value='param4'>
      <input name='param5' value='param5'>
      <input name='param6' value='param6'>
      <input name='param7' value='param7'>
      <input name='param8' value='param8'>
      <input name='param9' value='param9'>
</form>

选项 2 - HttpClient 通过服务

我还尝试在 Angular 应用程序中发出 HttpClient POST 请求,并且没有 NodeJS 后端。在这种情况下,我直接调用支付网关 URL,但出现 CORS 错误。

payment.service.ts:

payFunction(parameters: any)
   return this._httpClient.post('https://test-wallet.example.com/checkout/'+ 
      'param1='+parameters.param1+ 
      '&param2='+parameters.param2+
      '&param3='+parameters.param3+ 
      '&param4='+parameters.param4+ 
      '&param5='+parameters.param5+
      '&param6='+parameters.param6+ 
      '&param7='+parameters.param7+
      '&param8='+parameters.param8+
      '&param9='+parameters.param9
      ,parameters
      ,this.httpOptions 
    )
   .catch(err => 
      console.log(err);
      return Observable.of(err)
   )

我在组件中调用了之前的服务:

async test(form)
  await this._myPaymentService.payFunction(form.value).subscribe(res => 
        console.log(res);
)

在那种情况下,我只收到了 CORS 错误。

选项 3 - jQuery AJAX

我在我的 Angular 组件中使用 cross-domain contentType 调用它。

但在上述情况下,我也只收到了 CORS 错误。我知道在 Angular 应用程序中使用 jQuery 不是书本上的,但我必须尝试。

 $.ajax(
   headers:  
     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
   ,
   url : 'https://test-wallet.example.com/checkout/',
   type: "POST",
   beforeSend: function(xhrObj)
       xhrObj.setRequestHeader('Content-Type':  'application/x-www-form-urlencoded; charset=UTF-8');
   ,
   dataType : "json",
   async:true,
   crossDomain:true,
   data: corvusDataObject,
   error: function () 
     alert('Ajax Error');
   ,
   onFailure: function () 
     alert('Ajax Failure');
   ,
   statusCode: 
     404: function() 
       alert("Ajax 404");
        
   ,
   success : function (response) 
     alert("Success: " + JSON.stringify(response));
     
   )
   .done(function( data ) 
   alert("Done: " + JSON.stringify(response));
);

选项 4 - NodeJS/ExpressJS 后端

如果我使用这种方法,那么我会以与第一种情况相同的方式收到重定向。但是我的后端没有收到支付网关提供商的任何响应。

在 Angular 应用程序中,我正在调用我的 API:

<form [action]="'http://localhost:8080/myPaymentAPI/'" ngNoForm method="POST" target="_blank">
      <button type="submit">Pay with card</button>
      <input name='param1' value='param1'>
      <input name='param2' value='param2'>
      <input name='param3' value='param3'>
      <input name='param4' value='param4'>
      <input name='param5' value='param5'>
      <input name='param6' value='param6'>
      <input name='param7' value='param7'>
      <input name='param8' value='param8'>
      <input name='param9' value='param9'>
</form>

在 NodeJS/ExpressJS 中,我制作了 myPaymentAPI API 和 307 次重定向 (from this SO answer)。

    var express = require('express');
    var app = express();
    var cors = require('cors')  // CORS
    var bodyParser = require('body-parser'); 

    app.use(bodyParser.urlencoded( extended: true ));
    app.use(bodyParser.json());
    app.use(cors());

    var port = process.env.PORT || 8080;
    var apiRoutes = express.Router();

    apiRoutes.get('/', function(req, res) 
        res.json( message: 'API works!' );
    );

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

    app.post('/myPaymentAPI', function(req, res, next) 

      let param1 = req.body.param1;
      let param2 = req.body.param2;
      let param3 = req.body.param3;
      let param4 = req.body.param4;
      let param5 = req.body.param5;
      let param6 = req.body.param6;
      let param7 = req.body.param7;
      let param8 = req.body.param8;
      let param9 = req.body.param9;

    res.status(200).redirect(307, 'https://test-wallet.example.com/checkout/?param1='+param1 +'&param2='+param2+...)
    //res.end();

    );

以上重定向将用户转移到 URL(见第一张图片):https://test-wallet.example.com/#/checkout/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx 并且该 URL 上的用户进行了付款,但我再一次没有收到任何响应。

选项 4.1

fetch 返回 HTML 页面,但 &lt;body&gt; 为空白

app.post('/myPaymentAPI', function(req, res, next) 

    const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&param2='+param2+'&param3='+param3+'&param4='+param4+'&param5='+param5+'&param6='+param6+'&param7='+param7+'&param8='+param8+'&param9='+param9;
       fetch(url, 
           method : "POST",
           body: res.body
       ).then(
           response => response.text()
       ).then(
         html => res.send(html)
      ).catch((err) => 
         reject(err);
       );

);

选项 4.2

在这种方法中,我成功获得了 URL 的简短版本(参见第一张图片),然后我将用户重定向到该 URL。

    app.post('/myPaymentAPI', function(req, res, next) 

      let param1 = req.body.param1;
      let param2 = req.body.param2;
      let param3 = req.body.param3;
      ...

      try
        var body = JSON.stringify(req.body);
        const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&param2='+param2+...;
        var newData = await fetch(url, method: "POST", body: body)
        console.log(newData.url)
        res.redirect(307, newData.url);
      catch(error)
        console.log(error)
      

);

此页面在 307 重定向后打开。消息显示“无法处理您的请求。很抱歉,出现错误。”

在进行重定向之前,我是否需要在此步骤中再次附加 FormData?

选项 4.3

在这种方法中,我调用我的 API 并在 res.send 中创建一个对象,然后我将其发送到我的前端。

try
     var body = JSON.stringify(req.body);
     const url = 'https://test-wallet.example.com/checkout/?param1='+param1+'&param2='+param2+'&param3='+param3+...;
       await fetch(url, method: "POST", body: body).then((response) => 
         const data = response;
         res.send(
           success: true,
           redirectURL: data.url,
           body: req.body
         )
      )
       .catch((error) => 
         console.error(error);
       )
   catch(error)
     console.log(error)

在前端我成功接收到redirectURLbody 数据并尝试进行重定向。

this._myPaymentService.payFunction(form.value).subscribe(res => 
            console.log(res);
            console.log(res.redirectURL);
            window.location.replace(res.redirectURL);
)

Web 浏览器随后会转到以下页面,但内容为空白。

因为请求已经变成了GET。我知道以这种方式发送 POST 请求是不可能的,我正在寻找方法。

【问题讨论】:

支付服务如何发送错误或成功响应?只是使用查询字符串中的参数重定向到callbak url? @David 我在回调 URL 中没有收到任何响应,这是我最大的问题。文档指出成功 URL 应该是这样的http://example.com/success?order_number=1233,但我只收到http://example.com/success。我正在等待他们的支持部门对回调 URL 中的参数做出回应。 @David 据称,POST 参数位于消息正文中。他们说,URL 保持不变,我需要期待 POST。 您在问题中说,用户在成功付款后被重定向到“example.com/success”(example.com 是第 3 方支付网关)。因此,用户必须从该成功页面按下另一个按钮,该按钮将执行发布请求以返回您的网站? @David example.com/success 是我的网站,用户在test-wallet.example.com(支付网关的地址)上成功付款后会被重定向到该页面。 【参考方案1】:

哇,听起来您非常渴望编写代码,但确实缺乏一些基础知识。您想拥有 SPA 还是拥有旧式 POST?当然,当您尝试发送直接 API 请求时会收到 CORS 错误。

我很担心这个结果,因为你实际上是在处理付款,而且似乎对架构不太了解——也许我错了。你听说过 OWASP 或 CSRF 吗?您是否考虑过存储交易以防万一发生不好的事情?您是否防止用户使用负数发送错误请求?怎么样

给自己和用户的口袋一些安慰,在编写代码之前先阅读,至少通过一些示例,例如 Angular Tour of hero。

这是它应该是什么样子的基本流程。

后端是这里的翻译器。它提供了一个 API,将用户发送的数据(验证后)转换为支付提供商需要的请求。得到结果后,它会将答案转换为对 Angular 应用程序的定义响应——这将是成功或错误消息。然后 Angular 应用程序可以决定做什么:向用户显示 ok 或 error 消息。

还有!您总是会从支付提供商那里收到一条消息,如果真的没有,那么您应该实现超时并向用户发送错误消息。

祝你好运,我真的祈祷你了解并实施一些安全措施。

【讨论】:

感谢您的详细解答。我已经实现了上图中的一些步骤,我的后端作为翻译的解决方案对我来说是最合乎逻辑的。我已经发布了所有这些代码以避免答案告诉我尝试我已经尝试过的东西。再次感谢。【参考方案2】:

这两种方法似乎是正确的:

选项 1 选项 4(使用 nodejs 服务器 - 在 4.1 之前付款成功)

但是,似乎缺少一个流程。支付完成后,支付 API 服务器向 http://example.com/successhttp://example.com/cancel 发出一个 post 请求,并在正文中找到参数。因此,您不能直接使用 url 向用户显示屏幕上的信息(客户端浏览器)。


你需要做的是:

拥有节点服务器(或者您的后端 API 服务器也可以工作),并使用 app.post 处理服务器上的 url - 就像您为 app.post('/myPaymentAPI',) 所做的那样。 更新您的数据库或从 req.body 等获取相关的付款详情或 ID。 创建一个新的网址,如https://yourwebsite.com/payment?status=SUCCESS&amp;other-infohttps://yourwebsite.com/payment/id 将用户重定向到浏览器上的特定网址 该特定网址将包含详细信息或 ID。您可以显示相关详细信息或获取 id 并根据需要进行 API 调用
app.post("http://example.com/success", function(req, res)
  //get the req.body/params here which Payment Server will post to success url
  //update your backend etc about payment status etc
  //redirect to your custom page from here https://yourwebsite.com/payment?status=success&id=id or similar
)

app.post("http://example.com/cancel", function(req, res)
  //get the req.body/params here which Payment Server will post to cancel url
  //update your backend etc about payment status etc
  //redirect to your custom page from here https://yourwebsite.com/payment?status=failure&id=id
)

希望对您有所帮助。回复任何疑问/澄清

【讨论】:

感谢您的回答。问题是我不确定我需要在哪一步读取body 数据。付款后(用户有 15 分钟的时间完成付款),我被重定向到http://example.com/success。我是否需要在那个 Angular 组件中使用相同的地址 app.post("http://example.com/success",... 向我的 API 发出请求并读取 body 数据? 目前,我正在测试一种解决方案,在该解决方案中,在付款之前,我将所有用户数据保存到我的数据库(这是注册)并在 localStorage 中创建一个唯一 ID,然后等待 @987654331 @ 或 cancel 要在前端 Angular 应用程序上激活的页面。在success 页面上,我调用我的第二个API 并更新用户,在cancel 页面上,我调用我的第三个API 并删除该用户,以便他可以重复付款。我正在使用 localStorage 中的参数在数据库中进行比较。除非调用这两个 API 中的任何一个,否则我会在 15 分钟后从数据库中删除具有该唯一 ID 的用户。 付款后,用户被重定向到http://example.com/success,那个地方你需要做上面的事情。重定向通常是对http://example.com/success 的post 请求,需要在您的后端节点服务器中拦截。然后,您必须重定向到用户可以查看详细信息的新 url。您不能直接在屏幕上加载http://example.com/successhttp://example.com/success 是一个 url,支付服务器在付款后会向其发送详细信息。所以,你需要在服务器中处理它。 例如,尝试以下方法(选项 4 方法 - 在 4.1 之前):我猜您的节点服务器在 http://localhost:8080/ 上运行。从上面添加带有日志的app.post("/unique-success-url", function(req, res)... 代码,并在您的配置中将http://example.com/success 更改为http://localhost:8080/unique-success-url 以获取成功回调,取消也相同。尝试付款,您应该能够在节点服务器中看到参数和其他详细信息。我会看看,如果我能找到一些能让你更清楚的流程图。 谢谢你!我没有从树上看到森林。我一直在使用错误的回调 URL-s。而不是https://example.com/api/success(首先在我的后端创建)我使用https://example.com/success(来自网站的URL),因此我无法看到任何响应。

以上是关于nodejs post请求 怎么用url的主要内容,如果未能解决你的问题,请参考以下文章

nodejs中发送https请求怎么设置请求头

nodejs 怎么获取post请求的json数据

scrapy怎么post 请求payload形式的参数的实现

nodejs之get/post请求的几种方式

nodejs express怎么获取到前端以post请求的Ajax请求信息,请求信息是JSON对象

nodejs post 请求soap 报错.大神求助