NextJS + Fetch + Api 경로 + Typescript로 파일 업로드
29929 단어 javascripttypescriptnextjsreact
우선 다음을 실행하여 NextJs 애플리케이션을 생성해 보겠습니다.
yarn create next-app --typescript
설치가 완료되면 yarn dev를 실행하여 http://localhost:3000에서 개발 서버를 시작합니다.
페이지를 열면 다음과 유사한 내용이 표시됩니다.
이제 양식 데이터를 구문 분석하는 데 도움이 되는 패키지를 설치해 보겠습니다.
yarn add -D formidable @types/formidable
양식 만들기
파일을 업로드할 수 있는 작은 양식을 만들 것입니다. 더 명확하게 하기 위해 코드를 단순화하겠습니다.
pages/index.js
로 이동하여 모든 기본 코드를 다음으로 바꿉니다.import type { NextPage } from 'next'
import React from "react";
const Home: NextPage = () => {
const [isLoading, setIsLoading] = React.useState(false);
const inputFileRef = React.useRef<HTMLInputElement | null>(null);
const handleOnClick = async (e: React.MouseEvent<HTMLInputElement>) => {
/* Prevent form from submitting by default */
e.preventDefault();
/* If file is not selected, then show alert message */
if (!inputFileRef.current?.files?.length) {
alert('Please, select file you want to upload');
return;
}
setIsLoading(true);
/* Add files to FormData */
const formData = new FormData();
Object.values(inputFileRef.current.files).forEach(file => {
formData.append('file', file);
})
/* Send request to our api route */
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const body = await response.json() as { status: 'ok' | 'fail', message: string };
alert(body.message);
if (body.status === 'ok') {
inputFileRef.current.value = '';
// Do some stuff on successfully upload
} else {
// Do some stuff on error
}
setIsLoading(false);
};
return (
<form>
<div>
<input type="file" name="myfile" ref={inputFileRef} multiple />
</div>
<div>
<input type="submit" value="Upload" disabled={isLoading} onClick={handleOnClick} />
{isLoading && ` Wait, please...`}
</div>
</form>
)
}
export default Home
여기서는 여러 파일 업로드를 사용하고 있습니다. 하나의 파일만 업로드하려면
multiple
에서 input:file
를 제거하십시오.<input type="file" name="myfile" ref={inputFileRef} />
API 경로
업로드된 파일을 처리할 엔드포인트를 생성해 보겠습니다.
filepages/api/upload.ts
를 생성합니다.import type { NextApiRequest, NextApiResponse } from 'next'
import { promises as fs } from "fs";
import path from "path";
import formidable, { File } from 'formidable';
/* Don't miss that! */
export const config = {
api: {
bodyParser: false,
}
};
type ProcessedFiles = Array<[string, File]>;
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
let status = 200,
resultBody = { status: 'ok', message: 'Files were uploaded successfully' };
/* Get files using formidable */
const files = await new Promise<ProcessedFiles | undefined>((resolve, reject) => {
const form = new formidable.IncomingForm();
const files: ProcessedFiles = [];
form.on('file', function (field, file) {
files.push([field, file]);
})
form.on('end', () => resolve(files));
form.on('error', err => reject(err));
form.parse(req, () => {
//
});
}).catch(e => {
console.log(e);
status = 500;
resultBody = {
status: 'fail', message: 'Upload error'
}
});
if (files?.length) {
/* Create directory for uploads */
const targetPath = path.join(process.cwd(), `/uploads/`);
try {
await fs.access(targetPath);
} catch (e) {
await fs.mkdir(targetPath);
}
/* Move uploaded files to directory */
for (const file of files) {
const tempPath = file[1].filepath;
await fs.rename(tempPath, targetPath + file[1].originalFilename);
}
}
res.status(status).json(resultBody);
}
export default handler;
축하합니다. 완료되었습니다! 양식을 테스트할 수 있습니다!
모든 파일은 프로젝트 루트 내의 디렉터리
/uploads
에 저장됩니다.Api 경로를 프록시로 사용
여기서는 파일을 저장하고 파일에 대해 어려운 작업을 수행하고 싶지 않기 때문에 파일을 다른 서버로 전송해야 한다고 가정해 보겠습니다.
몇 가지 새 패키지를 추가합니다.
yarn add -D form-data node-fetch
널 바꿔
/pages/api/upload.ts to
:import type { NextApiRequest, NextApiResponse } from 'next'
import fs from "fs";
import fetch from "node-fetch";
import FormData from 'form-data';
import formidable, { File } from 'formidable';
export const config = {
api: {
bodyParser: false,
}
};
type ProcessedFiles = Array<[string, File]>;
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
let status = 200,
resultBody = { status: 'ok', message: 'Files were uploaded successfully' };
/* Get files using formidable */
const files = await new Promise<ProcessedFiles | undefined>((resolve, reject) => {
const form = new formidable.IncomingForm();
const files: ProcessedFiles = [];
form.on('file', function (field, file) {
files.push([field, file]);
})
form.on('end', () => resolve(files));
form.on('error', err => reject(err));
form.parse(req, () => {
//
});
}).catch(e => {
console.log(e);
status = 500;
resultBody = {
status: 'fail', message: 'Upload error'
}
});
if (files?.length) {
/* Add files to FormData */
const formData = new FormData();
for (const file of files) {
formData.append(file[0], fs.createReadStream(file[1].filepath));
}
/* Send request to another server */
const response = await fetch('PATH_TO_ANOTHER_SERVER', {
headers: formData.getHeaders(),
method: 'POST',
body: formData
});
// Do anything you need with response
}
res.status(status).json(resultBody);
}
export default handler;
교체하는 것을 잊지 마십시오
PATH_TO_ANOTHER_SERVER
.이거야, 즐기자! 전체 저장소https://github.com/gapon2401/upload-files-nextjs
Reference
이 문제에 관하여(NextJS + Fetch + Api 경로 + Typescript로 파일 업로드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/igaponov/upload-files-with-nextjs-fetch-api-routes-typescript-4k23텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)