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

时间:2018-11-25 21:20:35

标签: angular angular-http angular-httpclient

我正在尝试将付款网关合并到angular应用程序中,我发现遵循付款合作伙伴提供的用于合并的JavaScript代码段,我通过添加ngNoForm对其进行了调整并使其可以与angular一起使用; stackBlitz

<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>

接下来,我不想直接从组件模板中使用HTML <Form> POST + Action,而是想对我的后端服务器进行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;
    }));
}

最初我遇到了CORS问题,但是我可以使用Angular CLI的代理配置来绕过它,现在发生的是,HttpClient的POST方法实际上不是重定向到付款伙伴的网站,而是将网页作为字符串返回,但我不是这样做的,

请进一步参考此stackBlitz,以供进一步了解。

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

PS :我确实发现了this个类似的问题,但可惜没有有效的答案。

PSS :我不能使用window.location.hrefRouterLink作为其应为POST,并且应该传递诸如金额,货币和其他内容之类的信息旁边的付款伙伴。

3 个答案:

答案 0 :(得分:0)

最初,我不认为这会行得通,但是花了整整一周的时间进行研究和反复试验。使用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
})

2)设置一个拦截器以拦截您的子序列API请求(假设端点现在将返回json)。在拦截器中,传递 withCredentials = true 。在Javascript或Curl中,您希望能够从登录成功检索到该信息,然后将 JSESSIONID 发送回API请求。在Angular中,您仅需要拦截器中的 withCredentials = true 。 *注意:您不能在发出请求之前将其传递到HttpHeaders中。参见bug report here

这是我的拦截器代码段:

@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);
    }
}

希望这会有所帮助。

答案 1 :(得分:0)

const mapForm = document.createElement('form');
mapForm.method = 'POST';
mapForm.action = `${b2pApiUrl}/Purchase`;
mapForm.style.display = 'none';

const mapInput = document.createElement('input');
mapInput.type = 'hidden';
mapInput.name = 'param1';
mapInput.value = param1;
mapForm.appendChild(mapInput);

const mapInput1 = document.createElement('input');
mapInput1.type = 'hidden';
mapInput1.name = 'param2';
mapInput1.value = param2;
mapForm.appendChild(mapInput1);
....
document.body.appendChild(mapForm);

mapForm.submit();

答案 2 :(得分:0)

鉴于这种情况,我们可以通过使用普通JavaScript而不是HttpClient提交动态创建的表单来实现所需的输出。 当我们使用HttpClient时,重定向发生在网络中,而不是在客户端浏览器中。这是我的解决方法

const myform = document.createElement('form');
myform.method = 'POST';
myform.action = "https://test.pesopay.com/b2cDemo/eng/payment/payForm.jsp";
myform.style.display = 'none';
myform.append('Content-Type', 'application/x-www-form-urlencoded');
myform.append('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8');
document.body.appendChild(myform);
myform.submit();