繁体   English   中英

使用 Fetch API 提交 WordPress 表单时,我不断收到 400(错误请求)

[英]I keep getting a 400 (Bad Request) when submitting a WordPress form using the Fetch API

我正在开发一个 WordPress 网站,我正在尝试将我的 jQuery 代码转换为普通 JavaScript (主要是作为学习经验,但我也没有依赖 jQuery)。 目标是一旦提交表单,而不是转到感谢页面或其他内容,只需在表单上显示一个叠加层,上面写着“感谢您的信息”。 同样,jQuery/AJAX 一切正常,但我想尝试让它与普通的 JavaScript 一起工作。

这是有效的 jQuery 代码:

  jQuery('#myContactForm').on('submit', function () {
    var formData = jQuery(this).serializeArray();

    formData.push({ 
      name: 'security', 
      value: ajaxNonce 
    });

    jQuery.ajax({
      type: 'POST',
      url: ajaxUrl,
      data: formData
    });

    jQuery('.form-overlay').addClass('visible');

    return false;
  });

这是functions.php的工作代码:

<?php 

function javascript_variables() { ?>
  <script type="text/javascript">
    var ajaxUrl = '<?php echo admin_url('admin-ajax.php'); ?>';
    var ajaxNonce = '<?php echo wp_create_nonce('secure_nonce_name'); ?>';
  </script>
  <?php
}
add_action('wp_head', 'javascript_variables');


add_action('wp_ajax_send_form', 'send_form');
add_action('wp_ajax_nopriv_send_form', 'send_form');
 
function send_form() {
  check_ajax_referer('secure_nonce_name', 'security');
 
  $to = 'myemailaddressgoeshere@gmail.com';

  $subject = $_POST['subject'];
  
  $body  = 'From: ' . $_POST['full_name'] . '<br />';
  $body .= 'Email: ' . $_POST['email'] . '<br />';
  $body .= 'Phone: ' . $_POST['phone'] . '<br />';
  $body .= 'Message: ' . $_POST['message'] . '<br />';

  $headers = array('Content-Type: text/html; charset=UTF-8');
    
  wp_mail($to, $subject, $body, $headers);

  wp_die();
}

最后,这是表单中的相关输入:

<input class="form-inputs" type="hidden" name="action" value="send_form" />

这是我在尝试使用 Fetch API 而不是 jQuery 时想到的:

// handle form submission
const formSubmissionHandler = () => {
  const form = document.getElementById('myContactForm');
  const formOverlay = document.querySelector('.form-overlay');
  const formInputs = Array.from(document.querySelectorAll('.form-inputs'));
  const formData = [];

  form.addEventListener('submit', (e) => {
    e.preventDefault();

    formInputs.forEach((input) => {
      if (!input.name || !input.value) {
        return;
      }

      formData.push({
        name: input.name,
        value: input.value,
      });
    });

    formData.push({
      name: 'security',
      value: ajaxNonce,
    });

    const fetchOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(formData),
    };

    // send post request
    fetch(ajaxUrl, fetchOptions)
      .then((res) => res.json())
      .then((res) => console.log(res))
      .catch((err) => console.error(err));

    formOverlay.classList.add('visible');
  });
};
document.addEventListener('DOMContentLoaded', formSubmissionHandler);

我在搜索中遇到了FormData()构造函数,不确定在哪里/是否会在这里使用它?

这是我在 functions.php 文件中写的内容:

function send_form() {
  check_ajax_referer('secure_nonce_name', 'security');
 
  $to = 'myemailaddressgoeshere@gmail.com';

  $subject = $_POST['subject'];

  $json_input = json_decode(file_get_contents('php://input'), true);

  $body = '';
  
  foreach ($json_input as $key => $value) {
    $body  = 'From: ' . $value['full_name'] . '<br />';
    $body .= 'Email: ' . $value['email'] . '<br />';
    $body .= 'Phone: ' . $value['phone'] . '<br />';
    $body .= 'Message: ' . $value['message'] . '<br />';
  }

  $headers = array('Content-Type: text/html; charset=UTF-8');
    
  wp_mail($to, $subject, $body, $headers);

  wp_die();
}

我对这一切都很陌生,所以如果有人可以帮助我,我将不胜感激。 我认为我的问题是我如何解析 functions.php 中的 JSON 数据。 或者我可以简单地在 vanilla JS 中格式化数据,就像在 jQuery 中那样? 谢谢!

我知道我发布这个可能有点晚了,但如果将来有人遇到这个,这里是交易:

const fetchOptions = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(formData),
};

here, you are making a json string to pass to the destination URL but you have to remember, Wordpress's ajax parser can't understand data being sent to it as raw json.

$json_input = json_decode(file_get_contents('php://input'), true);

在这里,您将收到的原始输入转换为一个数组,但在此之前,所有 Wordpress 得到的只是一段数据,它是一个简单的字符串。 因此,它不知道如何处理它以及应该触发哪些用户定义的钩子和操作来验证这一点。

add_action('wp_ajax_send_form', 'send_form');
add_action('wp_ajax_nopriv_send_form', 'send_form');

在这里,您告诉 wordpress 期待一些带有 'send_form' 的 'action' 名称的请求,如果收到,请将其传递给名为 'send_form' 的 function。 Wordpress 但是没有收到名为“action”的请求。 因此错误。

但是,修复非常简单,只需将此请求名称作为 GET 添加到您要将原始数据发送到的 url 并为 wordpress 清除它:

var ajaxUrl = '<?php echo admin_url('admin-ajax.php'); ?>?action=send_for';

或者,我更喜欢的版本:

// send post request
fetch(ajaxUrl + '?action=send_form', fetchOptions)
  .then((res) => res.json())
  .then((res) => console.log(res))
  .catch((err) => console.error(err));

完成了,我想一旦你开始使用 fetch() 和 WP,至少现在是这样(直到 Wordpress 想出办法)。 这可能会派上用场。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM