editor

이미지 업로드

이미지를 내 서버로 올리기: 함수, URL, 서버 예제(PHP·Node·Workers·Spring).

아무 설정이 없으면 이미지는 base64로 글 안에 들어갑니다. 글이 커지므로 운영 사이트에서는 서버로 올리세요. 파일 선택, 드래그, 붙여넣기, 다른 사이트에서 복사한 이미지 모두 같은 길로 올라갑니다.

1. 업로드 함수 넘기기 (권장)

createEditor('#editor', {
  imageMaxSize: 10 * 1024 * 1024,
  uploadImage: async (file, { onProgress }) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/upload', { method: 'POST', body: form });
    if (!res.ok) throw new Error('업로드 실패');
    const { url } = await res.json();
    return url; // 에디터가 이 주소로 <img> 를 넣습니다
  },
});

2. URL만 지정하기

createEditor('#editor', {
  uploadUrl: '/upload',
  uploadField: 'file',
  uploadHeaders: { 'X-CSRF-Token': token },
});
// 서버는 { "url": "https://…/a.png" } 를 돌려주면 됩니다.

PHP

<?php
// upload.php
$f = $_FILES['file'] ?? null;
$types = ['image/png' => 'png', 'image/jpeg' => 'jpg', 'image/gif' => 'gif', 'image/webp' => 'webp'];
$type = $f ? mime_content_type($f['tmp_name']) : '';
if (!$f || !isset($types[$type]) || $f['size'] > 10485760) { http_response_code(400); exit; }
$name = bin2hex(random_bytes(16)) . '.' . $types[$type];
move_uploaded_file($f['tmp_name'], __DIR__ . '/files/' . $name);
header('Content-Type: application/json');
echo json_encode(['url' => '/files/' . $name]);

Node (Express + multer)

import express from 'express';
import multer from 'multer';

const upload = multer({ dest: 'public/files', limits: { fileSize: 10 * 1024 * 1024 } });
const app = express();
app.post('/upload', upload.single('file'), (req, res) => {
  if (!req.file?.mimetype.startsWith('image/')) return res.status(400).end();
  res.json({ url: '/files/' + req.file.filename });
});

Cloudflare Workers + R2

export default {
  async fetch(req, env) {
    const form = await req.formData();
    const file = form.get('file');
    if (!file || !file.type.startsWith('image/')) return new Response('bad', { status: 400 });
    const key = crypto.randomUUID() + '.' + file.type.split('/')[1];
    await env.BUCKET.put(key, file.stream(), { httpMetadata: { contentType: file.type } });
    return Response.json({ url: 'https://files.example.com/' + key });
  },
};

Spring Boot

@PostMapping("/upload")
public Map<String, String> upload(@RequestParam("file") MultipartFile file) throws IOException {
  if (file.getContentType() == null || !file.getContentType().startsWith("image/")) throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
  String name = UUID.randomUUID() + ".png";
  file.transferTo(Path.of("/var/www/files", name));
  return Map.of("url", "/files/" + name);
}