如何在 react-native-webview 中保持最后一个网络会话活跃?
How to keep last web session active in react-native-webview?
我正在开发一个应用程序,我需要让用户在 react-native-webview
.
中保持上次网络会话活跃
这是一个必需的工作流程。
我的应用只有一个WebView,固定的url正在加载。
用户将打开应用程序并登录该网站。
当用户关闭应用程序并再次打开它时,我需要让该用户保持登录状态,因为他已经上次登录了。
这是我到目前为止尝试过的:
- 我试过 https://github.com/react-native-community/cookies。到目前为止,我只能通过以下功能保存 cookies :
// 列出 cookie(仅 IOS)
CookieManager.getAll(useWebKit)
.then((res) => {
console.log('CookieManager.getAll from webkit-view =>', res);
});
但是正如建议的那样,它只适用于 iOS。我也无法在 WebView 中打开的网站中设置该 cookie 以保持该会话处于活动状态。
但是我还没有发现任何成功。
任何建议或解决方案将不胜感激。
=======更新=======
对于Android:
它默认工作,
这意味着我们只需要检查 iOS.
其实这个问题存在于react-native-webview
Cookies are lost on iOS after application closing
应该通过本机代码解决。但今天我做了一个解决方案并在 PHP 网站
上进行了测试
完整代码
import React, {Component} from 'react';
import {StyleSheet, SafeAreaView} from 'react-native';
import {WebView} from 'react-native-webview';
import CookieManager from '@react-native-community/cookies';
import AsyncStorage from '@react-native-community/async-storage';
let domain="http://example.com";
export default class App extends Component {
constructor(props) {
super(props);
this.currentUrl = '';
this.myWebView = React.createRef();
this.state = {
isReady: false,
cookiesString: '',
};
}
jsonCookiesToCookieString = (json) => {
let cookiesString = '';
for (let [key, value] of Object.entries(json)) {
cookiesString += `${key}=${value.value}; `;
}
return cookiesString;
};
componentWillMount() {
this.provideMeSavedCookies()
.then(async (savedCookies) => {
let cookiesString = this.jsonCookiesToCookieString(savedCookies);
const PHPSESSID = await AsyncStorage.getItem('PHPSESSID');
if (PHPSESSID) {
cookiesString += `PHPSESSID=${PHPSESSID};`;
}
this.setState({cookiesString, isReady: true});
})
.catch((e) => {
this.setState({isReady: true});
});
}
onLoadEnd = (syntheticEvent) => {
let successUrl = `${domain}/report.php`;
if (this.currentUrl === successUrl) {
CookieManager.getAll(true).then((res) => {
AsyncStorage.setItem('savedCookies', JSON.stringify(res));
if (res.PHPSESSID) {
AsyncStorage.setItem('PHPSESSID', res.PHPSESSID.value);
}
});
}
};
onNavigationStateChange = (navState) => {
this.currentUrl = navState.url;
};
provideMeSavedCookies = async () => {
try {
let value = await AsyncStorage.getItem('savedCookies');
if (value !== null) {
return Promise.resolve(JSON.parse(value));
}
} catch (error) {
return {}
}
};
render() {
const {cookiesString, isReady} = this.state;
if (!isReady) {
return null;
}
return (
<SafeAreaView style={styles.container}>
<WebView
ref={this.myWebView}
source={{
uri: `${domain}`,
headers: {
Cookie: cookiesString,
},
}}
scalesPageToFit
useWebKit
onLoadEnd={this.onLoadEnd}
onNavigationStateChange={this.onNavigationStateChange}
sharedCookiesEnabled
javaScriptEnabled={true}
domStorageEnabled={true}
style={styles.WebViewStyle}
/>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF',
},
WebViewStyle: {
flex: 1,
resizeMode: 'cover',
},
});
详情:
第 1 步:
像这样得到cookies after login and save in AsyncStorage
onNavigationStateChange = (navState) => {
this.currentUrl = navState.url;
};
onLoadEnd = () => {
let successUrl = `${domain}/report.php`;
if (this.currentUrl === successUrl) {
CookieManager.getAll(true).then((res) => {
AsyncStorage.setItem('savedCookies', JSON.stringify(res));
if (res.PHPSESSID) {
AsyncStorage.setItem('PHPSESSID', res.PHPSESSID.value);
}
});
}
};
第 2 步:
启用 sharedCookiesEnabled
props 并在 componentWillMount 中获取保存的 cookie 并通过 jsonCookiesToCookieString
函数使 webview header cookies formate 成为必需的,并通过 isReady
props utils 停止渲染 webview 你得到 cookies
jsonCookiesToCookieString = (json) => {
let cookiesString = '';
for (let [key, value] of Object.entries(json)) {
cookiesString += `${key}=${value.value}; `;
}
return cookiesString;
};
provideMeSavedCookies = async () => {
try {
let value = await AsyncStorage.getItem('savedCookies');
if (value !== null) {
return Promise.resolve(JSON.parse(value));
}
} catch (error) {
return {}
}
};
componentWillMount() {
this.provideMeSavedCookies()
.then(async (savedCookies) => {
let cookiesString = this.jsonCookiesToCookieString(savedCookies);
const PHPSESSID = await AsyncStorage.getItem('PHPSESSID');
if (PHPSESSID) {
cookiesString += `PHPSESSID=${PHPSESSID};`;
}
this.setState({cookiesString, isReady: true});
})
.catch((e) => {
this.setState({isReady: true});
});
}
第 3 步:
在 Webview Header 中传递 cookiesString 并像这样编写渲染函数
render() {
const {cookiesString, isReady} = this.state;
if (!isReady) {
return null;
}
return (
<SafeAreaView style={styles.container}>
<WebView
ref={this.myWebView}
source={{
uri: `${domain}`,
headers: {
Cookie: cookiesString,
},
}}
scalesPageToFit
useWebKit
onLoadEnd={this.onLoadEnd}
onNavigationStateChange={this.onNavigationStateChange}
sharedCookiesEnabled
javaScriptEnabled={true}
domStorageEnabled={true}
style={styles.WebViewStyle}
/>
</SafeAreaView>
);
}
我正在开发一个应用程序,我需要让用户在 react-native-webview
.
这是一个必需的工作流程。
我的应用只有一个WebView,固定的url正在加载。
用户将打开应用程序并登录该网站。
当用户关闭应用程序并再次打开它时,我需要让该用户保持登录状态,因为他已经上次登录了。
这是我到目前为止尝试过的:
- 我试过 https://github.com/react-native-community/cookies。到目前为止,我只能通过以下功能保存 cookies :
// 列出 cookie(仅 IOS)
CookieManager.getAll(useWebKit)
.then((res) => {
console.log('CookieManager.getAll from webkit-view =>', res);
});
但是正如建议的那样,它只适用于 iOS。我也无法在 WebView 中打开的网站中设置该 cookie 以保持该会话处于活动状态。
但是我还没有发现任何成功。
任何建议或解决方案将不胜感激。
=======更新=======
对于Android:
它默认工作, 这意味着我们只需要检查 iOS.
其实这个问题存在于react-native-webview
Cookies are lost on iOS after application closing
应该通过本机代码解决。但今天我做了一个解决方案并在 PHP 网站
上进行了测试完整代码
import React, {Component} from 'react';
import {StyleSheet, SafeAreaView} from 'react-native';
import {WebView} from 'react-native-webview';
import CookieManager from '@react-native-community/cookies';
import AsyncStorage from '@react-native-community/async-storage';
let domain="http://example.com";
export default class App extends Component {
constructor(props) {
super(props);
this.currentUrl = '';
this.myWebView = React.createRef();
this.state = {
isReady: false,
cookiesString: '',
};
}
jsonCookiesToCookieString = (json) => {
let cookiesString = '';
for (let [key, value] of Object.entries(json)) {
cookiesString += `${key}=${value.value}; `;
}
return cookiesString;
};
componentWillMount() {
this.provideMeSavedCookies()
.then(async (savedCookies) => {
let cookiesString = this.jsonCookiesToCookieString(savedCookies);
const PHPSESSID = await AsyncStorage.getItem('PHPSESSID');
if (PHPSESSID) {
cookiesString += `PHPSESSID=${PHPSESSID};`;
}
this.setState({cookiesString, isReady: true});
})
.catch((e) => {
this.setState({isReady: true});
});
}
onLoadEnd = (syntheticEvent) => {
let successUrl = `${domain}/report.php`;
if (this.currentUrl === successUrl) {
CookieManager.getAll(true).then((res) => {
AsyncStorage.setItem('savedCookies', JSON.stringify(res));
if (res.PHPSESSID) {
AsyncStorage.setItem('PHPSESSID', res.PHPSESSID.value);
}
});
}
};
onNavigationStateChange = (navState) => {
this.currentUrl = navState.url;
};
provideMeSavedCookies = async () => {
try {
let value = await AsyncStorage.getItem('savedCookies');
if (value !== null) {
return Promise.resolve(JSON.parse(value));
}
} catch (error) {
return {}
}
};
render() {
const {cookiesString, isReady} = this.state;
if (!isReady) {
return null;
}
return (
<SafeAreaView style={styles.container}>
<WebView
ref={this.myWebView}
source={{
uri: `${domain}`,
headers: {
Cookie: cookiesString,
},
}}
scalesPageToFit
useWebKit
onLoadEnd={this.onLoadEnd}
onNavigationStateChange={this.onNavigationStateChange}
sharedCookiesEnabled
javaScriptEnabled={true}
domStorageEnabled={true}
style={styles.WebViewStyle}
/>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF',
},
WebViewStyle: {
flex: 1,
resizeMode: 'cover',
},
});
详情:
第 1 步:
像这样得到cookies after login and save in AsyncStorage
onNavigationStateChange = (navState) => {
this.currentUrl = navState.url;
};
onLoadEnd = () => {
let successUrl = `${domain}/report.php`;
if (this.currentUrl === successUrl) {
CookieManager.getAll(true).then((res) => {
AsyncStorage.setItem('savedCookies', JSON.stringify(res));
if (res.PHPSESSID) {
AsyncStorage.setItem('PHPSESSID', res.PHPSESSID.value);
}
});
}
};
第 2 步:
启用 sharedCookiesEnabled
props 并在 componentWillMount 中获取保存的 cookie 并通过 jsonCookiesToCookieString
函数使 webview header cookies formate 成为必需的,并通过 isReady
props utils 停止渲染 webview 你得到 cookies
jsonCookiesToCookieString = (json) => {
let cookiesString = '';
for (let [key, value] of Object.entries(json)) {
cookiesString += `${key}=${value.value}; `;
}
return cookiesString;
};
provideMeSavedCookies = async () => {
try {
let value = await AsyncStorage.getItem('savedCookies');
if (value !== null) {
return Promise.resolve(JSON.parse(value));
}
} catch (error) {
return {}
}
};
componentWillMount() {
this.provideMeSavedCookies()
.then(async (savedCookies) => {
let cookiesString = this.jsonCookiesToCookieString(savedCookies);
const PHPSESSID = await AsyncStorage.getItem('PHPSESSID');
if (PHPSESSID) {
cookiesString += `PHPSESSID=${PHPSESSID};`;
}
this.setState({cookiesString, isReady: true});
})
.catch((e) => {
this.setState({isReady: true});
});
}
第 3 步:
在 Webview Header 中传递 cookiesString 并像这样编写渲染函数
render() {
const {cookiesString, isReady} = this.state;
if (!isReady) {
return null;
}
return (
<SafeAreaView style={styles.container}>
<WebView
ref={this.myWebView}
source={{
uri: `${domain}`,
headers: {
Cookie: cookiesString,
},
}}
scalesPageToFit
useWebKit
onLoadEnd={this.onLoadEnd}
onNavigationStateChange={this.onNavigationStateChange}
sharedCookiesEnabled
javaScriptEnabled={true}
domStorageEnabled={true}
style={styles.WebViewStyle}
/>
</SafeAreaView>
);
}