modules/FetchEventSource.js
const { fetch, Headers, Request, Response } = require('fetch-undici'); if (!globalThis.fetch) { globalThis.fetch = fetch; globalThis.Headers = Headers; globalThis.Request = Request; globalThis.Response = Response; } module.exports = require('@waylaidwanderer/fetch-event-source');
server.js
const express = require('express'); const bodyParser = require('body-parser'); const { fetchEventSource } = require('./modules/FetchEventSource'); const app = express(); const router = express.Router(); router.post('/request', (request, response) => { const url = 'https://ailab.synap.co.kr/sdk/ocr'; const apiKey = 'OCR_API_KEY'; const bodyData = Object.assign({}, request.body, { url: 'https://ailab.synap.co.kr/sdk/ocr', formData: { api_key: OCR_API_KEY, image: fs.createReadStream(imgPath), page_index: page, ...OCROption } }); const abortController = new AbortController(); (new Promise(async (resolve, reject) => { try { await fetchEventSource(url, { method: 'post', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(bodyData), signal: abortController.signal, onopen: async (openResponse) => { if (openResponse.status === 200) { response.on('close', () => { abortController.abort(); resolve(); }); response.set({ 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Content-Type': 'text/event-stream' }); response.flushHeaders(); return; } let error; try { const json = await openResponse.json(); error = json; } catch (e) { error = e; } error.status = openResponse.status; throw error; }, onclose: () => resolve(), onerror: (error) => { reject(error); throw error; }, onmessage: (message) => { if (!message.data || message.event === 'ping') { return; } response.write('data:' + message.data + '\n\n'); }, }); } catch (e) { reject(e); } })).then(() => response.end()) .catch((error) => response.status(error.status).json(error).end()); }); app.use(bodyParser.json()); app.use('/', router); app.listen(8080);