从 Angular 4 应用程序向 Paypal Payflow API 发布请求时,控制台日志中出现 Access-Control-Allow-Origin 错误

Posted

技术标签:

【中文标题】从 Angular 4 应用程序向 Paypal Payflow API 发布请求时,控制台日志中出现 Access-Control-Allow-Origin 错误【英文标题】:Getting Access-Control-Allow-Origin error in console log when posting request to Paypal Payflow API from an Angular 4 application 【发布时间】:2019-02-04 19:46:22 【问题描述】:

我正在 Angular 4 应用程序中实现信用卡支付组件,该应用程序使用 Paypal Payflow API 来处理信用卡支付。我已经在 Paypal Manager 中创建了测试和生产帐户(这些凭据必须在请求中发送到 Payflow API)。

根据 Payflow 文档,这是一个非常基本的示例,展示了如何向 Payflow API 发布请求:

curl https://pilot-payflowpro.paypal.com \
  -s \
  --insecure \
  -d PARTNER=PayPal \
  -d PWD=MyPassword \
  -d VENDOR=MyMerchantID \
  -d USER=MyMerchantID \
  -d TENDER=C \
  -d ACCT=5105105105105100 \
  -d TRXTYPE=S \
  -d EXPDATE=1221 \
  -d AMT=1.00

由于我正在开发 Angular 应用程序,因此我使用 HttpClient 库向 Payflow API 发出发布请求。

为了发布测试交易,我使用 Postman。在 Postman 上,我向 https://pilot-payflowpro.paypal.com 执行 POST 请求,并在请求正文中发送类似于以下字符串的内容:

USER=MyUser&PARTNER=PayPal&VENDOR=MyVendor&PWD=MyPassword&ACCT=4012888888881881&EXPDATE=102020&TENDER=C&TRXTYPE=A&AMT=100&VERBOSITY=HIGH

一旦我在 Postman 中执行该请求,它就可以正常工作,并且服务器返回预期的字符串响应,这是一个类似于下面的字符串:

RESULT=0&SECURETOKEN=7mHAFU7JlLEGhzUHy7VD4rQL2&SECURETOKENID=123456789123456789123456789123456781&RESPMSG=Approved

现在,我实现了一个 Angular 4 应用程序,它使用 HttpClient Angular 库来执行后期事务;请求类似于下面的代码:

private requestPayflowPaymentToPayflowGatewayApi( requestString: string ): Observable<string> 
      const headers: Headers = 
      new Headers(  'Content-Type': 'text/plain');
      const serverUrl = 'https://pilot-payflowpro.paypal.com';
      const body = 'USER=gtcdevelopment&PARTNER=PayPal&VENDOR=gtcdevelopment&PWD=k4l1m4nt4n&ACCT=5105105105105100&EXPDATE=102020&TENDER=C&TRXTYPE=A&AMT=100&VERBOSITY=HIGH&';

      return this.oldHttp.post(serverUrl, body, headers: headers, responseType: ResponseContentType.Text ).catch( ( error ) => 
      console.log('error in requestPayflowPaymentToPayflowGatewayApi');
      console.error(error);
      return Observable.throw(error);
     );
  

这只是一个基本的post请求,但是当我在浏览器中执行应用程序时它不起作用;我在控制台日志中收到以下错误:

在可观察代码(post() 方法)的 .catch() 部分中捕获了错误。

  
   "_body":  
      "isTrusted":true
   ,
   "status":0,
   "ok":false,
   "statusText":"",
   "headers":  

   ,
   "type":3,
   "url":null

以下是我的控制台日志的一些捕获:

现在,它确实有些奇怪;当我在谷歌浏览器中禁用网络安全时,我通过在 Windows 中运行以下命令打开谷歌浏览器,应用程序运行良好,执行对服务器的请求并返回预期的响应。

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

当我使用生产数据(指向https://payflowpro.paypal.com 的生产 Paypal 经理帐户)发布请求时,我遇到了同样的问题

有人遇到过这个问题吗?您认为这可能是这里的问题吗?

【问题讨论】:

【参考方案1】:

您似乎遇到了 CORS(跨域资源共享)错误。 基本上,您的 Web 浏览器(所有 Web 浏览器)不会向不是您的页面/应用程序最初来自的服务器的服务器(“源”)发送请求,除非目标服务器表示可以这样做。

有关此机制的详细信息,请参阅我之前对一个相关但略有不同的问题的回答:Response for preflight does not have HTTP ok status in angular

我不熟悉 PayPal 的 API,但要使这项工作正常进行,PayPal 的服务器必须响应您的请求(实际上是浏览器的 OPTION 请求),并带有一个标头,告诉您的浏览器可以实际发送真实的请求。

当您在 Chrome 中使用 --disable-web-security 选项时,您将关闭此 CORS 进程,因此 API 可以正常工作 - 一个非常糟糕的主意。

当您使用 curl 时,您同样不涉及浏览器的 CORS 保护,并且 API 可以正常工作。

如果没有办法让 API 返回正确的标头以便请求从基于浏览器的 Angular 客户端工作,那么我知道的唯一选择是设置您自己的服务器端进程(在与您的 Angular 应用程序提供服务的域/端口相同)代理来自浏览器的请求。

【讨论】:

您好,感谢您的回复!我很确定您是对的,因为当我发布没有任何标头的请求时,我还在控制台日志中看到以下消息: 无法加载 pilot-payflowpro.paypal.com: No 'Access-Control-Allow-Origin' header is出现在请求的资源上。因此不允许访问 Origin 'localhost:4200'。

以上是关于从 Angular 4 应用程序向 Paypal Payflow API 发布请求时,控制台日志中出现 Access-Control-Allow-Origin 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何从控制器向 PayPal 发送数据?

如何从 iOS 应用程序内的单个企业帐户向多个 paypal 或 venmo 或支票帐户付款

我可以使用 Paypal API 从一个用户直接向另一个用户汇款吗?

带有 Angular 应用程序的 Paypal 返回网址

使用braintree PayPal Dropin的Angular不会触发提交事件

从 PHP 表单向 PayPal 提交订阅请求