Golang 및 React를 사용한 이미지 업로드
41268 단어 gofiberreactjavascriptgo
이 블로그 게시물에서는 gofiber를 사용하여 간단한 이미지 업로드 서버를 만들고 프론트엔드용 reactjs를 사용하여 파일에서 이미지를 선택하고 서버에 업로드합니다.
우리는 서버에 대한 http 요청에 axios를 사용할 것이며 인증을 구현하고 많은 api 요청을 처리할 때 정말 좋습니다. 그것은 반응에서 API를 다룰 때 삶을 쉽게 만드는 많은 기능을 가지고 있습니다.
우리는 더 나은 SEO에 직접적인 영향을 미치는 접근성에서 버튼, 이미지 및 레이아웃과 같은 재료를 디자인하기 위해 chakra ui를 사용할 것입니다.
우리가 사용할 라이브러리 및 도구
백엔드 설정
새 디렉토리를 만들고 입력하십시오.
mkdir go-react-image-upload
cd go-react-image-upload
server
내부에 새 디렉토리go-react-image-upload
를 생성하고 입력합니다.mkdir server
cd server
이동 환경 설정
go mod init github.com/harshmangalam
백엔드에 필요한 패키지 설치
go get github.com/gofiber/fiber/v2
go get github.com/google/uuid
uuid는 고유 ID를 생성하여 이미지 이름을 쉽게 지정하고 두 이미지의 이름이 동일하지 않도록 합니다.
main.go
안에 새로운 go 파일server
을 만들고 코드 작성을 시작합니다.package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/google/uuid"
)
func main() {
// create new fiber instance and use across whole app
app := fiber.New()
// middleware to allow all clients to communicate using http and allow cors
app.Use(cors.New())
// serve images from images directory prefixed with /images
// i.e http://localhost:4000/images/someimage.webp
app.Static("/images", "./images")
// handle image uploading using post request
app.Post("/", handleFileupload)
// delete uploaded image by providing unique image name
app.Delete("/:imageName", handleDeleteImage)
// start dev server on port 4000
log.Fatal(app.Listen(":4000"))
}
func handleFileupload(c *fiber.Ctx) error {
// parse incomming image file
file, err := c.FormFile("image")
if err != nil {
log.Println("image upload error --> ", err)
return c.JSON(fiber.Map{"status": 500, "message": "Server error", "data": nil})
}
// generate new uuid for image name
uniqueId := uuid.New()
// remove "- from imageName"
filename := strings.Replace(uniqueId.String(), "-", "", -1)
// extract image extension from original file filename
fileExt := strings.Split(file.Filename, ".")[1]
// generate image from filename and extension
image := fmt.Sprintf("%s.%s", filename, fileExt)
// save image to ./images dir
err = c.SaveFile(file, fmt.Sprintf("./images/%s", image))
if err != nil {
log.Println("image save error --> ", err)
return c.JSON(fiber.Map{"status": 500, "message": "Server error", "data": nil})
}
// generate image url to serve to client using CDN
imageUrl := fmt.Sprintf("http://localhost:4000/images/%s", image)
// create meta data and send to client
data := map[string]interface{}{
"imageName": image,
"imageUrl": imageUrl,
"header": file.Header,
"size": file.Size,
}
return c.JSON(fiber.Map{"status": 201, "message": "Image uploaded successfully", "data": data})
}
func handleDeleteImage(c *fiber.Ctx) error {
// extract image name from params
imageName := c.Params("imageName")
// delete image from ./images
err := os.Remove(fmt.Sprintf("./images/%s", imageName))
if err != nil {
log.Println(err)
return c.JSON(fiber.Map{"status": 500, "message": "Server Error", "data": nil})
}
return c.JSON(fiber.Map{"status": 201, "message": "Image deleted successfully", "data": nil})
}
main.go
에서 server
실행go run main.go
이제 서버가 가동되어 Postman을 사용하여 테스트할 수 있습니다.
프런트엔드 설정
server
디렉토리에서 외부로 이동하여 reactjs
를 사용하여 create-react-app
프로젝트를 생성합니다.
npx create-react-app reactjs
cd reactjs
종속성 설치
npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4 axios
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />
,
document.getElementById('root')
);
설정
App.js
import { Box, ChakraProvider, Container } from "@chakra-ui/react";
import Axios from "axios";
import Upload from "./components/Upload";
Axios.defaults.baseURL = "http://localhost:4000";
function App() {
return (
<ChakraProvider>
<Box
minH="100vh"
w="100%"
bg="gray.200"
display="flex"
alignItems="center"
justifyContent="center"
>
<Container maxWidth="container.xl">
<Upload />
</Container>
</Box>
</ChakraProvider>
);
}
export default App;
새 후크 만들기
useUpload
후크 인hooks
폴더hooks/useUpload.js
import { useState } from "react";
import axios from "axios";
import { useToast } from "@chakra-ui/react";
const useUpload = () => {
const [image, setImage] = useState(null);
const [loading, setLoading] = useState(false);
const [uploadedImage, setUploadedImage] = useState(null);
const toast = useToast();
const handleChangeImage = (e) => {
setImage(e.target.files[0]);
};
const handleUploadImage = async () => {
try {
setLoading(true);
const formData = new FormData();
formData.append("image", image);
const res = await axios.post("/", formData);
if (res.data.data) {
console.log(res.data);
setUploadedImage(res.data.data);
toast({
title: "Image Uploaded",
description: res.data.message,
status: "success",
duration: 4000,
isClosable: true,
});
}
} catch (error) {
console.log(error);
} finally {
setImage(null);
setLoading(false);
}
};
const handleRemoveImage = async () => {
try {
setLoading(true);
const res = await axios.delete(`/${uploadedImage.imageName}`);
if (res.data) {
console.log(res.data);
setUploadedImage(null);
toast({
title: "Image Deleted",
description: res.data.message,
status: "success",
duration: 4000,
isClosable: true,
});
}
} catch (error) {
console.log(error);
} finally {
setLoading(false);
}
};
return {
image,
uploadedImage,
loading,
handleChangeImage,
handleUploadImage,
handleRemoveImage,
};
};
export default useUpload;
Upload.js
폴더 안에 components
생성components/Upload.js
import { Button, Heading, VStack, Image, HStack, Tag } from "@chakra-ui/react";
import React from "react";
import { useRef } from "react";
import useUpload from "../hooks/useUpload";
function Upload() {
const imageRef = useRef(null);
const {
loading,
image,
handleRemoveImage,
handleChangeImage,
handleUploadImage,
uploadedImage,
} = useUpload();
return (
<>
<input
style={{ display: "none" }}
type="file"
accept="image/*"
ref={imageRef}
onChange={handleChangeImage}
/>
<VStack>
<Heading>Image uploading using Golang and Reactjs</Heading>
<Button
onClick={() => imageRef.current.click()}
colorScheme="blue"
size="lg"
>
Select Image
</Button>
</VStack>
{image && (
<VStack my="4">
<Image
src={URL.createObjectURL(image)}
width="300px"
height="300px"
alt="selected image..."
/>
<Button
onClick={handleUploadImage}
variant="outline"
colorScheme="green"
isLoading={loading}
>
Upload
</Button>
</VStack>
)}
{uploadedImage && (
<VStack my="4">
<Image
src={uploadedImage.imageUrl}
width="300px"
height="300px"
alt={uploadedImage.imageName}
/>
<HStack>
<Tag variant="outline" colorScheme="blackAlpha">
~ {Math.floor(uploadedImage.size / 1024)} Kb
</Tag>
<Button
variant="solid"
colorScheme="red"
onClick={handleRemoveImage}
isLoading={loading}
>
Delete
</Button>
</HStack>
</VStack>
)}
</>
);
}
export default Upload;
Github 레포
백엔드
거친 망 갈람 / golang-반응-이미지-업로드-서버
프런트엔드
거친 망 갈람 / golang-반응-이미지-업로드-클라이언트
Create React App 시작하기
이 프로젝트는 Create React App으로 부트스트랩되었습니다.
사용 가능한 스크립트
프로젝트 디렉토리에서 다음을 실행할 수 있습니다.
npm 시작
개발 모드에서 앱을 실행합니다.
브라우저에서 보려면 http://localhost:3000을 여십시오.
수정하면 페이지가 다시 로드됩니다.
또한 콘솔에 린트 오류가 표시됩니다.
npm 테스트
대화형 감시 모드에서 테스트 러너를 시작합니다.
자세한 내용은 running tests 섹션을 참조하십시오.
npm 실행 빌드
프로덕션용 앱을 build
폴더에 빌드합니다.
프로덕션 모드에서 React를 올바르게 번들로 묶고 최상의 성능을 위해 빌드를 최적화합니다.
빌드가 축소되고 파일 이름에 해시가 포함됩니다.
앱을 배포할 준비가 되었습니다!
자세한 내용은 deployment 섹션을 참조하십시오.
npm 실행 꺼내기
참고: 이것은 단방향 작업입니다. 한 번 eject
, 돌아갈 수 없습니다!
만약 너라면…
View on GitHub
Reference
이 문제에 관하여(Golang 및 React를 사용한 이미지 업로드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/harshmangalam/image-upload-using-golang-and-react-29n1
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Golang 및 React를 사용한 이미지 업로드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/harshmangalam/image-upload-using-golang-and-react-29n1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)