인증이 된 사용자만 파일 다운로드가 가능해야하는 상황이라서 일반적인 a href를 쓸 수 없었다. 이런 경우 이런 식으로 파일 다운로드를 진행해야하는 것 같았다. 

간단해보이는 소스지만, 이 조합을 찾아내기까지 하루이상의 시간이 소요되었기 때문에 다음에는 헤매지 않기 위해 기록해둔다.

 

1. Express

import { join } from 'path';

...

router.get('/subpath/:id', async (req, res, next) => {
    const id = req.params.id;

    const filePath = join(__dirname, `서버에 저장된하위경로`);
    const filename = '파일명.확장자';
    
    // 1안
    res.setHeader('Content-Disposition', `attachment; filename=다른파일명가능`); // 필수
    res.sendFile(filePath + filename);

    // 2안
    res.download(filePath + filename); // 서버에 저장된 파일명으로만 가능

    // 3안
    res.setHeader('Content-Disposition', `attachment; filename=다른파일명가능`); // 필수
    const stream = fs.createReadStream(filePath + filename);
    stream.pipe(res);
});

출처: 불특정 다수

 

2. Front

const authHeader = 'token값'
const url = `/api/subpath/${id}`
let filename = '' // 서버에서 보내는 파일명이 담길 변수

fetch(url, { headers: { 'X-Auth-Token': authHeader } })
    .then((response) => {
        if (!response.ok) {
            throw Error(response.statusText)
        }

        const header = response.headers.get('Content-Disposition')
        const parts = header.split(';')
        filename = parts[1].split('=')[1].replaceAll('"', '')

        return response.blob()
    })
    .then((blob) => {
        if (blob != null) {
            var url = window.URL.createObjectURL(blob)
            var a = document.createElement('a')
            a.href = url
            a.download = filename
            document.body.appendChild(a)
            a.click()
            a.remove()
        }
    })
    .catch((err) => {
        console.log(err)
    })

출처: https://christosmonogios.com/2022/05/10/Use-the-Fetch-API-to-download-files-with-their-original-filename-and-the-proper-way-to-catch-server-errors/

 

front의 경우 이거 말고도 new ReadableStream에 new Response 동원해서 하는 복잡한 소스도 있었는데 위가 더 심플하고 속도도 체감될 정도로 빨라서 이 걸로 낙찰했다.

 

'Javascript' 카테고리의 다른 글

정렬 sort  (0) 2021.04.01
jQuery to VanillaJS  (0) 2021.03.16
키보드를 이용한 Input text 포커스 이동  (0) 2021.03.15
String to Date / Date to String  (0) 2020.12.17
숫자에 콤마와 언콤마를 편하게  (0) 2016.06.27

잘쓰던 포트였는데 갑자기 문제가 발생했다.

아래의 내용은 윈도우OS에서의 해결책이다.

 

내 원인

나의 경우에는 intellij에서 해당 포트와의 연결을 끊고 프로그램을 종료 했는데 그 후 재부팅을 하고 어쩌고 해도 저 포트를 사용할 수 없었다. 일반 콘솔에서도 동일한 에러가 발생하고 있었다.

 

해결

관리자 모드로 콘솔 혹은 파워셀을 연다.

net stop winnat
net start winnat

잘 된다.

 

출처: https://stackoverflow.com/questions/9164915/node-js-eacces-error-when-listening-on-most-ports

trigger를 통해서 값이 insert되면 외부 프로그램, 혹은 API를 호출하고 싶었다.

그때마다 검색되는 UDF인 sys_exec() 는 my_global.h가 없어 컴파일이 안되어 사용할 수 없는 상황이었다.

(MySQL 5에서는 있었지만 8 혹은 마이너 버전부터 제외한다는 글을 본 것 같다.)

mysql 내부에서 해결하는 것은 포기하고 돌도 돌다 node.js에 binlog를 이용하여 테이블을 감시하는 것을 찾았다.

https://www.npmjs.com/package/@vlasky/mysql-live-select

원래는 목적으로는 특정 레코드의 컬럼까지 감시가 가능한 것 같지만, 나는 테이블만 감시하는 목적으로 사용하려고 했고, 제공된 예제를 아래와 같이 수정하니 목적을 달성할 수 있게 되었다.

const LiveMysql = require('@vlasky/mysql-live-select');
const LiveMysqlKeySelector = require('@vlasky/mysql-live-select/lib/LiveMysqlKeySelector');

const settings = {
  host: '호스트주소',
  user: '아이디',
  password: '비밀번호',
  database: 'DB명'
};

const liveConnection = new LiveMysql(settings);

liveConnection
  .select('select version()', [], LiveMysqlKeySelector.Index(), [
    {
      table: '테이블명',
      condition: function (row, newRow, rowDeleted) {
        if (row && newRow === null) {
          if (rowDeleted === false) {
            // insert 상황            
          } else {
            // delete 상황
          }
        } else {
          // update 상황
        }
        return true;
      }
    }
  ]);
git config core.ignorecase false

 

tar 압축

find `ls` -type d -maxdepth 0 -exec tar -cvf "{}.tar" "{}" \;

 

zip 압축
find `ls` -type d -maxdepth 0 -exec zip -r -9 "{}.zip" "{}" \;

 

주의사항

maxdepth가 0이라 최상위 레벨까지만 압축한다.

+ Recent posts