在Ionic(科尔多瓦)的新窗口/ inAppBrowser中发布表单

时间:2022-10-18 23:00:44

I want to submit a checkout form to an external url, that should open a new window with the result, but I can't make my app to open it nor in a separate window, nor using the in app browser.

我想向外部网址提交一个结帐表单,该表单应该打开一个包含结果的新窗口,但我无法让我的应用程序打开它,也不能在单独的窗口中打开,也不能使用应用程序内浏览器。

What I've done until now is to create a directive with the form inside, and from linker function, call the submit element at some point.

到目前为止我所做的是创建一个带有表单内部的指令,并从链接器函数中调用submit元素。

When I'm running in browser, this opens a new window (like I want). The problem appears when running on device, because it just REPLACES the content of my view with the new content WITHOUT OPENING an external window.

当我在浏览器中运行时,这会打开一个新窗口(就像我想要的那样)。在设备上运行时会出现问题,因为它只是在没有打开外部窗口的情况下用新内容替换我的视图内容。

So, the question is... when running on device, how can I post this form opening a new window (navigator) or in-app-browser, and show there the results?

所以,问题是......在设备上运行时,如何发布此窗体打开一个新窗口(导航器)或应用内浏览器,并显示结果?

Thanks!!

谢谢!!

1 个解决方案

#1


4  

Well, it has been complex to figure it out, but at the end the solution is "quite" simple. I'll post it here to help any other people facing the same problem. If anyone has a more elegant solution, it will be welcomed.

好吧,弄清楚它是很复杂的,但最后解决方案“非常”简单。我会在这里发布,以帮助任何其他人面临同样的问题。如果有人有一个更优雅的解决方案,它将受到欢迎。

What I ended doing is to:

我最后做的是:

  1. Open the new window with my own template with angular and my form.
  2. 使用我自己的带有角度和形状的模板打开新窗口。
  3. In the new window controller, create a callback function in the global window object
  4. 在新窗口控制器中,在全局窗口对象中创建回调函数
  5. From the old window, after the loadstop event, execute that callback
  6. 在旧窗口中,在loadstop事件之后,执行该回调
  7. The posted form in the new window, redirects to the destination page (that is what I wanted to).
  8. 新窗口中的已发布表单会重定向到目标页面(这就是我想要的)。

Here's the code (Observe that I'm using a directive with the form, so I can control when to submit it, from link function, and that data is shared with the directive through a service) :

这是代码(观察我正在使用带有表单的指令,因此我可以控制何时提交它,来自链接功能,并且该数据通过服务与指令共享):

angular.module('starter', ['ionic'])


.constant('cartData', {
        redirectUrl: 'https://test.mycart.com/hpp/pay.shtml',
        redirectMethod: 'POST',
        redirectData: {
                'formParam1': 'value1',
                'formPara2': 'value2'
            }
    }
)


.controller('InitCtrl', function($cordovaInAppBrowser, $scope, cartData) {
     
    $scope.openView = function(){
    
        var counter = 0;
        if(ionic.Platform.isWebView()){

            $ionicPlatform.ready(function() {                    
                //this is the cordova in app web view
                var ref = $cordovaInAppBrowser.open('payment.html', '_blank', {location:'yes'});

                $rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event){
                    if(counter < 1){
                        //prevent the callback to be called several times
                        $cordovaInAppBrowser.executeScript({
                            code: 'window.paymentCallback('+ angular.toJson(cartData) +');'
                        });
                        counter++;
                    }
                });
            });
        }
    };
    
})




//and then in payment.js


window.paymentCallback = null;

angular.module('payment', [])


.directive('autoSubmitForm', ['$timeout', 'autoSubmitFormDelegate', function($timeout, autoSubmitFormDelegate) {
    return {
        replace: true,
        scope: {},
        template: '<form action="{{formData.redirectUrl}}" method="{{formData.redirectMethod}}">'+
                      '<div ng-repeat="(key,val) in formData.redirectData">'+
                           '<input type="hidden" name="{{key}}" value="{{val}}" />'+
                      '</div>'+
                  '</form>',
        link: function($scope, element, $attrs) {
            
            autoSubmitFormDelegate.submitCallback = function(data) {
                $scope.formData = data;
                $timeout(function() {
                    element[0].submit();
                });
             };
        }
    }
}])

.factory('autoSubmitFormDelegate', function(){
    var delegate = {};
    
    delegate.submitCallback = null;
    
    delegate.submitForm = function(data){
        if(delegate.submitCallback){
            delegate.submitCallback(data);
        }
    }
    
    return delegate;
})

.controller('PaymentCtrl', function($scope, $timeout, $window, $sce, autoSubmitFormDelegate){


    $window.paymentCallback = function(data){
        console.log("callback called");
        data.redirectUrl = $sce.trustAsResourceUrl(data.redirectUrl);    
        $timeout(function(){
            autoSubmitFormDelegate.submitForm(data);
        });
    };
    
})
<link href="http://code.ionicframework.com/1.1.1/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.1.1/js/ionic.bundle.min.js"></script>


<body ng-app="starter">

  <ion-view view-title="Init">
  <ion-content>
    <h1>Init</h1>
      <button class="button button-positive" ng-click="openView()">Open new view</button>
  </ion-content>
</ion-view>
  
</body>



<script type="text/ng-template" id="payment.html">

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
    <title></title>

    <script src="../lib/angular/angular.min.js"></script>
    <script src="../js/payment.js"></script>
  </head>

  <body ng-app="payment" ng-controller="PaymentCtrl">
    <auto-submit-form></auto-submit-form>
  </body>
</html>

</script>

#1


4  

Well, it has been complex to figure it out, but at the end the solution is "quite" simple. I'll post it here to help any other people facing the same problem. If anyone has a more elegant solution, it will be welcomed.

好吧,弄清楚它是很复杂的,但最后解决方案“非常”简单。我会在这里发布,以帮助任何其他人面临同样的问题。如果有人有一个更优雅的解决方案,它将受到欢迎。

What I ended doing is to:

我最后做的是:

  1. Open the new window with my own template with angular and my form.
  2. 使用我自己的带有角度和形状的模板打开新窗口。
  3. In the new window controller, create a callback function in the global window object
  4. 在新窗口控制器中,在全局窗口对象中创建回调函数
  5. From the old window, after the loadstop event, execute that callback
  6. 在旧窗口中,在loadstop事件之后,执行该回调
  7. The posted form in the new window, redirects to the destination page (that is what I wanted to).
  8. 新窗口中的已发布表单会重定向到目标页面(这就是我想要的)。

Here's the code (Observe that I'm using a directive with the form, so I can control when to submit it, from link function, and that data is shared with the directive through a service) :

这是代码(观察我正在使用带有表单的指令,因此我可以控制何时提交它,来自链接功能,并且该数据通过服务与指令共享):

angular.module('starter', ['ionic'])


.constant('cartData', {
        redirectUrl: 'https://test.mycart.com/hpp/pay.shtml',
        redirectMethod: 'POST',
        redirectData: {
                'formParam1': 'value1',
                'formPara2': 'value2'
            }
    }
)


.controller('InitCtrl', function($cordovaInAppBrowser, $scope, cartData) {
     
    $scope.openView = function(){
    
        var counter = 0;
        if(ionic.Platform.isWebView()){

            $ionicPlatform.ready(function() {                    
                //this is the cordova in app web view
                var ref = $cordovaInAppBrowser.open('payment.html', '_blank', {location:'yes'});

                $rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event){
                    if(counter < 1){
                        //prevent the callback to be called several times
                        $cordovaInAppBrowser.executeScript({
                            code: 'window.paymentCallback('+ angular.toJson(cartData) +');'
                        });
                        counter++;
                    }
                });
            });
        }
    };
    
})




//and then in payment.js


window.paymentCallback = null;

angular.module('payment', [])


.directive('autoSubmitForm', ['$timeout', 'autoSubmitFormDelegate', function($timeout, autoSubmitFormDelegate) {
    return {
        replace: true,
        scope: {},
        template: '<form action="{{formData.redirectUrl}}" method="{{formData.redirectMethod}}">'+
                      '<div ng-repeat="(key,val) in formData.redirectData">'+
                           '<input type="hidden" name="{{key}}" value="{{val}}" />'+
                      '</div>'+
                  '</form>',
        link: function($scope, element, $attrs) {
            
            autoSubmitFormDelegate.submitCallback = function(data) {
                $scope.formData = data;
                $timeout(function() {
                    element[0].submit();
                });
             };
        }
    }
}])

.factory('autoSubmitFormDelegate', function(){
    var delegate = {};
    
    delegate.submitCallback = null;
    
    delegate.submitForm = function(data){
        if(delegate.submitCallback){
            delegate.submitCallback(data);
        }
    }
    
    return delegate;
})

.controller('PaymentCtrl', function($scope, $timeout, $window, $sce, autoSubmitFormDelegate){


    $window.paymentCallback = function(data){
        console.log("callback called");
        data.redirectUrl = $sce.trustAsResourceUrl(data.redirectUrl);    
        $timeout(function(){
            autoSubmitFormDelegate.submitForm(data);
        });
    };
    
})
<link href="http://code.ionicframework.com/1.1.1/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.1.1/js/ionic.bundle.min.js"></script>


<body ng-app="starter">

  <ion-view view-title="Init">
  <ion-content>
    <h1>Init</h1>
      <button class="button button-positive" ng-click="openView()">Open new view</button>
  </ion-content>
</ion-view>
  
</body>



<script type="text/ng-template" id="payment.html">

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
    <title></title>

    <script src="../lib/angular/angular.min.js"></script>
    <script src="../js/payment.js"></script>
  </head>

  <body ng-app="payment" ng-controller="PaymentCtrl">
    <auto-submit-form></auto-submit-form>
  </body>
</html>

</script>