Angular 6 使用 POST 重定向到外部 url

Sai*_*aif 9 angular-http angular angular-httpclient

我正在尝试将支付网关合并到 angular 应用程序中,我发现以下付款合作伙伴提供的用于合并的 JavaScript 片段,我通过添加ngNoForm 对其进行了调整,并使其与 angular 一起使用;堆栈闪电战

<form ngNoForm method="post" action="https://test.pesopay.com/b2cDemo/eng/payment/payForm.jsp">
<input type="hidden" name="amount" value="1" >
<input type="hidden" name="currCode" value="608" >
<input type="hidden" name="payMethod" value="CC">
<input type="submit" name="submit">
</form>
Run Code Online (Sandbox Code Playgroud)

接下来不是<Form> POST + Action直接从组件模板使用 HTML ,我想对我的后端服务器进行 REST 调用,执行其他一些步骤,并将该 API 响应映射到我的支付合作伙伴期望的内容,然后使用 HttpClient POST 重定向到我的支付合作伙伴,这将应该做同样的事情并重定向到应该负责支付过程的支付合作伙伴网站,所以简而言之,我想以编程方式实现同​​样的事情,我尝试过:

redirectToPaymentHandler(): Observable<any> {
  const urlEncodeData = 'amount=1&currCode=608&payMethod=CC';
  let headers = new HttpHeaders();
  headers = headers.append('Content-Type', 'application/x-www-form-urlencoded');
  headers = headers.append('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8');

  return this.httpClient.post('https://test.pesopay.com/b2cDemo/eng/payment/payForm.jsp',
    urlEncodeData, {
      headers,
      responseType: 'text'
    }).pipe(catchError((error) => {
      console.log(error)
      return EMPTY;
    }));
}
Run Code Online (Sandbox Code Playgroud)

最初我遇到了 CORS 问题,但我能够使用 Angular CLI 的代理配置绕过该问题,现在发生的情况是,HttpClient 的 POST 方法实际上将网页作为来自服务端点的字符串返回,而不是重定向到支付合作伙伴的网站,不是我认为它会做的,

请参阅此stackBlitz以进一步了解。

所以总而言之,基本上我正在寻求将上述工作模板驱动的 POST 请求转换为程序化版本。所以我可以先执行一些操作,然后使用 POST 重定向到外部 URL。我相信我以编程方式尝试的可能与针对 Html 发生的不同<form> POST + Action。必须有一些程序上的等价物。

PS:我确实发现了这个类似的问题,但遗憾的是它没有有效的答案。

PSS:我不能使用window.location.hrefRouterLink因为它应该是 POST 并且应该有诸如金额、货币和其他信息之类的信息要一起传递给支付合作伙伴。

小智 1

最初我认为这行不通,但经过整整一周的研究和反复试验后。它对我使用 Angular 6 来说工作得很好。你可能可以使用 javascript 或任何其他你想要的语言。基本上,您必须遵循 2 个步骤:

1) 调用登录表单重定向时,必须设置respontType=text,这样 HttpClient 就不会抛出需要 JSON 数据的错误。

return  this.http.post(this.HOST_URL+'login' ,params1.toString(), 
{
    headers:  headers,
    withCredentials: true,
    observe: 'response',
    params: params1,
    responseType: 'text',
    reportProgress: true
})
Run Code Online (Sandbox Code Playgroud)

2) 设置拦截器来拦截您的子序列 API 请求(假设端点现在将返回 json)。在拦截器中,传递 withCredentials=true。在 Javascript 或 Curl 中,您希望从登录成功中检索该信息,并通过 API 请求发回JSESSIONID 。在 Angular 中,您只需要 在拦截器中使用withCredentials=true 即可。*注意:在发出请求之前,您不能在 HttpHeaders 中传递此信息。请参阅此处的错误报告

这是我的拦截器代码片段:

@Injectable()
export class WithCredentialsInterceptor implements HttpInterceptor {

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log("Intercepting Request withCredentials=true ");
        request = request.clone({
            withCredentials: true
        });

        return next.handle(request);
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助。