一、首次加载自动登录
- 问题分析
Rn webview有自动登录机制,即如果是需要登录的页面,在首次登录后,二次进入不需登录。但第一次进入页面必须要进行密码输入和登录操作。所以,如果要实现首次自动登录,必须要在webview加载之前进行手动登录操作。
- 解决
利用RN webview的handleWebViewNavigationStateChange和injectedJavaScript等api进行操作:
webview:
1 2 3 4 5
| <WebView ref={ref => (this.webview = ref)} onNavigationStateChange={this.handleWebViewNavigationStateChange} source={{ uri: this.state.source }} />
|
handleWebViewNavigationStateChange:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| let a = false;
handleWebViewNavigationStateChange = newNavState => { const { url } = newNavState;
if (url.includes(xxxx) && !a) { fetch( URL , { credentials: 'same-origin', method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(BODY) }).catch( err => { throw err; } ).then( resp => { let newURL = "xxxxx" let redirectTo = 'window.location = "' + newURL + '"'; this.webview.injectJavaScript(redirectTo); } ); a = true; } };
|
webview通过injectJavaScript注入代码到pc端,进行手动跳转操作,即可达到自动登录效果。
二、webview定时自动登录
HTML设定距离最后一次操作的8小时内若无任何用户操作,即会注销用户,提示超时信息。
所以设定每7小时自动登录一次,即可避免页面超时。
handleWebViewNavigationStateChange:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| handleWebViewNavigationStateChange = newNavState => { console.log(newNavState) const { url } = newNavState; var _this = this; if (url.includes('dom') && !a) { this.setState({ firstLogin: true })
this.autoLogin(_this);
setInterval(() => { this.autoLogin(_this) }, 1000*60*60*7) a = true; } };
|
autoLogin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| autoLogin(_this) { fetch('http://dom.inwhile.com/api/login/2', { credentials: 'same-origin', method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({"name": 'dev@basdom.com', "pwd": "Abcd12345"}) }).catch( err => { throw err; } ).then( resp => { let newURL = 'http://dom.inwhile.com/app/observer/' + this.state.itemId + '/' + this.state.name_en + '/' + this.state.newId + '/' + this.state.page_Id; if( this.state.page_Id !== '' ) { this.setState({ source: newURL, firstLogin: false }); let redirectTo = 'window.location = "' + newURL + '"'; this.webview.injectJavaScript(redirectTo); } } ); }
|
补充:
原本的解决方法(太过鸡肋。。。)如下:
webview过期后自动登录:
当webview加载的网页过期后,HTML端可能会弹出(alert)警告窗口,并跳转到登录页。因此,过期后自动登录的实现需要解决三个问题:获取网页端过期的时间节点提醒、再次自动登录和取消alert提醒(屏蔽弹出框)。
- 获取HTML过期提醒
HTML需向RN传递消息:
1 2 3
| window.postMessage(JSON.stringify({ msg: "out of date!" }))
|
RN接收消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| onMessage = event => {
const action = JSON.parse(event.nativeEvent.data)
if (action.msg == "out of date") {
const spamAlertScript = ` alert = function(str) { return; //什么事也不做,等于屏蔽了它 } alert( "已经无效! "); ` this.webview.injectJavaScript(spamAlertScript);
setTimeout(() => { this.autoLogin(); }, 500); } } }
|