ios与andriod中webview网页js用户登录状态同步方案

ios与andriod中webview网页js用户登录状态同步方案

ios与andriod中webview网页js用户登录状态同步方案

在app开发过程中,我们会将一些活动营销页面使用h5来制作,然后采用ios与andriod的app中的webview中进行加载,但是现在有个问题,h5页面中如何读取用户的登录状态

有几种方案可以解决

一、js调用原生接口

这种方式很简单,原生app本身有一套机制存储用户的登录状态信息,只要通过webview开放一个接口给h5页面进行js调用即可

假设这个js方法叫getuseinfo

那么我们先看看ios怎么设置这个接口,在iOS 7之后,apple添加了一个新的库JavaScriptCore,用来做JS交互,因此JS与原生OC交互也变得简单了许多。

JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

//再然后定义好JS需要调用的方法,例如JS要调用getuserinfo方法:

//则可以在UIWebView加载url完成后,在其代理方法中添加要调用的getuserinfo方法:

- (void)webViewDidFinishLoad:(UIWebView *)webView

{

    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    //定义好JS要调用的方法, getuserinfo就是调用的getuseinfo方法名

    context[@"getuserinfo"] = ^() {

        NSLog(@"+++++++Begin Log+++++++");

        NSArray *args = [JSContext currentArguments];

        for (JSValue *jsVal in args) {

            NSLog(@"%@", jsVal.toString);//打印js传的参数

        }
        JSValue *this=[JSContect currentThis]
        NSLog(@"-------End Log-------");
        return @"123";//返回用户id给js
    };

}

再看看andriod如何设置这个接口

 protected void onCteate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        WebView webview;
        webview= (WebView)findViewById(R.id.webView);
        webview.getSettings().setJavaScriptEnabled(true);

        webview.loadUrl("http://www.bfw.wiki/index.html");

        webview.addJavascriptInterface(new WebAppInterface(this), "Bfw");
    }
    public class WebAppInterface {
        Context mContext;


        WebAppInterface(Context c) {
            mContext = c;
        }

        //定义js要访问的函数
        @JavascriptInterface
        public String getuserinfo() {
           return "123";//返回用户的信息
        }
    }

好了,最后一步,在html中直接调用app的接口,这里要区分一下ios与Android

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>BFW NEW PAGE</title>
    <script id="bfwone" data="dep=jquery.17&err=0" type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/bfwone.js"></script>
    <script type="text/javascript">
        function getuser() {
            //判断webview类型
            var u = navigator.userAgent;
            var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
            var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端

            if (isAndroid) {
                return Bfw.getuserinfo();
            }
            if (isiOS) {
                return getuserinfo();
            }
            return "";
        }

    </script>
</head>
<body>
    <buttonBfwOnclick="getuser();">获取用户信息</button>
</body>
</html>

二、原生app修改webview中header或COOKIE的token

这种方式就是讲app中的通讯token拿出来与h5共享,这种方案h5不需要进行任何修改,只需要app端在webview调用前将token等信息插入到webview请求的header中或COOKIE里

我们先看ios

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColorFromRGB(0xf3f6f6);
    //添加登陆通知,防止APP端未登陆状态,在后面的代理对h5登陆做拦截处理,回调原生APP的登陆方式,
    //然后通过通知方式来重载本页面
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(uerislogin) name:@"userIsLogin" object:nil];
    JMUserInfoModel *userInfo = [JMLoginManager getInfo];//这是我的本地登陆信息
    
    //进行偏好设置,把token传到session里面去。
    WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc] init];
    _userContent = [[WKUserContentController alloc] init];
    
    //关键的地方来了,这一步是对session添加token信息,就算目前APP未登陆状态,传入空字符串也是没关系,
    //后面通知重载页面会重新注入信息。
    NSString * js = [NSString stringWithFormat:@"window.sessionStorage.setItem('token','%@')",userInfo.user_token];
    WKUserScript * userScript = [[WKUserScript alloc]initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [_userContent addUserScript:userScript];
    configuration.userContentController = _userContent;
    
    
    //注意要在创建webview的时候就要把偏好设置给初始化configuration
    _webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, DEVICE_WIDTH, DEVICE_HEIGHT- JMHeightGap) configuration:configuration];
    _webView.backgroundColor = [UIColor whiteColor];
    _webView.UIDelegate = self;
    _webView.navigationDelegate = self;
    [_webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL]; //添加观察者模式 更换标题
    
    NSString *url = [NSString stringWithFormat:@"https://www.jumifinance.com/h5/views/wheel/wheel.html"];
    NSURL *weburl =[[NSURL alloc] initWithString:url];
    NSURLRequest *request =  [[NSURLRequest alloc] initWithURL:weburl];
    [self.webView loadRequest:request];
    
    [self.view addSubview:self.webView];
}

ok,然后我们在看看andriod

    public void initView() {
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        url = (String) extras.get("url");
        WebSettings webSettings = web.getSettings();
        webSettings.setJavaScriptEnabled(true);
        COOKIEManager COOKIEManager=COOKIEManager.getInstance();
        COOKIEManager.setAcceptCOOKIE(true);
        StringBuilder sbCOOKIE = new StringBuilder();
        String token=UserInfo.getToken();//获取本地token
        sbCOOKIE.append("token=" + token);//凭借token
        String COOKIEValue = sbCOOKIE.toString();
        COOKIEManager.setCOOKIE(url, COOKIEValue);//为url设置COOKIE
        COOKIESyncManager.getInstance().sync();//同步COOKIE
        String newCOOKIE = COOKIEManager.getCOOKIE(url);
        web.loadUrl(url);

    }

ok,这样就实现了app与h5共享登录状态了

{{collectdata}}

网友评论0