index.php 에서만 문의 등록 폼이 안되는 이유
본문
안녕하세요. 오랜만에 문의 남깁니다.
제가 사이트를 하나 만들어 보고 있는데요
index 페이지와 렌딩 페이지가 있을때
동일한 상담문의 폼을 그대로 복붙해도
렌딩 페이지에서는 정상적으로 문의 게시글이 작성되고,
index 페이지에서는 상담문의 성공 얼럿이 뜨지만 문의 게시글이 작성되지 않습니다.
아래는 해당 코드입니다.
<div class="custom-main-banner">
<div class="banner-container">
<div class="banner-left">
<h2>온라인 상담 신청</h2>
<form id="consultForm" action="제 도메인 주소/bbs/write_update.php" method="post">
<input type="hidden" name="bo_table" value="tl_qa">
<input type="hidden" name="wr_id" value="">
<input type="hidden" name="sca" value="">
<input type="hidden" name="w" value="">
<input type="hidden" name="html" value="html1">
<!-- CSRF 방지를 위한 토큰 추가 -->
<input type="hidden" name="token" value="<?php echo get_write_token('tl_qa'); ?>">
<div class="form-group">
<label for="name"></label>
<input type="text" id="name" name="wr_name" placeholder="이름" required />
<input type="hidden" name="wr_subject" id="wr_subject_hidden" />
</div>
<div class="form-group">
<label for="phone"></label>
<input type="tel" id="phone" name="wr_content" placeholder="‘-’ 없이 숫자만 입력" pattern="[0-9]{11,14}" required />
</div>
<div class="form-group">
<label for="selectCategory"></label>
<select id="selectCategory" name="consult_type">
<option value="상담신청">상담신청</option>
<option value="상품1">상품1</option>
<option value="상품2">상품2</option>
<option value="상품3">상품3</option>
<option value="상품4">상품4</option>
<option value="상품5">상품5</option>
</select>
</div>
<div class="form-check">
<input type="checkbox" id="agree" checked />
<label for="agree">개인정보 수집 및 이용 동의 <a href="#" id="openModal">자세히보기</a></label>
</div>
<button class="btn-submit blue" type="submit">빠른 상담</button>
</form>
<!-- 개인정보 수집 모달 -->
<div class="memo__modal" id="privacyModal" style="display: none;">
<div class="memo-modal__inner">
<div class="memo-modal__close" id="closeModal">닫기</div>
<div class="memo-modal__txt">
<h3>개인(신용)정보의 수집,이용에 관한사항</h3>
<p>[개인정보보호법] 및 [신용정보의 이용 및 보호에 관한 법률]에 따라 아래와 같은 내용으로 본인의 개인정보 수집·이용에 동의합니다.</p>
기타 개인정보 내용
</div>
</div>
</div>
</div>
<div class="banner-right">
<div class="banner-card">
<span class="card-label">상품1</span>
<h3>상품1</h3>
<p>어쩌고저쩌고</p>
<div class="card-image"><img src="<?=G5_THEME_URL?>/img/cnimg.png" alt="상품1"></div>
<a href="/theme/sample03/html/렌딩.php" class="goto-button">바로가기</a>
</div>
<div class="banner-card">
<span class="card-label">상품1</span>
<h3>상품1</h3>
<p>어쩌고저쩌고</p>
<div class="card-image"><img src="<?=G5_THEME_URL?>/img/cnimg.png" alt="상품1"></div>
<a href="/theme/sample03/html/렌딩.php" class="goto-button">바로가기</a>
</div>
<div class="banner-card">
<span class="card-label">상품1</span>
<h3>상품1</h3>
<p>어쩌고저쩌고</p>
<div class="card-image"><img src="<?=G5_THEME_URL?>/img/cnimg.png" alt="상품1"></div>
<a href="/theme/sample03/html/렌딩.php" class="goto-button">바로가기</a>
</div>
<div class="banner-card">
<span class="card-label">상품1</span>
<h3>상품1</h3>
<p>어쩌고저쩌고</p>
<div class="card-image"><img src="<?=G5_THEME_URL?>/img/cnimg.png" alt="상품1"></div>
<a href="/theme/sample03/html/렌딩.php" class="goto-button">바로가기</a>
</div>
<div class="banner-card">
<span class="card-label">상품1</span>
<h3>상품1</h3>
<p>어쩌고저쩌고</p>
<div class="card-image"><img src="<?=G5_THEME_URL?>/img/cnimg.png" alt="상품1"></div>
<a href="/theme/sample03/html/렌딩.php" class="goto-button">바로가기</a>
</div>
</div>
</div>
</div>
<script>
// 오류 로그 저장 함수
function saveErrorLog(data) {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
sessionId: document.cookie.match(/PHPSESSID=([^;]+)/)?.[1] || 'none',
referer: window.location.href,
cookies: document.cookie,
...data
};
let logs = JSON.parse(localStorage.getItem('ormErrors') || '[]');
logs.push(logEntry);
localStorage.setItem('ormErrors', JSON.stringify(logs));
console.log('Error log saved:', logEntry);
}
document.getElementById('consultForm').addEventListener('submit', function(e) {
e.preventDefault(); // Prevent default form submission
const form = e.target;
const name = document.getElementById('name').value.trim();
const phone = document.getElementById('phone').value.trim();
const consultTypeElement = form.querySelector('select[name="consult_type"]');
const consultType = consultTypeElement ? consultTypeElement.value : '상담신청';
const agree = document.getElementById('agree').checked;
// 1. Name validation: Korean characters, 2-5 letters
const namePattern = /^[가-힣]{2,5}$/;
const invalidNamePattern = /^(?:[ㄱ-ㅎㅏ-ㅣ]+)$/;
const repeatedCharPattern = /^(.)\1+$/;
if (!namePattern.test(name)) {
alert("이름은 2~5글자 한글로 입력해 주세요.");
return;
}
if (invalidNamePattern.test(name) || repeatedCharPattern.test(name)) {
alert("이름을 확인해 주세요.");
return;
}
// 2. Phone validation: 11-14 digits (aligned with cancer.txt)
const phonePattern = /^[0-9]{11,14}$/;
if (!phonePattern.test(phone)) {
alert("연락처는 11~14자리 숫자만 입력해 주세요.");
return;
}
if (!agree) {
alert("개인정보 수집 및 이용에 동의해야 상담이 가능합니다.");
return;
}
// 3. Construct post content with consult type
const currentPageUrl = window.location.href;
const postContent = `상담신청: ${consultType}<br>이름: ${name}<br>연락처: ${phone}<br>신청페이지: ${currentPageUrl}`;
// Debugging: Log post content and form fields
console.log("postContent:", postContent);
console.log("Form fields:", {
bo_table: form.querySelector('input[name="bo_table"]').value,
wr_name: name,
wr_content: postContent,
wr_subject: name + " 님의 상담 요청",
consult_type: consultType
});
// Set subject and content
const subjectHidden = document.getElementById('wr_subject_hidden');
if (subjectHidden) {
subjectHidden.value = name + " 님의 상담 요청";
}
const phoneInput = document.getElementById('phone');
if (phoneInput) {
phoneInput.value = postContent;
}
// Debugging: Log FormData
const formData = new FormData(form);
for (let [key, value] of formData.entries()) {
console.log(`FormData: ${key} = ${value}`);
}
// AJAX request
fetch(form.action, {
method: 'POST',
body: formData
})
.then(response => {
// Debugging: Log response status and headers
console.log("Response status:", response.status, response.statusText);
console.log("Response headers:", [...response.headers.entries()]);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status} ${response.statusText}`);
}
return response.text();
})
.then(responseText => {
// Debugging: Log response text
console.log("Response text:", responseText);
// Use cancer.txt's success condition
if (responseText.includes("location.replace") || responseText.includes("onclick=")) {
alert("상담 신청이 완료되었습니다.");
form.reset();
} else {
alert("전송에 실패했습니다. 다시 시도해 주세요.");
console.error("Unexpected response:", responseText);
}
})
.catch(error => {
console.error("Fetch error:", error);
alert("서버 오류가 발생했습니다: " + error.message);
});
});
// Modal open/close (integrated from cancer.txt and index_n.txt)
document.getElementById('openModal').addEventListener('click', function(e) {
e.preventDefault();
document.getElementById('privacyModal').style.display = 'flex';
});
document.getElementById('closeModal').addEventListener('click', function() {
document.getElementById('privacyModal').style.display = 'none';
});
// index_n.txt's existing banner slider and modal script
document.addEventListener('DOMContentLoaded', function() {
const bannerRight = document.querySelector('.banner-right');
let isDown = false;
let startX;
let scrollLeft;
let autoScroll;
// Drag functionality
bannerRight.addEventListener('mousedown', (e) => {
isDown = true;
bannerRight.classList.add('active');
startX = e.pageX - bannerRight.offsetLeft;
scrollLeft = bannerRight.scrollLeft;
clearInterval(autoScroll);
bannerRight.style.scrollBehavior = 'auto';
});
bannerRight.addEventListener('mouseleave', () => {
isDown = false;
bannerRight.classList.remove('active');
bannerRight.style.scrollBehavior = 'smooth';
startAutoScroll();
});
bannerRight.addEventListener('mouseup', () => {
isDown = false;
bannerRight.classList.remove('active');
bannerRight.style.scrollBehavior = 'smooth';
startAutoScroll();
});
bannerRight.addEventListener('mousemove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - bannerRight.offsetLeft;
const walk = (x - startX) * 2;
bannerRight.scrollLeft = scrollLeft - walk;
});
// Touch functionality
bannerRight.addEventListener('touchstart', (e) => {
isDown = true;
startX = e.touches[0].pageX - bannerRight.offsetLeft;
scrollLeft = bannerRight.scrollLeft;
clearInterval(autoScroll);
bannerRight.style.scrollBehavior = 'auto';
});
bannerRight.addEventListener('touchend', () => {
isDown = false;
bannerRight.style.scrollBehavior = 'smooth';
startAutoScroll();
});
bannerRight.addEventListener('touchmove', (e) => {
if (!isDown) return;
const x = e.touches[0].pageX - bannerRight.offsetLeft;
const walk = (x - startX) * 2;
bannerRight.scrollLeft = scrollLeft - walk;
});
// Auto-scroll functionality
function startAutoScroll() {
clearInterval(autoScroll);
autoScroll = setInterval(() => {
const cardWidth = window.innerWidth <= 768 ? 200 + 20 : 250 + 20;
const maxScroll = bannerRight.scrollWidth - bannerRight.clientWidth;
if (bannerRight.scrollLeft + cardWidth >= maxScroll) {
setTimeout(() => {
bannerRight.style.scrollBehavior = 'auto';
bannerRight.scrollLeft = 0;
bannerRight.style.scrollBehavior = 'smooth';
}, 500);
} else {
bannerRight.scrollLeft += cardWidth;
}
}, 2000);
}
bannerRight.style.scrollBehavior = 'smooth';
startAutoScroll();
});
</script>
조언 부탁드립니다ㅠㅠ
그누5 버전은 가장 최신이고
서버 환경은 UTF-8 (PHP8.4, mariadb-10.x) 입니다.
!-->
답변 4
ai로 한건가요??
암튼 저거 개발자도구 켜서 네트워크로 확인해보세요
에러 로그로 내용이 잘 들어가는데 페이로드 문제 없는지 그리고 응답이나 시작점 눌러서 json 출력 잘되는지 꼼꼼히 확인해보세요
index 에 common 파일 인클루드 되어있나요?
아래 3개중에 하나일것 같은데 확인한번 해보세요
PHP 토큰 미처리 index.html → index.php로 변경 + common.php 포함
JS 값 누락 wr_subject, wr_content가 정상적으로 세팅되는지 확인
응답만 받음 fetch 응답 확인 + 서버단 POST값 수신 여부 확인
답변을 작성하시기 전에 로그인 해주세요.