By a3040, Published on Invalid Date
주소창에 https://localhost:8443/admin/topic/edit?id=1 를 이용해서 접근했을때
querystring 얻는 방법
${param.id}
<p th:text="${param.id }"></p>
By a3040, Published on Invalid Date
1. spring boot 톰켓용 p12 인증서를 생성합니다.
> keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
Enter keystore password: <-- 개인 암호 입력
Re-enter new password: <-- 위와 같은 암호입력
1.1 생성한 인증서를 spring boot에 추가 합니다.
application.properties 또는 application.yaml
server.ssl.key-store-type=PKCS12
#위에서 생성한 keystore.p12 파일이 위치한 폴더입니다.
server.ssl.key-store=file:/C:/Us...40/keystore.p12
#위에서 인증서 생성시 keytool실행하면 나오는 암호입력부분에 입력한 암호입니다.
server.ssl.key-store-password=123456
#위에서 인증서 생성시 작성한 alias입니다. 변경 안한경우 tomcat
server.ssl.key-alias=tomcat
2.express에서 https용 인증서 생성
openssl이 설치된곳에서 생성합니다.
>openssl genrsa -out key.pem
>openssl req -new -key key.pem -out csr.pem
>openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
2.1 인증서 추가하기
import https from 'https';
...
let port = 3000;
var app=express();
const privateKey = fs.readFileSync('./key.pem', 'utf8');
const certificate = fs.readFileSync('./cert.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate
};
const server = https.createServer(credentials, app);
server.listen(port, () => {
console.log(`HTTP server is running at https://localhost:${port}`);
});
-1,2두 방법 모두 사설 인증서여서 브라우저에서 접속할 경우 경고가 발생합니다.
브라우저에서 p12로 인증서 추가하기 를 수행해주시면 경고가 사라집니다.
3.vite 사용시 connect error가 발생합니다.
npm i vite-plugin-mkcert -D
vite.config.js
import { defineConfig } from 'vite'
import mkcert from 'vite-plugin-mkcert'
export default defineConfig({
server: { https: true }, // Not needed for Vite 5+
plugins: [ mkcert() ]
})
를 수행하면 vite의 경우 자동으로 인증서를 브라우저에 추가해줍니다.
By a3040, Published on Invalid Date
<div className="sticky top-0 bg-blue-400 p-5 drop-shadow shadow-blue-600">
<h1 className="text-white text-4xl text-center">sticky top-0</h1>
</div>
sticky, top-0 속성을 이용해서 고정할수 있습니다. position: sticky;
"sticky": 이 클래스는 요소를 화면에서 고정시키는 데 사용됩니다. top: 0px;
"top-0": 이 클래스는 요소를 부모 요소의 상단에 고정시키는 데 사용됩니다.
By a3040, Published on Invalid Date
Multer란?
파일 업로드를 위해 사용되는 multipart/form-data
를 다루기 위한 node.js 의 미들웨어 입니다. 효율성을 최대화 하기 위해 busboy 를 기반으로 하고 있습니다.
설치
$ npm install --save multer
파일 전송 쪽 단일 파일 //react, axios, react-dropzone 예시
const UploadApp = () => {
const onDrop = async (acceptedFiles) => {
const formData = new FormData();
formData.append('file', acceptedFiles[0]);
try {
const response = await axios.post('http://localhost:3000/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
if (response.status === 200) {
console.log('File uploaded successfully.');
} else {
console.error('File upload failed.');
}
} catch (error) {
console.error('Error uploading file:', error);
}
};
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
<div {...getRootProps()} style={{ border: '2px dashed #ccc', padding: '20px', textAlign: 'center' }}>
<input {...getInputProps()} />
<p>Drag & drop a file here, or click to select a file</p>
</div>
);
};
export default UploadApp;
서버쪽 Multer : multipart/form-data 데이터 처리
./up.js <-- url 처리 및 전송데이터 처리용 express코드
./uploads <-- 첨부파일 저장 위치
import express from 'express';
import multer from 'multer';
import path from 'path';
import cors from 'cors'; // CORS 미들웨어 추가
const app = express();
const port = 3000;
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // 파일 저장 경로 설정
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
const fileExtension = path.extname(file.originalname);
cb(null, file.fieldname + '-' + uniqueSuffix + fileExtension); // 파일 이름 설정
},
});
const upload = multer({ storage });
app.use(cors({
origin: 'http://localhost:5173', // 클라이언트 주소
}));
app.use(express.static('public'));
app.use('/uploads', express.static('uploads'));
app.post('/upload', upload.single('file'), (req, res) => {
console.log('request start....')
res.status(200).json({ message: 'File uploaded successfully.' });
});
app.get('/alive',(req, res) => {
res.status(200).json({ message: 'server alive.' });
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
cors 미들웨어는 react실행하는 쪽 에서 axios 전송 요청시 에러가 발생해서 추가핬습니다.
실행 및 테스트
>node ./up.js
multer/doc/README-ko.md at master · expressjs/multer (github.com)
By a3040, Published on Invalid Date
1.생성되는 js 특정 위치에 놓기
vite -rollup설정 추가
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
build:{
rollupOptions:{
input : "./src/main.tsx",
output:{
dir:"../../back/src/main/resources/static/js/admin", /*출력 디렉토리*/
entryFileNames:"dashboard.js", /*만들 js */
}
},
},
plugins: [react()],
})
2.tailwindcss를 통해 성성된 css파일 위치 및 파일명 고정
export default defineConfig({
build:{
rollupOptions:{
input : "./src/main.tsx",
output:{
assetFileNames: (chunkInfo) => {
if (chunkInfo.name === 'main.css') /*임시로 만들어 지는 파일명*/
return 'index.css' /* 새로 만들 원하는 고정 파일명 */
},
dir:"../../back/src/main/resources/static/js/admin", /*출력 디렉토리*/
entryFileNames:"dashboard.js", /*만들 js */
}
},
},
plugins: [react()],
})
css설정 전 임의의 파일 생성
css설정 후 고정 파일 생성
3.고정파일에서 페이지 설정
board.html
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>admin-dashboard</title>
<link rel="stylesheet" href="/js/admin/index.css">
</head>
<body>
<div id="root"></div>
<script type="module" src="/js/admin/dashboard.js"></script>
</body>
</html>
package.json
"scripts": {
"dev": "vite",
"build": "tsc && vite build --watch",