0
1

Всем привет.

Курс "JavaScript - полный курс с нуля до результата!"

Урок 4.3 "Реализация скрипта отправки данных из формы ".

На 11:26 минуте делается проверка отправки данных. При просмотре в network выдаёт эту ошибку. Что может быть не так? Как это исправить?

https://yapx.ru/v/UPZ3v

html-code

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Yoga</title>
   
    <link href="https://fonts.googleapis.com/css?family=Roboto+Slab:300,400,700&amp;subset=cyrillic-ext" rel="stylesheet">
    <link rel="stylesheet" href="css/bootstrap-grid.min.css">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <header>
        <div class="container">
            <nav>
                <ul>
                    <li><a href="#about">О нас</a></li>
                    <li><a href="#photo">Фото</a></li>
                    <li><a href="#price">Стоимость</a></li>
                    <li><a href="#contacts">Контакты</a></li>
                </ul>
            </nav>
        </div>
    </header>
    <div class="main">
        <div class="container">
            <div class="row">
                <div class="col-12">
                    <div class="main-block">
                        <div class="main-block-link">
                            Travel.org                          
                        </div>
                        <div class="main-block-title">
                            йога-туры в индию
                        </div>
                        <div class="main-block-descr">
                            океан / йога / путешествия / аюрведа
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="content">
        <div class="container" id="about">
            <div class="info" >
                <div class="info-header">
                    <div class="info-header-tab">Лечение</div>
                    <div class="info-header-tab">Отдых</div>
                    <div class="info-header-tab">Природа</div>
                    <div class="info-header-tab">Йога</div>
                </div>
                <div class="info-tabcontent fade">
                    <div class="description">
                        <div class="description-title">Здоровый позвоночник</div>
                        <div class="description-text">Йога, массажи и плавание в море - помогут уставшей спине! Индийские йоги считали, что здоровье человека можно определить по тому, насколько здоров и гибок у него позвоночник.<br> Интересно, что бы древние йоги сказали, глядя на современного человека, который уже со школьного возраста мучается болями в спине, работает подолгу в неудобных сидячих позах и не умеет расслабляться, имеет искривление, которое в итоге приведет к болезням других органов? Йоги сказали бы – займись собой и срочно!
                        </div>
                        <div class="description-btn">
                            Узнать подробнее
                        </div>
                    </div>
                    <div class="photo">
                        <img src="img/massage.jpg" alt="Massage">
                    </div>
                </div>
                <div class="info-tabcontent fade">
                    <div class="description">
                        <div class="description-title">Антистресс</div>
                        <div class="description-text">Аюрведа и йога утверждают, что главным источником здоровья нашего организма является здоровый ум. Программа «Антистресс» сначала убирает последствия стресса на физическом уровне, потом помогает избавиться от негативных и навязчивых мыслей, затем повышает общий уровень энергии.<br> Вы наконец вспомните ощущение "свободной головы", ощутите прилив физических сил и вспомните, что такое счастье.</div>
                        <div class="description-btn">
                            Узнать подробнее
                        </div>
                    </div>
                    <div class="photo">
                        <img src="img/sunset.jpg" alt="sunset">
                    </div>
                </div>
                <div class="info-tabcontent fade">
                    <div class="description">
                        <div class="description-title">Восстановление</div>
                        <div class="description-text">Стрессы, жизнь в условиях города, плохая экология, загрязненные продукты и вода, напряженный ритм жизни - все это день ото дня отбирает у нас молодость и хорошее здоровье.<br> Одним кремом для лица не решить проблему омоложения организма, когда тебе за 40. Согласны?</div>
                        <div class="description-btn">
                            Узнать подробнее
                        </div>
                    </div>
                    <div class="photo">
                        <img src="img/sunrise.jpg" alt="sunrise">
                    </div>
                </div>
                <div class="info-tabcontent fade">
                    <div class="description">
                        <div class="description-title">Йога и аюрведа</div>
                        <div class="description-text">Несколько лет назад мы разработали специальные программы по йоге и аюрведе - и мы поняли, что они отлично работают - на опыте 530 наших туристов! В каждой из этих программ есть одна цель, на достижение которой будут направлены и асаны, и дыхательные практики, и медитации, и аюрведические процедуры, будут читаться лекции по этой теме. <br>Йога и аюрведа - два сильных война, которые сообща будут бороться с проблемами и болезнями.</div>
                        <div class="description-btn">
                            Узнать подробнее
                        </div>
                    </div>
                    <div class="photo">
                        <img src="img/yoga.jpg" alt="yoga">
                    </div>
                </div>
            </div>
            <div class="timer">
                <div class="timer-title">Успей забронировать место со скидкой</div>
                <div class="timer-action">
                    До конца акции осталось
                </div>
                <div class="timer-numbers" id="timer">
                    <span class="hours">18</span>
                    <span>:</span>
                    <span class="minutes">20</span>
                    <span>:</span>
                    <span class="seconds">11</span>
                </div>
            </div>
            <button class="more"> Узнать больше</button>
            <div class="slider" id="photo">
                <div class="slider-title">Фото с наших поездок
                </div>
                <div class="wrap">

                    <div class="slider-item fade">
                        <img src="img/slider_1.jpg" alt="slider">
                    </div>
                    <div class="slider-item fade">
                        <img src="img/slider_2.jpg" alt="slider">
                    </div>
                    <div class="slider-item fade">
                        <img src="img/slider_3.jpg" alt="slider">
                    </div>
                    <div class="slider-item fade">
                        <img src="img/slider_4.jpg" alt="slider">
                    </div>

                    <div class="prev"><div class="arrow-left"></div></div>
                    <div class="next"><div class="arrow-right"></div></div>
                </div>
                <div class="slider-dots">
                    <div class="dot dot-active"></div>
                    <div class="dot"></div>
                    <div class="dot"></div>
                    <div class="dot"></div>
                </div>
            </div>
            <div class="counter" id="price">
                <div class="counter-title">Рассчитайте стоимость вашего отдыха
                </div>
                <div class="counter-block">
                    <div class="counter-block-option">Количество людей</div>
                    <input type="number" min="1" step="1" class="counter-block-input">
                </div>
                <div class="counter-block">
                    <div class="counter-block-option">На сколько дней</div>
                    <input type="number" min="1" step="1" class="counter-block-input">
                </div>
                <div class="counter-block">
                    <div class="counter-block-option">Выберете базу</div>
                    <select name="place" id="select">
                        <option id="mumbai" value="1">Индия, Мумбай</option>
                        <option id="kerala" value="1.5">Индия, Керала</option>
                        <option id="varanasi" value="1.8">Индия, Варанаси</option>
                    </select>
                </div>
                <div class="counter-total">
                    Общая сумма<br>
                    <span id="total">20456</span>
                </div>
            </div>
            <div class="contact" id="contacts">
                <div class="contact-img">
                    <img src="img/letter.png" alt="letter">
                </div>
                <div class="contact-form">
                    <div class="contact-form-title">
                        Мы с вами свяжемся
                    </div>
                    <form id="form">
                        <input required type="email" placeholder="Ваша почта">
                        <input required type="tel" placeholder="Ваш телефон">
                        <button type="submit">Отправить</button>
                    </form>
                </div>
            </div>
        </div>
        <footer>
            <div class="container">
                <div class="social">
                    <div class="social-block">
                        <a href="#">
                        <img src="logo/twitter-logo-silhouette.svg" alt="">
                        </a>
                    </div>
                    <div class="social-block">
                        <a href="#">
                        <img src="logo/facebook-logo.svg" alt="">
                        </a>
                    </div>
                    <div class="social-block">
                        <a href="#">
                        <img src="logo/instagram-social-network-logo-of-photo-camera.svg" alt="">
                        </a>
                    </div>
                    <div class="social-block">
                        <a href="#">
                        <img src="logo/pinterest-logo.svg" alt="">
                        </a>
                    </div>
                </div>
            </div>
        </footer>
    </div>
    <div class="overlay fade">
            <div class="popup">
                <div class="popup-close">&times;
                </div>
                <div class="popup-title">
                Форма обратной связи</div>
                    <div class="popup-form">    
                        <form action="#" class="main-form">
                            <div class="popup-form-header">
                                Узнайте больше о своём отдыхе
                            </div>
                                <label class="popup-form__label" for="phone">
                                Введите ваш номер телефона:
                                </label>
                                <input class="popup-form__input" name="phone" type="tel" required placeholder="+7(978) 973 33 45">
                                <button class="button popup-form__btn">
                                    Оставить заявку!
                                </button>
                        </form>
                    </div>
            </div>
    </div>
    <script src="js/script.js"></script>
