JavaScript의 API: 정의 및 HTML 페이지에서 API를 사용하는 방법

API는 어려운 부분을 직접 작성하는 대신 호출할 수 있는 미리 만들어진 개체 및 함수 집합입니다. 웹 페이지에서 브라우저는 많은 정보를 전달하고 가져오기를 통해 서버의 API와 통신할 수 있습니다.

영문 원문 보기

브라우저 JavaScript에서 API(응용 프로그래밍 인터페이스)는 직접 작성하지 않고도 작업을 수행하기 위해 호출할 수 있는 개체 및 함수 집합입니다. 브라우저는 모든 페이지에 Web API라는 대규모 세트를 제공합니다.

세 가지를 먼저 만나보실 수 있습니다: 페이지용 document, 브라우저 및 장치용 navigator, 네트워크용 fetch.

두 번째 의미는 서버 API입니다. 이는 데이터(주로 JSON)로 요청에 응답하는 인터넷의 또 다른 프로그램입니다. 브라우저에서는 그 자체가 웹 API인 fetch를 사용하여 접근할 수 있습니다. 이 가이드에서는 두 가지 모두를 다룹니다.

첫 번째 것을 시도해 보세요. 버튼을 누른 다음 창 크기를 조정하세요.

실행 예제직접 써 보고 코드를 복사하세요
링크로 공유하기
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Web APIs in one page</title>
<style>
  body { margin: 0; padding: 18px; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  button { font: inherit; padding: 9px 16px; border: 0; border-radius: 8px; background: #2563eb; color: #fff; cursor: pointer; }
  table { margin-top: 14px; width: 100%; max-width: 460px; border-collapse: collapse; background: #fff; border-radius: 10px; overflow: hidden; }
  td { padding: 8px 10px; border-bottom: 1px solid #eceef2; font-size: 14px; }
  td code { font-size: 12.5px; color: #6b7280; }
  td:last-child { font-weight: 600; text-align: right; }
</style>
</head>
<body>
<button id="ask">Ask the browser</button>

<table>
  <tr><td>Language<br><code>navigator.language</code></td><td id="lang">?</td></tr>
  <tr><td>Window width<br><code>window.innerWidth</code></td><td id="width">?</td></tr>
  <tr><td>Online<br><code>navigator.onLine</code></td><td id="online">?</td></tr>
  <tr><td>Page title<br><code>document.title</code></td><td id="title">?</td></tr>
</table>

<script>
  // document, navigator and window are objects the browser gives every page
  const show = (id, value) => document.getElementById(id).textContent = value;

  function ask() {
    show('lang', navigator.language);
    show('width', window.innerWidth + 'px');
    show('online', navigator.onLine ? 'yes' : 'no');
    show('title', document.title);
  }

  document.getElementById('ask').addEventListener('click', ask);
  // APIs also send events: update the width when the window is resized
  window.addEventListener('resize', () => show('width', window.innerWidth + 'px'));
</script>
</body>
</html>
세 개의 브라우저 개체에서 네 개의 값을 읽습니다. 라이브러리도 없고 서버도 없습니다.

여기에는 아무것도 설치되지 않았습니다. navigator, window 및 document는 모든 페이지에 존재하며 바로 사용할 수 있습니다.

JavaScript와 Web API는 같은 것이 아닙니다

JavaScript 언어는 Math, JSON, Date 및 Promise와 같은 기능을 제공합니다. 페이지, 장치 또는 네트워크에 닿는 모든 것은 브라우저에서 나옵니다. MDN은 "JavaScript 언어 위에 위치하는" 브라우저 API 구성을 호출합니다.

왼쪽: 언어의 일부. 오른쪽: 브라우저에서 제공됩니다. 둘 다 같은 방식으로 호출합니다.
왼쪽: 언어의 일부. 오른쪽: 브라우저에서 제공됩니다. 둘 다 같은 방식으로 호출합니다.

이는 도움을 검색할 때 중요합니다. 페이지의 텍스트 변경에 대한 질문은 JavaScript 구문 질문이 아니라 DOM 질문입니다.

모든 API의 구성 방식

브라우저 API는 동일한 패턴을 따르므로 한 번 사용하면 다음은 익숙합니다.

  • 진입점. 시작하는 개체: document, navigator.geolocation, 캔버스의 getContext().
  • navigator.language와 같이 읽는 속성.
  • 메서드 호출(예: document.getElementById()).
  • 이벤트 API가 resize와 같이 보내는 이벤트입니다. addEventListener로 청취합니다.

일부 최신 API는 HTTPS를 통해 제공되는 페이지에서만 실행되며 일부는 먼저 사용자에게 권한을 요청합니다. 예를 들어 알림 API는 권한 프롬프트를 표시합니다.

종류 그것이 사는 곳 예 요구 사항
브라우저 API 브라우저 내부 document, navigator 아무것도; 그것은 내장되어있다
권한이 있는 브라우저 API 브라우저 내부 알림, 지리적 위치 사용자가 그렇다고 대답함
서버 API HTTP를 통해 도달한 또 다른 프로그램 fetch('/api/products') URL; 때로는 열쇠

API를 사용하기 전에 API가 존재하는지 확인하세요.

모든 브라우저에 모든 API가 있는 것은 아닙니다. 누락된 항목을 호출하면 오류가 발생하고 나머지 스크립트가 중지됩니다. MDN의 대답은 기능 감지입니다. 해당 속성이 상위 개체에 존재하는지 확인하세요.

if ('geolocation' in navigator) {
  navigator.geolocation.getCurrentPosition(show);
} else {
  showManualForm();
}

이 페이지는 브라우저에서 다음과 같은 8가지 검사를 실행합니다.

실행 예제직접 써 보고 코드를 복사하세요
링크로 공유하기
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Feature detection</title>
<style>
  body { margin: 0; padding: 18px; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  p { margin: 0 0 12px; font-size: 14px; }
  ul { list-style: none; margin: 0; padding: 0; max-width: 460px; background: #fff; border-radius: 10px; }
  li { display: flex; justify-content: space-between; gap: 10px; padding: 8px 12px; border-bottom: 1px solid #eceef2; font-size: 14px; }
  li code { font-size: 13px; }
  .yes { color: #0f5132; font-weight: 600; }
  .no { color: #9a3412; font-weight: 600; }
</style>
</head>
<body>
<p>Secure context: <b id="secure"></b></p>
<ul id="list"></ul>

<script>
  // Each check asks: does this object have this property?
  const checks = [
    ['fetch', 'fetch' in window],
    ['navigator.geolocation', 'geolocation' in navigator],
    ['navigator.clipboard', 'clipboard' in navigator],
    ['navigator.share', 'share' in navigator],
    ['navigator.vibrate', 'vibrate' in navigator],
    ['navigator.serviceWorker', 'serviceWorker' in navigator],
    ['Notification', 'Notification' in window],
    ['IntersectionObserver', 'IntersectionObserver' in window],
  ];

  const list = document.getElementById('list');
  for (const [name, ok] of checks) {
    const li = document.createElement('li');
    li.innerHTML = '<code>' + name + '</code><span class="' + (ok ? 'yes">available' : 'no">missing') + '</span>';
    list.append(li);
  }
  document.getElementById('secure').textContent = window.isSecureContext ? 'yes' : 'no';
</script>
</body>
</html>
각 줄은 하나의 검사입니다. 다른 브라우저에서 열면 목록이 변경될 수 있습니다.

Chromium, Firefox 및 WebKit 엔진을 사용한 테스트에서 navigator.vibrate는 Chromium에서만 사용할 수 있었습니다. 이것이 바로 수표가 귀하의 코드에 속하는 이유입니다. HTML의 위치정보는 하나의 권한 기반 API의 전체 예를 보여줍니다.

가져오기를 사용하여 서버 API 호출

서버 API는 데이터를 반환하는 URL입니다. fetch(url)는 Response로 해결되는 약속을 반환합니다. 그런 다음 그것을 확인하고 본문을 읽으십시오.

묻고, 서버가 응답하도록 하고, 상태를 확인한 다음 데이터를 읽고 표시합니다.
묻고, 서버가 응답하도록 하고, 상태를 확인한 다음 데이터를 읽고 표시합니다.
async function loadProducts() {
  const response = await fetch('/api/products');
  if (!response.ok) throw new Error('Server answered ' + response.status);
  const products = await response.json();
  // put products on the page
}

두 개의 키워드가 대기를 수행합니다. await는 약속이 확정될 때까지 일시 중지됩니다. 비동기 및 대기가 이에 대해 설명합니다. response.json()는 JSON.parse와 동일한 작업인 본문을 구문 분석합니다.

항상 response.ok를 확인하세요

fetch는 네트워크 오류 또는 잘못된 URL과 같은 오류가 있는 경우 거부합니다. 서버가 404 또는 500으로 응답하면 가져오기는 계속 성공하고 오류 페이지가 본문으로 도착합니다.

확인하지 않으면 실제 문제는 혼란스러운 JSON 오류가 됩니다.
확인하지 않으면 실제 문제는 혼란스러운 JSON 오류가 됩니다.

확인하지 않고 json()는 HTML 오류 페이지를 구문 분석하려고 시도하고 SyntaxError를 발생시킵니다. 하나의 if (!response.ok) 라인은 이를 명확한 메시지로 바꿉니다.

완성된 예: 로드, 실패, 재시도

이 버전에는 각 실패에 대한 로딩 메시지, 목록 및 읽을 수 있는 오류가 있습니다. 대체 기능이 네트워크를 대체합니다. fakeFetch는 실제 Response 개체를 반환하므로 그 뒤의 코드는 fetch로 작성하는 코드와 정확히 같습니다.

실행 예제직접 써 보고 코드를 복사하세요
링크로 공유하기
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Show API data</title>
<style>
  body { margin: 0; padding: 18px; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  .bar { display: flex; flex-wrap: wrap; gap: 8px; }
  button { font: inherit; font-size: 14px; padding: 8px 12px; border: 1px solid #d5d9e0; border-radius: 8px; background: #fff; cursor: pointer; }
  button.main { background: #2563eb; border-color: #2563eb; color: #fff; }
  #status { margin: 12px 0 8px; font-size: 14px; color: #6b7280; }
  #status.error { color: #9a3412; font-weight: 600; }
  ul { list-style: none; margin: 0; padding: 0; max-width: 460px; }
  li { display: flex; justify-content: space-between; padding: 9px 12px; margin-bottom: 6px; background: #fff; border-radius: 8px; font-size: 14px; }
</style>
</head>
<body>
<div class="bar">
  <button class="main" data-case="ok">Load products</button>
  <button data-case="404">Server says 404</button>
  <button data-case="offline">Network fails</button>
</div>
<p id="status">Press a button.</p>
<ul id="list"></ul>

<script>
  // Stand-in for fetch(url): it returns a real Response object, without the network.
  // On your own site, replace fakeFetch(...) with fetch('/api/products').
  function fakeFetch(kind) {
    return new Promise((resolve, reject) => setTimeout(() => {
      if (kind === 'offline') reject(new TypeError('Failed to fetch'));
      else if (kind === '404') resolve(new Response('Not found', { status: 404 }));
      else resolve(new Response(JSON.stringify([
        { name: 'Notebook', price: 4.5 },
        { name: 'Pen set', price: 7 },
        { name: 'Desk lamp', price: 24.99 },
      ]), { headers: { 'Content-Type': 'application/json' } }));
    }, 600));
  }

  const status = document.getElementById('status');
  const list = document.getElementById('list');

  async function load(kind) {
    status.className = '';
    status.textContent = 'Loading...';
    list.innerHTML = '';
    try {
      const response = await fakeFetch(kind);
      // a 404 or 500 does not throw by itself, so check ok
      if (!response.ok) throw new Error('Server answered ' + response.status);
      const products = await response.json();  // text -> objects
      for (const p of products) {
        const li = document.createElement('li');
        li.innerHTML = '<span></span><b></b>';
        li.firstChild.textContent = p.name;  // textContent: data is never run as HTML
        li.lastChild.textContent = '$' + p.price.toFixed(2);
        list.append(li);
      }
      status.textContent = products.length + ' products loaded.';
    } catch (err) {
      status.className = 'error';
      status.textContent = 'Could not load: ' + err.message;
    }
  }

  document.querySelectorAll('[data-case]').forEach((btn) =>
    btn.addEventListener('click', () => load(btn.dataset.case)));
</script>
</body>
</html>
목록을 로드한 다음 서버가 404를 반환하게 하고 네트워크가 실패하게 만듭니다.
  • 로드 상태: await 앞에 상태 텍스트를 설정합니다.
  • 오류: 하나의 try...catch가 잘못된 상태와 네트워크 오류를 모두 처리합니다.
  • 안전한 출력: textContent는 페이지에 API 데이터를 텍스트로 표시하므로 HTML로 실행되지 않습니다.

실제 서버를 사용하려면 fakeFetch(kind)를 fetch('/api/products')로 바꾸세요. 그러면 페이지가 아닌 서버에 따라 두 가지 사항이 달라집니다.

CORS:  a server on another site must send Access-Control-Allow-Origin
       for your page, or the browser hides the answer from your script.
Keys:  if the API needs a secret key, call it from your own server.
       MDN warns never to embed API keys in front-end code
       unless the API vendor explicitly allows it.

CORS 설명에서 첫 번째 항목을 자세히 다룹니다.

작동하지 않을 때

당신이 보는 것 원인 수정
null 속성을 읽을 수 없습니다. 요소가 존재하기 전에 스크립트가 실행되었습니다. body 끝에 있는 요소 뒤의 스크립트를 넣으세요.
데이터 대신 [object Promise] await 누락 await async 함수 내부 호출
json()의 구문 오류 서버가 HTML 오류 페이지를 보냈습니다. json() 이전에 response.ok를 확인하세요.
콘솔의 CORS 오류 다른 사이트에서는 귀하의 페이지를 허용하지 않습니다 이를 허용하는 API를 사용하거나 서버에서 호출하세요.
... is not a function 또는 정의되지 않음 이 브라우저에는 API가 없거나 페이지가 HTTPS가 아닙니다. 기능 감지 및 HTTPS를 통해 페이지 제공
로드 시 소리가 시작되지 않습니다. 자동재생 정책 버튼 클릭으로 오디오 시작

아무것도 실행되지 않으면 HTML JavaScript가 작동하지 않음을 순서대로 해결하세요.

링크로 공유하세요

브라우저 API를 호출하는 페이지는 설명하는 것보다 시도해 보는 것이 더 쉽습니다. 스크린샷은 클릭할 수 없으며, 스크린샷에 표시되는 값은 독자의 것이 아닌 브라우저에 속합니다.

작업 버전을 보내려면 페이지를 NOS 문서에 붙여넣고 공유 링크 만들기를 선택하세요. 링크할 HTML이 이를 안내합니다.

페이지는 작성된 대로 렌더링되고 해당 스크립트가 실행되므로 링크가 있는 사람은 누구나 계정 없이 자신의 브라우저에서 버튼을 누를 수 있습니다. 나중에 코드를 변경하면 동일한 링크에 새 버전이 표시됩니다.

한 가지 제한 사항: 공유 NOS 페이지에서는 다른 사이트에 대한 가져오기 호출이 차단됩니다. DOM과 같은 브라우저 API가 작동하므로 완성된 예제에서는 라이브 서버 대신 독립 Response를 사용합니다.

자주 묻는 질문

API는 무엇을 의미하나요?

응용 프로그래밍 인터페이스. MDN은 API를 간단한 구문 뒤에 복잡한 코드를 숨겨 개발자가 복잡한 기능을 더 쉽게 만들 수 있는 구조로 설명합니다.

가져오기는 JavaScript의 일부인가요?

아니요. 가져오기는 브라우저가 제공하는 웹 API입니다. MDN은 Math, JSON 및 Promise와 같은 JavaScript 언어 자체 내장 객체와 Web API 참조에 브라우저가 제공하는 문서 객체를 별도로 나열합니다.

API 키가 필요합니까?

DOM이나 자체 가져오기와 같은 브라우저 API에는 적합하지 않습니다. 내장되어 있습니다. 일부 타사 API에는 키가 필요합니다. MDN은 공급자가 명시적으로 허용하지 않는 한 이러한 키를 프런트엔드 코드에 절대 넣지 말라고 경고합니다. 왜냐하면 모든 방문자가 키를 읽을 수 있기 때문입니다.

단일 HTML 파일이 서버의 API를 호출할 수 있습니까?

예, 가져오기를 사용합니다. 서버가 다른 사이트에 있는 경우 페이지를 허용하는 Access-Control-Allow-Origin 헤더를 보내야 합니다. 그렇지 않으면 브라우저에서 스크립트가 답변을 읽도록 허용하지 않습니다.

브라우저가 API를 지원하는지 어떻게 알 수 있나요?

사용하기 전에 내비게이터의 '지리적 위치' 등을 확인하세요. MDN에서는 이 기능 감지를 호출합니다. API가 있으면 API를 실행하고, 없으면 다른 것을 표시합니다.