티스토리 뷰
nextjs+typescript 기반 CMS 개발 프로젝트
[nextjs/typescript] 파일업로드+프로그래스바 구현(backend/frontend)
개발자 고포고 2022. 3. 15. 21:04반응형
[nextjs/typescript] 파일업로드 구현(backend/frontend)
#필요 라이브러리
multer
next-connect
axios
#라이브러리 설치
$npm i axios multer next-connect
os
# pages/api/upload/index.tsx
- config:bodyParser를 false로 지정함으로써 stream을 허용한다.
- next-connect를 활용하여, 미들웨어수준에서 file정보를 명시하여준다.
import nc from "next-connect";
import multer from "multer";
import path from "path";
import { NextApiRequest, NextApiResponse } from "next";
import { ResponseType } from "@libs/server/withHandler";
//stream 사용을 위하여 fasle 처리
export const config = {
api: {
bodyParser: false,
},
};
//next-connect는 express에서 제공하는
const handler = nc();
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/upload");
},
filename: function (req, file, cb) {
cb(
null,
file.fieldname + "-" + Date.now() + path.extname(file.originalname)
);
},
});
let upload = multer({
storage: storage,
});
let uploadFile = upload.single("file");
handler.use(uploadFile);
handler.post(
async (req: NextApiRequest, res: NextApiResponse<ResponseType>) => {
console.log("req.file", req.file);
console.log("req.body", req.body);
let url = "http://" + req.headers.host;
let filename = req.file.filename;
console.log(filename);
res.status(200).send({
ok: true,
result: url + "/public/" + req.file.filename,
});
}
);
export default handler;
#pages/monitoring1.tsx
-submit 이벤트 발생
-e:React.FormEvent<HTMLFormElement> 객체로 받는다.
-Formdate 객체를 생성하여, 이름을 맞춰 넣는다.
-header에 Content-Type:multipart/form-data 타입을 명시하여준다.
-onUploadProgress 이벤트를 등록하여 현재 %이벤트를 받아온다.
import type { NextPage } from "next";
import React, { useState } from "react";
import axios from "axios";
const Monitoring1: NextPage = () => {
const [pValue, setpValue] = useState(0);
const [file, setFile] = useState();
const [uploadedFile, setUploadedFile] = useState({});
const onChange = (e: React.FormEvent<HTMLInputElement>) => {
setFile(e.target.files[0]);
console.log(e.target.files[0].name);
};
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log(file);
const formData = new FormData();
formData.append("file", file);
formData.append("data", { name: "gofogo" });
try {
const res = await axios.post("/api/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
onUploadProgress: (progressEvent: any) => {
let pert = (progressEvent.loaded * 100) / progressEvent.total;
console.log(pert);
setpValue(pert / 100);
},
});
console.log(res.data);
const { ok, result } = res.data;
setUploadedFile({ ok, result });
} catch (err) {}
};
return (
<div>
<form onSubmit={onSubmit}>
<input type="file" onChange={onChange} />
<input type="submit" value="upload" />
</form>
<progress value={pValue} />
</div>
);
};
export default Monitoring1;
#react #nextjs #typescript #upload #file #stream #axios #multer #next-connect #api
반응형
'nextjs+typescript 기반 CMS 개발 프로젝트' 카테고리의 다른 글
[nextjs/ts/react] 로그인 페이지 [완성] -기본 구성 설명- (0) | 2022.03.14 |
---|---|
[nextjs+ts]프로젝트 06. api request middleware 만들기(nextjs) (0) | 2022.03.13 |
[nextjs+ts]프로젝트 05.로그인 페이지 react-hook-form을 활용한 리펙토링 (0) | 2022.03.13 |
[prisma+nextjs] api 서비스 개발하기 (0) | 2022.03.12 |
[prisma+PlanetScale]스크립트 작성하여 DB(PlanetScale)에 동기화하기 (0) | 2022.03.12 |
댓글
반응형