Javascript 在浏览器中响应本机打开链接并返回应用程序
我在react native中开发了一个应用程序,它应该与支付网关通信,在完成支付过程(成功或失败)后,我需要向用户显示一个警报。为此,我在Javascript 在浏览器中响应本机打开链接并返回应用程序,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我在react native中开发了一个应用程序,它应该与支付网关通信,在完成支付过程(成功或失败)后,我需要向用户显示一个警报。为此,我在{ 此.props.dispatch(setPaymentStatus('checked')); 让splitedURL=url.split(“/”); PaymentFactoriad=splitedURL[splitedURL.length-2]; if(splitedURL[splitedURL.length-1]=“0”){ paymentAccep
中打开了一个链接,然后通过onNavigationStateChange
获取return的url,并显示成功或失败消息
但是,此安全问题的流程必须在默认设备浏览器中完成
当前代码:
const BASEURL = 'https://gatewayURL/?ID=';
let Token = null;
let paymentAccepted = null;
let paymentFactorId = null;
class Gateway extends PureComponent {
static propTypes = {
dispatch: PropTypes.func,
navigation: PropTypes.any,
}
componentWillMount() {
this.props.dispatch(getPaymentStatus());
}
_onLoad(webViewState) {
let url = webViewState.url.toString();
let isResponseValid = url.includes('backFromGateway');
if(isResponseValid){
if(this.props.checkedPaymentStatus != 'checked' ){
setTimeout(() => {
this.props.dispatch(setPaymentStatus('checked'));
let splitedURL = url.split("/");
paymentFactorId = splitedURL[splitedURL.length -2];
if(splitedURL[splitedURL.length - 1] === '0'){
paymentAccepted = true;
this.props.dispatch(setGatewayResponse('done', paymentFactorId));
}
else {
paymentAccepted = false;
this.props.dispatch(setGatewayResponse('rejected', paymentFactorId));
}
this.props.navigation.navigate('BackFromGateway', { title: '' })
}, 1000);
}
}
}
render() {
const { addNewOrderGatewayToken, checkedPaymentStatus } = this.props;
token = addNewOrderGatewayToken;
let view = null;
if(checkedPaymentStatus !== 'checked'){
view = <WebView onNavigationStateChange={this._onLoad.bind(this)} style={styles.container} source={{ uri: `${BASEURL}${token}` }}/>
}
else{
view = <View></View>
}
return (
<View style={styles.container}>
{view}
</View>
);
}
}
const BASEURL='1〕https://gatewayURL/?ID=';
让Token=null;
let paymentAccepted=null;
让PaymentFactoriad=null;
类网关扩展了PureComponent{
静态类型={
调度:PropTypes.func,
导航:PropTypes.any,
}
组件willmount(){
this.props.dispatch(getPaymentStatus());
}
_onLoad(webViewState){
让url=webViewState.url.toString();
让isResponseValid=url.includes('backFromGateway');
如果(isResponseValid){
如果(this.props.checkedPaymentStatus!=“checked”){
设置超时(()=>{
此.props.dispatch(setPaymentStatus('checked'));
让splitedURL=url.split(“/”);
PaymentFactoriad=splitedURL[splitedURL.length-2];
if(splitedURL[splitedURL.length-1]=“0”){
paymentAccepted=正确;
此.props.dispatch(setGatewayResponse('done',PaymentFactoriad));
}
否则{
paymentAccepted=假;
此.props.dispatch(setGatewayResponse('rejected',PaymentFactoriad));
}
this.props.navigation.navigate('BackFromGateway',{title:'})
}, 1000);
}
}
}
render(){
const{addNewOrderGatewayToken,checkedPaymentStatus}=this.props;
令牌=addNewOrderGatewayToken;
让view=null;
如果(checkedPaymentStatus!==“已检查”){
视图=
}
否则{
视图=
}
返回(
{view}
);
}
}
有什么想法吗?谢谢如果您可以从网关网站进行回调,那么我建议使用深度链接来处理应用程序和浏览器之间的流。基本上,您的应用程序将打开网关网站进行支付,并且根据支付结果,该网站将使用其深层链接回调应用程序。然后,应用程序将收听该链接,获取必要的信息并继续进行 您需要做的是: 在应用程序中设置深度链接。您应该按照官方网站()中的指南来启用它。在此处选择一个随机URL进行链接,例如
gatewaylistener
设置从网关到应用程序的必要回调。在您的情况下,由于您需要处理成功付款和失败付款,您可以添加2个回调,例如gatewaylistener://success?id={paymentId}
和gatewaylistener://error?id={paymentId}
最后,您需要从应用程序收听web浏览器。一种方法是在打开网关的组件内部添加侦听器
// setup
componentDidMount() {
Linking.getInitialURL().then((url) => {
if (url) {
this.handleOpenURL(url)
}
}).catch(err => {})
Linking.addEventListener('url', this.handleOpenURL)
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL)
}
// open your gateway
async openGateWay = () => {
const { addNewOrderGatewayToken } = this.props
const url = `${BASEURL}${addNewOrderGatewayToken}`
const canOpen = await Linking.canOpenURL(url)
if (canOpen) {
this.props.dispatch(setPaymentStatus('checked'))
Linking.openURL(url)
}
}
// handle gateway callbacks
handleOpenURL = (url) => {
if (isSucceedPayment(url)) { // your condition
// handle success payment
} else {
// handle failure
}
}
出于身份验证的目的,例如,使用深度链接重定向,您可以使用一个嵌入式浏览器,该浏览器具有来自Android的Chrome自定义选项卡,以及来自iOS的SafariViewController,请检查该组件以支持具有相同代码的两种平台(链接已在内部用于检测深度链接重定向) 从示例文件夹中可以看到,您可以使用从应用程序配置的自定义深度链接(Android的AndroidManifest和iOS的Info.plist):
getDeepLink (path = '') {
const scheme = 'my-demo'
const prefix = Platform.OS === 'android' ? `${scheme}://demo/` : `${scheme}://`
return prefix + path
}
async tryDeepLinking () {
const redirectToURL = `https://proyecto26.github.io/react-native-inappbrowser/`
const redirectUrl = this.getDeepLink('home')
const url = `${redirectToURL}?redirect_url=${encodeURIComponent(redirectUrl)}`
try {
if (await InAppBrowser.isAvailable()) {
const result = await InAppBrowser.openAuth(url, redirectUrl)
await this.sleep(800)
Alert.alert('Response', JSON.stringify(result))
} else {
// You can use Linking directly for iOS < 9
}
} catch (error) {
Alert.alert('Something’s wrong with the app :(')
}
}
getDeepLink(路径=“”){
const scheme='我的演示'
const prefix=Platform.OS=='android'?`${scheme}://demo/`:`${scheme}://`
返回前缀+路径
}
异步trydeplinking(){
常数重定向Tourl=`https://proyecto26.github.io/react-native-inappbrowser/`
const redirectUrl=this.getDeepLink('home'))
const url=`${redirectToURL}?redirect\u url=${encodeURIComponent(redirectUrl)}`
试一试{
如果(等待InAppBrowser.isAvailable()){
const result=await InAppBrowser.openAuth(url,重定向url)
等待这个。睡眠(800)
Alert.Alert('Response',JSON.stringify(结果))
}否则{
//对于iOS<9,您可以直接使用链接
}
}捕获(错误){
Alert.Alert('应用程序有问题:('))
}
}
我完全不明白您在Webview安全问题背后的推理和含义是什么?是否有一些文章与此相关?Webview在移动设备上使用与Chrome相同的引擎,我不知道Webview在安全方面会受到什么影响。@JimiPajala我们当地的商店只接受这种方式,用于包括在线支付的应用程序。感谢您的支持你的回答很有帮助,你说为了设置深度链接,我们需要一个URL,对吗?这个URL可以在意向过滤器和数据属性中指定?像这样?
,并将其放在gatewa中ylistener://success?id={paymentId}在这些数据中?应该是
,因为您要使用的方案不是http,而是网关侦听器
。我建议您看看周围的一些好例子,想知道如何调用和设置深度链接。为什么我的方案不是http?我需要从浏览器中侦听URL,如果用户重定向到该URL,我的应用程序应该打开该屏幕n并显示成功/失败消息。这是正确的还是我犯了错误?现在,我向浏览器发送用户进行支付,但在完成支付后,我的应用程序没有响应。方案的价值是让Android系统知道在调用web URI意图时它可以做什么。你的应用程序不侦听浏览器的URL,而是侦听网关的回调如果你做得正确,那么即使是像
这样的链接标签也可以毫无困难地打开你的应用程序。当然,方案可以是http或任何你想要的,但你必须首先在你的应用程序中正确设置它,以确保系统知道当