파이썬/Fast API

[HTTP] 프론트엔드와 백엔드의 데이터 통신 Content-Type

코샵 2025. 1. 22. 10:52
반응형

소개

HTTP 통신에서 Content-Type은 서버와 클라이언트 간에 주고받는 데이터의 형식을 지정하는 중요한 헤더입니다. 이번 글에서는 Content-Type의 모든 것을 상세히 알아보겠습니다.

Content-Type이란?

Content-Type은 HTTP 헤더의 일부로, MIME(Multipurpose Internet Mail Extensions) 타입을 사용하여 데이터의 형식을 지정합니다.

주요 Content-Type 형식

텍스트 형식

// 일반 텍스트
Content-Type: text/plain

// HTML
Content-Type: text/html

// CSS
Content-Type: text/css

// JavaScript
Content-Type: text/javascript

애플리케이션 데이터

// JSON
Content-Type: application/json

// XML
Content-Type: application/xml

// 폼 데이터
Content-Type: application/x-www-form-urlencoded

// 바이너리 데이터
Content-Type: application/octet-stream

멀티미디어

// 이미지
Content-Type: image/jpeg
Content-Type: image/png
Content-Type: image/gif

// 오디오
Content-Type: audio/mpeg
Content-Type: audio/wav

// 비디오
Content-Type: video/mp4
Content-Type: video/webm

실제 사용 예시

JSON 데이터 전송

// 프론트엔드
const sendJsonData = async (data) => {
  const response = await fetch('/api/data', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  });
  return response.json();
};

// 백엔드 (FastAPI)
@app.post("/api/data")
async def handle_json(request: Request):
    json_data = await request.json()
    return {"received": json_data}

파일 업로드

// 프론트엔드 (FormData 사용)
const uploadFile = async (file) => {
  const formData = new FormData();
  formData.append('file', file);

  const response = await fetch('/api/upload', {
    method: 'POST',
    body: formData
    // Content-Type은 브라우저가 자동으로 설정
  });
  return response.json();
};

// 백엔드 (FastAPI)
@app.post("/api/upload")
async def upload_file(file: UploadFile):
    contents = await file.read()
    return {"filename": file.filename}

폼 데이터 전송

// HTML 폼
<form action="/api/submit" method="post">
  <input type="text" name="username">
  <input type="password" name="password">
  <button type="submit">Submit</button>
</form>

// 백엔드 (FastAPI)
@app.post("/api/submit")
async def handle_form(request: Request):
    form_data = await request.form()
    return {"received": dict(form_data)}

 

문자셋 지정

// UTF-8 인코딩 지정
Content-Type: text/html; charset=utf-8

// 다른 인코딩 사용
Content-Type: text/plain; charset=iso-8859-1

주의사항과 모범 사례

적절한 Content-Type 선택

// 데이터 형식에 따른 올바른 Content-Type 선택
const sendData = async (data, type) => {
  let contentType;
  let body;

  switch(type) {
    case 'json':
      contentType = 'application/json';
      body = JSON.stringify(data);
      break;
    case 'form':
      contentType = 'application/x-www-form-urlencoded';
      body = new URLSearchParams(data);
      break;
    case 'file':
      // FormData의 경우 Content-Type 자동 설정
      body = data;
      break;
  }

  const response = await fetch('/api/data', {
    method: 'POST',
    headers: contentType ? {
      'Content-Type': contentType
    } : {},
    body: body
  });

  return response.json();
};

에러 처리

// Content-Type 검증
const validateContentType = (request) => {
  const contentType = request.headers.get('Content-Type');

  if (!contentType) {
    throw new Error('Content-Type header is missing');
  }

  if (!contentType.includes('application/json')) {
    throw new Error('Content-Type must be application/json');
  }
};

보안 고려사항

XSS 방지

// Content-Type과 함께 보안 헤더 설정
const secureHeaders = {
  'Content-Type': 'text/html; charset=utf-8',
  'Content-Security-Policy': "default-src 'self'",
  'X-Content-Type-Options': 'nosniff'
};

MIME 타입 스니핑 방지

// 서버 응답 헤더 설정
response.headers['X-Content-Type-Options'] = 'nosniff';

마치며

Content-Type은 웹 애플리케이션에서 데이터를 주고받을 때 매우 중요한 역할을 합니다. 적절한 Content-Type을 사용하면 데이터 통신의 안정성과 보안성을 높일 수 있습니다.