Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在浏览器中响应本机打开链接并返回应用程序_Javascript_Reactjs_React Native - Fatal编程技术网

Javascript 在浏览器中响应本机打开链接并返回应用程序

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

我在react native中开发了一个应用程序,它应该与支付网关通信,在完成支付过程(成功或失败)后,我需要向用户显示一个警报。为此,我在
中打开了一个链接,然后通过
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或任何你想要的,但你必须首先在你的应用程序中正确设置它,以确保系统知道当