When the "Submit Comment" Button Stops Working: Handling Fetch Errors and Preventing Duplicate Submissions
1. μμ²μ΄ λλ¬λ€κ³ μμ μ΄ μ±κ³΅ν κ²μ μλλλ€
λκΈ μ μ‘ λ²νΌμ λλ λλ° μ무 λ°μμ΄ μκ±°λ λ²νΌμ΄ κ³μ λΉνμ±νλ μ μμ΅λλ€. μλ²κ° μ€λ₯λ₯Ό 보λλλ° μ½λκ° μ±κ³΅ μλ΅μ²λΌ μ²λ¦¬νμ μλ μκ³ JSONμ΄ μλ HTMLμ νμ±νλ €λ€ μ€ν¨νμ μλ μμ΅λλ€. μμ² λμ€ μ°κ²°μ΄ λκΈ΄ μν©λ λ°λ‘ νμΈν΄μΌ ν©λλ€.
μ΄ κΈμ μ€μ λκΈ μλ²λ₯Ό νΈμΆνμ§ μλ μ¬ν μμ λ₯Ό μ€μ¬μΌλ‘ μ€λ₯ μ²λ¦¬μ ꡬ쑰λ₯Ό μ€λͺ ν©λλ€. μμμ μλ΅ κ°μ²΄λ‘ μ μ JSON, HTTP μ€λ₯, μλͺ»λ λ³Έλ¬Έ, μ°κ²° μ€ν¨λ₯Ό λΉκ΅ν©λλ€. μμ λ₯Ό μ¬μ΄νΈμ λΆμ΄κΈ° μ μ κΈ°μ‘΄ APIμ μλ΅ νμκ³Ό μΈμ¦ λ°©μμ νμΈν΄μΌ ν©λλ€.
2. fetchλ HTTP μ€λ₯λ₯Ό λ³λλ‘ νμΈν΄μΌ ν©λλ€
fetchλ‘ μλ΅μ λ°μλ€κ³ 200λ²λλΌλ λ»μ μλλλ€. 404λ 500 μλ΅λ HTTP μλ΅ κ°μ²΄λ‘ λ°μ μ μμΌλ―λ‘ response.ok λλ statusλ₯Ό νμΈν©λλ€. λ€νΈμν¬ λ¬Έμ λ‘ μλ΅ μ체λ₯Ό λ°μ§ λͺ»ν μν©κ³Ό ꡬλΆν΄μΌ μ¬μ©μμκ² λ€μ νλμ μλ΄ν μ μμ΅λλ€.
κ·Έλ€μ λ³Έλ¬Έ νμμ νμΈν©λλ€. APIκ° JSONμ κΈ°λνμ§λ§ νλ‘μ μ€λ₯ νμ΄μ§κ° HTMLλ‘ μ€λ©΄ response.jsonμμ μμΈκ° μκΈΈ μ μμ΅λλ€. μλ² μλ¬ μλ¬Έμ΄λ μ 체 HTMLμ μ¬μ©μμκ² κ·Έλλ‘ λ ΈμΆνμ§ λ§κ³ , νλ©΄μλ νμν μλ΄λ₯Ό μ 곡νκ³ μ§λ¨ κΈ°λ‘μλ μνμ μμ² μλ³μλ₯Ό λ¨κΉλλ€.
3. μΌκ΄λ μλ² μλ΅ κ³μ½μ΄ λ¨Όμ μ λλ€
μ μ μλ΅μλ success κ°μ νμ κ°μ λͺ μνκ³ μ€λ₯ μλ΅μ μ μ ν μν μ½λμ μμΈ‘ κ°λ₯ν νμμ μ¬μ©νλλ‘ μ€κ³ν©λλ€. μ΄λ―Έ μ¬μ© μ€μΈ APIλΌλ©΄ ν΄λΌμ΄μΈνΈκ° μ΄λ€ ννλ₯Ό κΈ°λνλμ§ νμΈνμΈμ. μλ²μ λΈλΌμ°μ λ₯Ό λ€λ₯Έ μμ μ λ°°ν¬νλ©΄ κ³ΌλκΈ°μ μΈ νμ μ°¨μ΄λ λ°μν μ μμ΅λλ€.
μλ μμ λ JSON Content-Typeκ³Ό successκ° trueμΈ κ²½μ°λ₯Ό μ±κ³΅μΌλ‘ λ΄ λλ€. μ΄ κ·μΉμ μ΄ κΈμ νμ΅μ© κ³μ½μ λλ€. λͺ¨λ APIμ μ μ©λλ νμ€ μλ΅ κ΅¬μ‘°λ μλλλ€. λ³ΈμΈμ μλ²κ° λ€λ₯Έ μ΄λ¦κ³Ό μλ£νμ μ¬μ©νλ€λ©΄ κ·Έ κ³μ½μ λ§μΆ° κ²μ¬λ₯Ό μ‘°μ ν΄μΌ ν©λλ€.
4. λ²νΌ λΉνμ±νλ finallyμμ 볡ꡬν©λλ€
μ μ‘ μ€ λ²νΌμ λΉνμ±ννκ³ μ²λ¦¬κ° λλλ©΄ finallyμμ 볡ꡬνλ ν¨ν΄μ μ¬μ©ν μ μμ΅λλ€. μ€λ₯κ° λλ μ΄ κ²½λ‘κ° μ€νλλ―λ‘ λ²νΌμ΄ μꡬμ μΌλ‘ λ©μΆλ μν©μ μ€μ λλ€. λμμ μ§ν μ€μΈ μμ²μ νμνλ νλκ·Έλ₯Ό λλ©΄ μ°μ ν΄λ¦μΌλ‘ κ°μ μμ μ΄ λ λ² μμλλ κ²μ μ€μΌ μ μμ΅λλ€.
λΈλΌμ°μ λ²νΌ μ μ΄λ§μΌλ‘ μλ²μ μ€λ³΅ μ μ₯μ μμ ν λ§λ κ²μ μλλλ€. ν λ κ°, μ¬μ μ‘, λ€νΈμν¬ μ€κ° μ€ν¨ κ°μ μν©μ μλ²μμλ κ³ λ €ν΄μΌ ν©λλ€. λκΈΒ·κ²°μ Β·ν¬μΈνΈμ²λΌ μνκ° λ°λλ μμ μμλ μλ³ ν€λ μ€λ³΅ κ²μ¬ λ± μλ² μ μ± μ λ³λλ‘ μ€κ³ν©λλ€. μλ μμ λ μλ² λ©±λ±μ±μ ꡬννμ§ μμ΅λλ€.
5. μμ μμ λ‘ μ€ν¨ μ νμ λΆλ¦¬ν©λλ€
readApiResult ν¨μλ μλ΅μ κ²ν νλ μμν λΆλΆμ λλ€. μ΄ λΆλΆμ λ¨Όμ κ²μ¬νλ©΄ νλ©΄ μ΄λ²€νΈμ μλ² μνκ° μμ΄μ§ μμ΅λλ€. μ΄μ΄μ λ²νΌ μνλ₯Ό κ΄λ¦¬νλ ν¨μμμ κΈ°μ‘΄ νΌ μ μ‘μ μ°κ²°ν©λλ€. μμ² μ£Όμμ μ λ ₯ κ°μ νλ‘κ·Έλ¨ λ°μμ λͺ μμ μΌλ‘ μ λ¬νκ² νλ©΄ μλͺ»λ κΈ°λ³Έ μ£Όμλ‘ μ μ‘νλ μ€μλ₯Ό μ€μΌ μ μμ΅λλ€.
λ‘κ·ΈμΈ μΏ ν€μ CSRF ν ν°μ μ°λ μλΉμ€μμλ ν΄λΉ κ³μ½λ μ μ§ν΄μΌ ν©λλ€. μμ μ μΈμ¦ κ°μ μ§μ μ μ§ λ§μΈμ. cross-origin μμ²μ μ°λ μλΉμ€λΌλ©΄ μΏ ν€, CORS, origin κ΄κ³λ₯Ό λ³λλ‘ μ κ²ν©λλ€. μ€λ₯λ₯Ό μμ κΈ° μν΄ no-corsλ₯Ό λΆμ΄λ λ°©λ²μ μλ΅μ μ½μ μ μκ² λ§λ€μ΄ μ§λ¨ λͺ©μ κ³Ό λ§μ§ μμ μ μμ΅λλ€.
6. μ€ν¨ ν μ¬μ©μμκ² λ³΄μ¬ μ€ λ΄μ©
μ μ‘ μ€ν¨λ₯Ό μ‘°μ©ν μΌν€λ©΄ μ¬μ©μλ μ¬λ¬ λ² λλ₯Ό μ μμ΅λλ€. μ λ ₯ λ΄μ©μ 보쑴νκ³ μ±κ³΅μ΄ νμΈλμ λλ§ μ΄κΈ°ννλ νΈμ΄ μ’μ΅λλ€. μ€ν¨ μλ΄μλ μ¬μλ κ°λ₯ μ¬λΆλ₯Ό μ κ³ , μμ² μ νμΈ κ²½μ° μλΉμ€μ λκΈ° μ μ± μ λ°μν©λλ€. λͺ¨λ μ€ν¨μμ μ¦μ μλ μ¬μλνλ μ€κ³λ νΌνμΈμ.
μλ΅μ λ°μ§ λͺ»νλλΌλ μλ²μλ μ μ₯λμ μ μμ΅λλ€. μ±κ³΅Β·μ€ν¨λ₯Ό λͺ¨λ₯΄λ μνλ₯Ό λ¨μ μ€ν¨μ ꡬλΆν νμκ° μμ΅λλ€. μ€μν μμ μμλ μ‘°νλ‘ κ²°κ³Όλ₯Ό νμΈνκ±°λ μλ² μλ³μλ₯Ό μ¬μ©νλ λ°©λ²μ κ²ν ν©λλ€. κ°λ°μ λꡬμ μμ²κ³Ό μλ² κΈ°λ‘μ λμ‘°νκ³ UIλ§ μ μμΌλ‘ 보μ΄λμ§ νμΈνμ§ λ§μΈμ.
7. μμνμ§ λͺ»ν μλ΅μ μν ν μ€νΈ λͺ©λ‘
μ μ μλ΅ νλλ§ νμΈνμ§ λ§κ³ μ€ν¨ μ νμ λλμ΄ μνν©λλ€. HTTP μ€λ₯, μ μ μ½λμ§λ§ μλͺ»λ λ³Έλ¬Έ, successκ° falseμΈ λ°μ΄ν°μ μ°κ²° κ±°μ μ λ°λ‘ μ€λΉνμΈμ. κ° κ²½μ°μ λ²νΌμ΄ 볡ꡬλλμ§, μμ± λ΄μ©μ΄ μ μ§λλμ§, μ¬μ©μ μλ΄κ° ν λ²λ§ νμλλμ§ νμΈν©λλ€. νλ©΄ μ΄λ²€νΈ μ체λ μ€μ λΈλΌμ°μ μμλ λ³λλ‘ κ²μ¬ν΄μΌ ν©λλ€.
μ μ‘ μ€ λ λ² ν΄λ¦νλ κ²½μ°μ λ€λ₯Έ λ²νΌμ λλ₯΄λ κ²½μ°λ₯Ό ꡬλΆν©λλ€. μμ μ sending νλκ·Έλ ν΄λΉ κΈ°λ₯μ μμ²μ νλλ‘ μ ννλ ꡬ쑰μ λλ€. μ¬λ¬ λ 립 νΌμ λμμ μ¬μ©ν νλ©΄μ΄λΌλ©΄ νλμ μ μ νλκ·Έκ° λ€λ₯Έ κΈ°λ₯κΉμ§ λ§μ μ μμΌλ―λ‘ νΌ λ¨μ μνλ₯Ό μ€κ³νμΈμ. μμ μ λ²μλ₯Ό μ΄ν΄ν λ€ νμ₯νλ νΈμ΄ μ’μ΅λλ€.
μλ²κ° μ€λ μλ΅νμ§ μλ μν©μλ κΈ°λ€λ¦¬λ μλ΄μ μ·¨μ μ μ± μ΄ νμν μ μμ΅λλ€. μ¬μ©μκ° νλ©΄μ λ λ λ μμ²μ μ·¨μν μ§, κ²°κ³Ό νμΈμ μ΄μ΄κ°μ§ κ²°μ νμΈμ. μμ²μ μ·¨μνλ€κ³ μλ² μμ κΉμ§ μ·¨μλλ€κ³ λ¨μ ν μλ μμ΅λλ€. νΉν μνλ₯Ό λ°κΎΈλ μμ μμλ νμ μ‘°νμ μμ μλ³μ μ€κ³λ₯Ό ν¨κ» κ²ν ν©λλ€.
μλ¬ κΈ°λ‘μ μ¬μ©μ νλ©΄κ³Ό κ°λ°μ λ‘κ·Έλ₯Ό ꡬλΆν©λλ€. νλ©΄μλ μκΈ° μ¬μ΄ μλ΄λ₯Ό μ 곡νκ³ λ‘κ·Έμλ μν μ½λμ μ€ν¨ λ¨κ³ λ± μ¬νμ νμν μ 보λ₯Ό λ¨κΉλλ€. μλ²κ° λ³΄λΈ μ€ν μΆμ μ΄λ μΈμ¦ κ°μ κ·Έλλ‘ νμνμ§ λ§μΈμ. κ³΅ν΅ μ€λ₯ νμμ μ¬μ©νλ APIλΌλ©΄ ν΄λΌμ΄μΈνΈλ κ·Έ ꡬ쑰λ₯Ό λ°λ₯΄λλ‘ λ§μΆ₯λλ€.
λ°°ν¬ νμλ μ JavaScriptκ° μ€μ λ‘λλλμ§λ νμΈν©λλ€. λΈλΌμ°μ μΊμμ μ΄μ νμΌμ΄ λ¨μΌλ©΄ μ½λλ₯Ό κ³ μ³€λλ° κ°μ μ¦μμ΄ λ³΄μΌ μ μμ΅λλ€. νμΌ λ²μ κ³Ό μμ² κ²½λ‘λ₯Ό λμ‘°νκ³ μ μΒ·μ€ν¨ ν μ€νΈλ₯Ό ν λ²μ© λ°λ³΅νμΈμ. ν μ€νΈκ° ν΅κ³Όν λ²μλ§ κΈ°λ‘νλ©΄ HTML νλ©΄, λ€νΈμν¬ μ μ± κ³Ό μλ² μ μ₯ λμμ λ―ΈνμΈ μμμ λΆλͺ ν μ μ μμ΅λλ€.
8. λ°λΌ νλ μμ
λͺ λ Ήκ³Ό μ½λλ νμ΅μ©μ λλ€. μ€λͺ μ νμλ μ€ν νκ²½μ ꡬλΆνκ³ μ μν ν΄λ λλ λͺ¨μ μ λ ₯μΌλ‘ μμνμΈμ.
μμ μ½λ
async function readApiResult(response) {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const type = response.headers.get('content-type') || '';
if (!type.toLowerCase().includes('application/json')) {
throw new Error('JSON μλ΅μ΄ μλλλ€');
}
const data = await response.json();
if (!data || data.success !== true) {
throw new Error('μμ
μ±κ³΅μ νμΈνμ§ λͺ»νμ΅λλ€');
}
return data;
}
let sending = false;
async function submitWithState(button, requestFactory) {
if (sending) return;
sending = true;
button.disabled = true;
try {
return await readApiResult(await requestFactory());
} finally {
sending = false;
button.disabled = false;
}
}
// νΈμΆ μ: κΈ°μ‘΄ submit μ²λ¦¬ μμμ catchλ‘ μ¬μ©μ μλ΄λ₯Ό νμνμΈμ.
// await submitWithState(button, () => fetch(url, existingRequestOptions));9. κ²μ¦ κ²°κ³Όμ ν΄μ
| νμΈ νλͺ© | κ²°κ³Ό λλ κ²μ¦ λ²μ |
|---|---|
| 200 + μ¬λ°λ₯Έ JSON | μ±κ³΅ λ°μ΄ν° λ°ν |
| 500 μλ΅ | HTTP μ€λ₯λ‘ κ΅¬λΆ |
| 200 + HTML | JSON νμ μ€λ₯λ‘ κ΅¬λΆ |
| 200 + μλͺ»λ JSON | νμ± μ€ν¨ |
| μ°κ²° μ€ν¨ | μμΈ μ λ¬ Β· λ²νΌ 볡ꡬ |
| λμ λ νΈμΆ | μ μ‘ ν¨μ ν λ² νΈμΆ |
Node.jsμ Response κ°μ²΄μ λͺ¨μ μμ²μΌλ‘ λΆκΈ°Β·λ²νΌ 볡ꡬ·μ€λ³΅ νΈμΆμ κ²μ¦νμ΅λλ€. μ€μ λΈλΌμ°μ DOM, CORSμ μ΄μ λκΈ APIλ κ²μ¦νμ§ μμμ΅λλ€.
10. μμ£Ό 묻λ μ§λ¬Έ
catchλ§ μμΌλ©΄ 500μ μ‘λμ?
fetch μ체μ κ±°μ κ³Ό HTTP μ€λ₯λ λ€λ¦ λλ€. μλ΅ μνλ₯Ό νμΈνκ³ νμνλ©΄ μ§μ μ€λ₯λ₯Ό λ°μμμΌμΌ ν©λλ€.
λ²νΌμ λ§μΌλ©΄ μ€λ³΅ λκΈμ΄ μμ ν μ¬λΌμ§λμ?
μλλλ€. λ€λ₯Έ νκ³Ό μ¬μλλ μλ²μμλ μ²λ¦¬ν΄μΌ ν©λλ€. λ²νΌμ UI μμ€μ μ μ΄μ λλ€.
μ±κ³΅ μ μ μ λ ₯μ λΉμλ λλμ?
μ€ν¨ μ μμ± λ΄μ©μ μμ μ μμ΅λλ€. μ±κ³΅ νμΈ μ΄ν μ΄κΈ°ννκ³ μ€λ₯κ° λλ©΄ μ λ ₯μ μ μ§νλ λ°©ν₯μ κ²ν νμΈμ.
11. 곡μ μ°Έκ³ μλ£
λμ μ μμ μ΅μ μ μλ μ μμ λ¬Έμμμ νμΈν μ μμ΅λλ€. λ³Έλ¬Έμ μ¬λ‘μ μμ λ νμ΅μ μν΄ λ 립μ μΌλ‘ ꡬμ±νμ΅λλ€.
μμ μ λ ₯μ νμ΅μ© λͺ¨μ μλ£μ λλ€. μ€μ νκ²½μ μ μ©ν λλ λ³Έλ¬Έμ μλ΄ν κ²μ¦ λ²μμ 쑰건μ νμΈνμΈμ.
π¬ 0 Comments