JS. Почему не срабатывает preventDefault() если input type file содержит файл

Есть форма, на ней event listener submit, внутри Event.preventDefault(). Есть поле type file. Если оно пустое, то при отправке формы перегрузка не происходит. Если содержит файл, то страница перегружается несмотря на preventDefault. Интересует это какое-то дефолтное поведение связанное с этим типом инпута или мой косяк? Спасибо!

const pushNewOrderOnServer = (fetchUrl) => {
const orderForm = document.getElementById('add-order');
const addOrderBtn = document.getElementById('add-order-btn');
orderForm.addEventListener('submit', async (e) => {
    e.preventDefault();
    
    if(validator()){
        const url = fetchUrl;
        const formData = new FormData(orderForm);
        await fetch(url, {method: 'POST', body: formData});
        updateState('orders');
        }
    }
}

PS Похоже причина в php обработчике "move_uploaded_file", а не в js. При работе на локальном сервере это происходит.


Ответы (1 шт):

Автор решения: Artem Criticall Metr

Все элементарно просто, если немного почитать документацию)))

Одним из способов избежать перезагрузки страницы при отправке файла является использование XMLHttpRequest или Fetch API для отправки данных формы на сервер асинхронно. Вы уже используете Fetch API, поэтому вам необходимо убедиться, что ваша форма отправляется с помощью AJAX-запроса, а не стандартного запроса, который вызывает перезагрузку страницы.

Для того, чтобы отправить файл через AJAX, вам необходимо добавить дополнительные параметры в объект настроек Fetch API, чтобы указать тип данных (Content-Type) и метод отправки (POST)

const pushNewOrderOnServer = (fetchUrl) => {
  const orderForm = document.getElementById('add-order');
  const addOrderBtn = document.getElementById('add-order-btn');
  
  orderForm.addEventListener('submit', async (e) => {
    e.preventDefault();
    
    if (validator()) {
      const url = fetchUrl;
      const formData = new FormData(orderForm);
      
      const options = {
        method: 'POST',
        body: formData,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      };
      
      await fetch(url, options);
      updateState('orders');
    }
  });
};

Если вы не указываете тип контента, то браузер будет пытаться отправить форму с помощью стандартного запроса, который вызовет перезагрузку страницы.

→ Ссылка