HTML Форма отправки с XHR не работает на устройствах на базе iOS / iPadOS - PullRequest
0 голосов
/ 09 февраля 2020

Я сделал HTML форму, в которой можно отправлять данные на листы Google, используя метод здесь . Данный метод может успешно отправить данные на листы Google. Но если он используется на устройствах iOS / iPadOS, отправка формы не работает независимо от браузеров (протестировано в Safari и Chrome). Я подозреваю, что XHR является основным виновником здесь, но я не могу найти решение, которое работает. Вот фрагмент функции отправки формы.

  function handleFormSubmit(event) {  // handles form submit without any jquery
    event.preventDefault();           // we are submitting via xhr below
    var form = event.target;
    var formData = getFormData(form);
    var data = formData.data;

    // If a honeypot field is filled, assume it was done so by a spam bot.
    if (formData.honeypot) {
      return false;
    }

    disableAllButtons(form);
    var url = form.action;
    var xhr = new XMLHttpRequest();
    xhr.open('POST', url);
    // xhr.withCredentials = true;
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && xhr.status === 200) {
        form.reset();
        var formElements = form.querySelector('.form-elements');
        if (formElements) {
          formElements.style.display = 'none'; // hide form
        }
        var thankYouMessage = form.querySelector('.thankyou_message');
        if (thankYouMessage) {
          thankYouMessage.style.display = 'block';
        }
      }
    };
    // url encode form data for sending as post data
    var encoded = Object.keys(data).map(function(k) {
      return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
    }).join('&');
    xhr.send(encoded);
  }

  function loaded() {
    // bind to the submit event of our form
    var forms = document.querySelectorAll('form.gform');
    for (var i = 0; i < forms.length; i++) {
      forms[i].addEventListener('submit', handleFormSubmit, false);
    }
  };
  document.addEventListener('DOMContentLoaded', loaded, false);

  function disableAllButtons(form) {
    var buttons = form.querySelectorAll('button');
    for (var i = 0; i < buttons.length; i++) {
      buttons[i].disabled = true;
    }
  }
})();

И это открывающий тег моего тега form:

    <form [formGroup]="oprecForm" method="POST" data-email="someone@someone.com" class="gform"
          action="link_to_google_sheets"
          (ngSubmit)="prosedurMaju()">

(я использую Angular в своем проекте, если это может помочь каким-либо образом. И Я поставил эти функции за пределы ngOnInit()

Дополнительная информация: Это еще одна функция, которую я поставил помимо упомянутой выше, и она расположена выше над этими функциями выше.

(function finalization() {
  // get all data in form and return object
  function getFormData(form) {
    var elements = form.elements;
    var honeypot;

    var fields = Object.keys(elements).filter(function(k) {
      if (elements[k].name === 'honeypot') {
        honeypot = elements[k].value;
        return false;
      }
      return true;
    }).map(function(k) {
      if (elements[k].name !== undefined) {
        return elements[k].name;
        // special case for Edge's html collection
      } else if (elements[k].length > 0) {
        return elements[k].item(0).name;
      }
    }).filter(function(item, pos, self) {
      return self.indexOf(item) == pos && item;
    });

    var formData = <any> {};
    fields.forEach(function(name) {
      var element = elements[name];

      // singular form elements just have one value
      formData[name] = element.value;

      // when our element has multiple items, get their values
      if (element.length) {
        var data = [];
        for (var i = 0; i < element.length; i++) {
          var item = element.item(i);
          if (item.checked || item.selected) {
            data.push(item.value);
          }
        }
        formData[name] = data.join(', ');
      }
    });

    // add form-specific values into the data
    formData.formDataNameOrder = JSON.stringify(fields);
    formData.formGoogleSheetName = form.dataset.sheet || 'responses'; // default sheet name
    formData.formGoogleSend
      = form.dataset.email || ''; // no email by default

    return {data: formData, honeypot: honeypot};
  }

1 Ответ

0 голосов
/ 09 февраля 2020

Это не Angular способ ведения дел. Я ожидаю увидеть что-то похожее на этот пример кода при отправке http-запроса.

import { HttpClient, HttpParams } from '@angular/common/http';

constructor(private http: HttpClient) {
}

sendRequest(): void {
  // create body of POST in some way
  const httpParams: HttpParams = new HttpParams({
    fromObject: {
      key: 'value'
    }
  });

  this.http.post(this.url, body).subscribe(response => {
    // do something with the response
    console.log(response);
  });
}

У вас могут быть веские причины для использования нативного XMLHttpRequest, но вам еще далеко до его достижения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...