PhoneGap redirect management

Author: Eugeniy Marilev
Date of publication: 2014-05-06 10:27:57
"No way! I can not believe my eyes!" - are my first words I said after I had found out that PhoneGap uses any «redirect», except for the start-domain, opens the link in the default browser ... I tried various options:
location = "some.domail.com";
window.location = "some.domail.com";
window.location.href = "some.domail.com";
Unfortunately, everything was useless, since I thought there was something extra special to do about it, noting as usual as in javascript. It turns out that the problem lies in the fact that PhoneGap does not trust a third-party domains. This protection may be needed in the following situation - when the users of the system are placing links to their resources in their comments. It does make sense not to open third-party links within the current application window, otherwise the user gets the impression that he works with a regular browser instead of the native-application. But the situation I got in did not match any of the above case. I had to make the authentication of the application using Facebook oAuth. It was quite logical that the application made the redirection to the log-in form on Facebook, and then a couple of other redirects ... and as a result got to the main page of the application. Later, of course, an option of authentication with help of redirect in the main window was successfully replaced using a similar mechanism, but within a pop-up dialogue PhoneGap. The latest version of PhoneGap, the actual full implementation of this mechanism will be in the future, there was an option of solving this problem - While list. As far as I know, this solution works only with IOS and Windows Phone 7. Therefore, it is safe to forget the presence of such a functional, because the main problem - the problem of cross-platform - will not be solved. Who is curious to try White list - read here. I suggest an alternative approach, which is certainly more flexible than the standard one. To redefine the default mechanism for handling redirect for our application we will need to redefine a method shouldOverrideUrlLoading - for Android, shouldStartLoadWithRequest - for the IPhone. Solution for Windows Phone — you will find yourself (that's your homework). And here are some examples:

Management of Android's redirect

package com.myapp;
 
import java.net.MalformedURLException;
 
import com.phonegap.*;
import android.webkit.*;
 
public class MyDroidGap extends DroidGap
{
    /**
     * Create and initialize web container.
     */
    public void init()
    {
        super.init();
        this.setWebViewClient(this.appView, new My GapViewClient(this));
    }
 
    /**
     * The webview client receives notifications about appView
     */
    public class MyGapViewClient extends GapViewClient
    {
        /**
         * Application's URL loading schema 
         */
        final UrlLoadingSchema urlSchema;
 
        /**
         * Constructor.
         * 
         * @param ctx
         */
        public MyGapViewClient(DroidGap ctx)
        {
            super(ctx);
            urlSchema = new UrlLoadingSchema();
        }
 
        /**
         * Give the host application a chance to take over the control when a new url 
         * is about to be loaded in the current WebView.
         * 
         * @param view          The WebView that is initiating the callback.
         * @param url           The url to be loaded.
         * @return              true to override, false for default behavior
         */
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
             try {
                 if (this.urlSchema.isInternalUrl(url)) {
                     view.loadUrl(url);
                     return true;
                 } else {
                     return super.shouldOverrideUrlLoading(view, url);
                 }
             } catch (MalformedURLException e) {
                 e.printStackTrace();
             } catch (Exception e) {
                 e.printStackTrace();
             }
             return super.shouldOverrideUrlLoading(view, url);
        }
    }
}
Next step is to inherit the main activity of application from the class MyGroidGap.

Management of iPhone's redirect

//
//  AppDelegate.m
//  My application
//
//  Created by Evgeniy Marilev on 10.09.11.
//  Copyright __MyCompanyName__ 2011. All rights reserved.
//
 
#import "AppDelegate.h"
#ifdef PHONEGAP_FRAMEWORK
        #import 
#else
        #import "PhoneGapViewController.h"
#endif
 
#import "UrlLoadingSchema.h"
 
@implementation AppDelegate
 
@synthesize invokeString;
@synthesize loadingSchema;
 
- (id) init
{
    self.loadingSchema = [[UrlLoadingSchema alloc] init];
    return [super init];
}
 
//.....
 
/**
 * Start Loading Request
 * This is where most of the magic happens... We take the request(s) and process the response.
 * From here we can re direct links and other protocalls to different internal methods.
 */
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *url = [request URL];
    if ([self.loadingSchema isInternalUrl: url]) {
        return YES;
    } else {
        return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
    }
}
 
//.....
 
- (void)dealloc
{
        [loadingSchema release];
        [ super dealloc ];
}
 
@end

About the design of redirect's policies in general

In the examples given above, appears a certain class of «UrlLoadingSchema». If you think that this is a standard class - you are wrong. «UrlLoadingSchema» - the most common class with one public-method «isInternalUrl». The use of just such a title, and, in general, in this situation, a special class may seem unnecessary - it's just my advice ... And how to implement a redefining - you are to decide. The main thing is that redefined methods return TRUE, when the address can be loaded from the main webView application, and otherwise - return FALSE. You can go further and identify a mechanism of the White list based on the redefining methods mentioned above, and do not handle the forbidden URL under any circumstances, but simply to give an error message. In the conclusion, not always, but it happens that even a perfectly designed system does not provide a solution to your problem situations, in this case, you must be patient, armed with Google and sources, and insert "a couple of lines of code" in the right place and you can move on ...
Article comments
Comments:
Александр
20\03\2012
Прошу прощения за некоторую неграмотность, но, можно показать на конкретном примере как это реализовать? Куда прописывается super.loadUrl("file:///android_asset/www/myLocalFile.html"); и как в приложении переходить по ссылкам ?
djvibegga_admin
25\03\2012
Вызов
super.loadUrl(«file:///android_asset/www/myLocalFile.html»
нужно выполнять в главной activity (активности) приложения. Подробный пример описан на официальном сайте phonegap. Вариант для android смотри здесь.
Only logged users can leave comments.