</body>
</html>

js-code

window.addEventListener('DOMContentLoaded', function (){

    'use strict';

    let tab = document.querySelectorAll('.info-header-tab');
    let info = document.querySelector('.info-header');
    let tabContent = document.querySelectorAll('.info-tabcontent');

    function fideTabContent(a) {
        // функция которая скрывает все табы
        for(let i = a; i < tabContent.length; i++){
            tabContent[i].classList.remove('show');
            tabContent[i].classList.add('hide');
        }
    }

    fideTabContent(1);

    function showTabContent(b) {
        //функция показывающая выбранный в обработчике события таб
        if(tabContent[b].classList.contains('hide')){
            tabContent[b].classList.remove('hide');
            tabContent[b].classList.add('show');
        }
    }

    //навешиваем обработчик, который определяет нужный нам таб с помощью делегирования. Данный способ позволяет нам получить один обработчик событий, вместо 4 в данном случае, что значительно сокращает код и естественно ускоряет его работу.
    info.addEventListener('click', function(event){
        let target = event.target;
        //показывает, что целью является тег содержащий нужный нам класс-лист(это может быть также и тег)
        // event.target.tagName == 'BUTTON' // название тега большими буквами
        if(target && target.classList.contains('info-header-tab')){
            for(let i = 0; i < tab.length; i++){
                if(target == tab[i]){
                    fideTabContent(0);
                    showTabContent(i);
                    break;
                }
            }
        }
    });

    //  делаем таймер

    // создаем дэдлайн

    let deadLine = '2022-10-15';

    //получаем разницу между текущими временем и нашим дедлайном

    function getTimeRemaining(endtime){
        let t = Date.parse(endtime) - Date.parse(new Date());
        let seconds = Math.floor((t/1000)%60);
        let minutes = Math.floor((t/1000/60)%60);
        let hours = Math.floor((t/1000/60/60));

        return {
            'total' : t,
            'hours' : hours,
            'minutes' : minutes,
            'seconds' : seconds
        };
    }

    //функция подстваляющая значения в html

    function setClock(id, endtime) {
        //первый аргумент id куда будем вставлять на страницу, второй заданный дедлайн
        let timer = document.getElementById(id);
        let docHours = timer.querySelector('.hours');
        let docMinutes = timer.querySelector('.minutes');
        let docSeconds = timer.querySelector('.seconds');
        let timeInterval = setInterval(updateClock, 1000);

        function updateClock(){
            let t = getTimeRemaining(endtime);
            docHours.textContent = t.hours;
            docMinutes.textContent = t.minutes;
            docSeconds.textContent = t.seconds;

            if(t.total <= 0) {
                clearInterval(timeInterval);
            }
        }
    }

    setClock('timer', deadLine);

    //создаём модальное окно

    let moreBtn = document.querySelector('.more');
    let overlay = document.querySelector('.overlay');
    let crossModal = overlay.querySelector('.popup-close');

    moreBtn.addEventListener('click', showInfo);

    function showInfo() {
        overlay.style.display = 'block';
        this.classList.add('more-splash');
        document.body.style.overflow = 'hidden';      
    }

    crossModal.addEventListener('click', closeInfo);

    function closeInfo() {
        overlay.style.display = 'none';
        moreBtn.classList.remove('more-splash');
        document.body.style.overflow = '';
    }

    let descriptionBtn = document.querySelector('.description-btn');

    descriptionBtn.addEventListener('click', showInfo);


    //форма
    // создаем объект с сообщениями для пользователя
    let message = {
        loading: 'Загрузка',
        succsess: 'Спасибо за заявку',
        failure: 'Что-то пошло не так!'
    };

    let form = document.querySelector('.main-form');
    let input = document.getElementsByTagName('input');
    let statusMessage = document.createElement('div');

    statusMessage.classList.add('status');

    form.addEventListener('submit',function (event){
            // основная ошибка заключается когда пытаются событие
        //навешивать на кнопку. Нужно событие вешать на форму
        event.preventDefault();
        form.appendChild(statusMessage);

        let request = new XMLHttpRequest();
        request.open('POST', 'server.php');
        request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   
   
        // получение данных от пользователя
        // ключами для атрибута name в html будет формироваться
        //ключ, а значение для него введет пользователь
   
        let formData = new FormData(form);
        request.send(formData);       
    });

});


Алексей Рассказов
2 years ago






Добрый вечер. Ошибка 405 означает, что вы запускаете проект не на локальном сервере. Убедитесь, что проект запускается на работающем сервере по типу MAMP, OpenServer, XAMPP и тп. Именно на них разрешен метод POST 

Иван Петриченко
2 years ago

Так в том и вопрос, как запустить этот локальный сервер? В уроке об этом ничего не говорится.

Алексей Рассказов
2 years ago

Недавно человек тоже спрашивал про локальные сервера - здесь на beonmax почти в каждом базовом курсе есть про работу с локальным сервером

посмотри - насколько помню, XAMPP в курсе PHP/MySQL, OpenServer и MAMP в курсе Веб-разработчик (раздел 3). Также в курсах по WordPress тоже есть про локальные сервера.

https://beonmax.com/courses/web-razrabotchik/lokalnye-servera/

или в поиске набираешь "локальный сервер установка настройка MAMP/OpenServer/XAMPP" выдаст тысячу результатов, это не какие-то уникальные знания, материалов полно. 

Олег
2 years ago

3 ответов