【问题标题】:Can javascript submission of a form interfere with previous axios callsjavascript提交表单会干扰之前的axios调用吗
【发布时间】:2019-07-29 13:49:38
【问题描述】:

我的用户遇到了一个间歇性问题,但我无法导致它发生,所以我自己从未经历过。

我有一个带有两个 html 表单的 vue.js 组件。用户填写第一个表单,提交它......调用一个函数,该函数执行两个 axios 调用,然后以编程方式提交第二个表单。第二种形式是标准的 PayPal 形式,将用户发送到 PayPal。参见下面的代码 sn-ps。

doLogging() 函数写入另一台服务器上的文件。 doMail() 函数发送电子邮件并写入不同的文件。

用户总是被发送到 PayPal 网站,并且从未注意到任何问题。但是,有时日志记录和电子邮件都会发生,有时两者都不会发生。它总是要么两者兼而有之,要么都不是。好像 axios 调用有时会发生,但其他时候不会发生。

这里是 html sn-ps:

<form @submit.prevent="processRegistration()">
  <button type="submit"
    class="button is-info">Ready to pay with PayPal
  </button>
  ... other form elements ...
</form>

<form id="paypalForm" action="https://www.paypal.com/cgi-bin/webscr" method="post" class="hidden">
   ... paypal form elements ...
   <input type="submit" value="Pay with PayPal"/>
</form>

以下是被调用的精简函数:

 processRegistration() {
    this.doLogging();
    this.doMail();

    let paypalForm = document.getElementById('paypalForm');
    paypalForm.submit();
 }

async doLogging() {   // log info to a file
  let headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'};
  try {
    await axios.post('https://logging.xxx.com/logger.php', this.stuff, {headers: headers});
  } catch (e) {
    console.log(e);
  }
}, 


async doMail() {  / send email and log info to a file
    let headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'};
    try {
        await axios.post('/email.log.php', this.otherStuff, {headers: headers});
    } catch (e) {
        console.log(e);
    }
 },

【问题讨论】:

  • 那是因为有时你的doLogging()doMail() 在你的用户被重定向到贝宝之前就已经完成了,有时不会。
  • 我认为通过使用await,它们都会串行执行。 @弗兰克
  • 是的,但是 processRegistration 不是异步函数。

标签: javascript vue.js paypal axios


【解决方案1】:

doLogging()doMail() 中的承诺在提交 paypal 表单时可能尚未解决。解决这个问题最明显的方法是等待这两个函数(并使processRegistration()异步)。

async processRegistration() {
    await this.doLogging();
    await this.doMail();

    let paypalForm = document.getElementById('paypalForm');
    paypalForm.submit();
 }

现在,doMail() 将等待 doLogging() 并且在解决 doMail() 之前不会调用 paypalForm.submit()。另一种选择是使用链接。

这不是最漂亮的方法,但无论如何都能完成工作。

【讨论】:

    【解决方案2】:

    在阅读了更多关于 Promises 的内容后,这是我自己的问题的解决方案。由于 doLogging() 和 doMail() 帖子可以同时发生,使用 Promise.all() 似乎是用来确保这些帖子在发布到 PayPal 之前完成的事情。

    doLogging() {
     let headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'};
     return axios.post('https://logging.xxx.com/logger.php', this.stuff, {headers: headers});
    },
    
    doMail() {
     let headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'};
     return axios.post('/email.php', this.otherStuff, {headers: headers});
    },
    
    submitToPayPal() {
     let paypalForm = document.getElementById('paypalForm');
     paypalForm.submit();
    },
    
    processMembership() {
     let log = this.doLogging();
     let mail = this.doMailToDancer();
    
     Promise.all([log, mail])
      .then(this.submitToPayPal())
      .catch(error => {
       console.log(error.message)
      });
    },`
    

    【讨论】:

    • Promise.all([log, mail]) .then(this.submitToPayPal()) 在承诺解决之前立即执行this.submitToPayPal(),因此您的问题仍然存在。您需要将其设为.then(() =&gt; this.submitToPayPal()).then(this.submitToPayPal)
    • 好的,太好了。我想我现在看到了区别。我必须清楚 submitToPayPal()submitToPayPal 以及 .then 需要什么。
    猜你喜欢
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    相关资源
    最近更新 更多