개요
본 문서에서는 Vue.js 프론트엔드에서 Axios를 사용하여 ASP.NET Core 3.1 백엔드로부터 Base64 형식의 캡차 이미지를 가져와 표시하는 방법에 대해 설명한다. Axios의 기본 URL과 타임아웃을 전역적으로 설정하는 방법도 함께 다룬다.
1. 프론트엔드 구현
다음은 Vue.js와 Axios를 사용하여 캡차 이미지를 표시하는 HTML 페이지이다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Captcha Demo</title>
<style>
.captcha-container {
width: 260px;
height: 160px;
border: 1px solid #666666;
cursor: pointer;
}
.captcha-thumbnail {
width: 80px;
height: 20px;
}
</style>
<script src="../assets/vue.js"></script>
<script src="../assets/axios.js"></script>
</head>
<body>
<div id="app">
<div v-if="userInfo">
<p>이름: {{userInfo.name}}</p>
<p>나이: {{userInfo.age}}</p>
<div @click="refreshCaptcha" class="captcha-container">
<img :src="captchaImage" alt="캡차 이미지" />
</div>
<div><img :src="captchaImage" alt="썸네일" /> </div>
<div>{{captchaImage}}</div>
</div>
</div>
<script>
// Axios 전역 기본 설정
axios.defaults.baseURL = "http://localhost:5000/api/";
axios.defaults.timeout = 5000;
var app = new Vue({
el: "#app",
data: {
userInfo: null,
captchaImage: "",
thumbnailData: ""
},
methods: {
fetchUserData: function() {
axios({
method: "post",
url: "auth/getuserinfo",
params: {
name: "홍길동",
age: 25
}
}).then(response => {
this.userInfo = response.data;
})
},
loadCaptchaImage: function() {
var _this = this;
axios({
method: "post",
url: "auth/generatecaptcha",
}).then(response => {
_this.captchaImage = response.data.imageData;
_this.thumbnailData = response.data.imageData;
})
},
refreshCaptcha: function() {
this.loadCaptchaImage();
return false;
}
},
mounted: function() {
this.fetchUserData();
}
})
</script>
</body>
</html>
2. ASP.NET Core Web API 컨트롤러
백엔드에서는 캡차 이미지를 생성하고 Base64로 인코딩하여 반환하는 엔드포인트를 제공한다.
using Microsoft.AspNetCore.Mvc;
using System;
using WebApiDemo.Filters;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace WebApiDemo.Controllers
{
[ApiController]
[Route("api/[controller]")]
[MyFilter]
public class AuthController : ControllerBase
{
[HttpGet]
[Route("getconfig")]
public ApiResult<AppConfig> GetConfiguration()
{
ApiResult<AppConfig> result = new ApiResult<AppConfig>();
try
{
result.data = new AppConfig
{
Name = "구성정보",
Value = 100
};
result.success = true;
result.message = "조회 성공";
}
catch (Exception ex)
{
result.message = "조회 실패: " + ex.Message;
}
return result;
}
[HttpPost("getuserinfo")]
public dynamic GetUserInfo(string name, int age)
{
dynamic userData = new { name = name, age = age };
return userData;
}
[HttpPost("generatecaptcha")]
public dynamic GenerateCaptcha()
{
try
{
return new { imageData = CaptchaGenerator.CreateCode() };
}
catch (Exception ex)
{
return new { imageData = ex.Message };
}
}
}
public class AppConfig
{
public string Name { get; set; }
public int Value { get; set; }
}
public class ApiResult<T>
{
public bool success { get; set; }
public string message { get; set; }
public T data { get; set; }
}
}
3. 캡차 생성 헬퍼 클래스
이미지를 생성하고 Base64 문자열로 변환하는 유틸리티 클래스이다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace WebApiDemo
{
public class CaptchaGenerator
{
private static readonly Color[] CaptchaColors =
{
Color.Black, Color.Red, Color.DarkBlue,
Color.Green, Color.Orange, Color.Brown,
Color.DarkCyan, Color.Purple
};
private static readonly string[] CaptchaFonts =
{
"Verdana", "Microsoft Sans Serif",
"Comic Sans MS", "Arial"
};
private static MemoryStream CreateCaptchaImage(string code, int width = 0, int height = 30)
{
var image = new Bitmap(
width == 0 ? code.Length * 25 : width,
height
);
using (var g = Graphics.FromImage(image))
{
g.Clear(Color.WhiteSmoke);
var random = new Random();
//干扰点 생성
for (var i = 0; i < 40; i++)
{
var x = random.Next(image.Width);
var y = random.Next(image.Height);
g.DrawRectangle(
new Pen(
CaptchaColors[random.Next(CaptchaColors.Length)],
0
),
x, y, 1, 1
);
}
//验证码 문자열 그리기
for (var i = 0; i < code.Length; i++)
{
var colorIndex = random.Next(CaptchaColors.Length);
var fontIndex = random.Next(CaptchaFonts.Length);
var font = new Font(CaptchaFonts[fontIndex], 15, FontStyle.Bold);
Brush brush = new SolidBrush(CaptchaColors[colorIndex]);
var offset = (i + 1) % 2 == 0 ? 2 : 4;
g.DrawString(
code.Substring(i, 1),
font,
brush,
10 + (i * 15),
offset
);
}
var ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
return ms;
}
}
public static string CreateCode(int length = 4)
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
List<int> generatedNumbers = new List<int>();
while (generatedNumbers.Count < length)
{
int num = numbers[new Random().Next(0, numbers.Length)];
if (!generatedNumbers.Contains(num))
{
generatedNumbers.Add(num);
}
}
string code = string.Join("", generatedNumbers);
using (var ms = CreateCaptchaImage(code))
{
string base64 = ConvertToBase64(ms);
return base64;
}
}
private static string ConvertToBase64(MemoryStream stream)
{
return "data:image/png;base64," + Convert.ToBase64String(stream.ToArray());
}
}
}
4. 구현のポイント
- Axios 기본 설정: axios.defaults.baseURL을 통해 API 기본 경로를 설정하고, timeout으로 요청 제한 시간을 구성한다.
- Base64 이미지 처리: 서버에서 생성된 이미지를 Base64 문자열로 변환하여 클라이언트에 전달하고, img 태그의 src 속성에 "data:image/png;base64," 접두사를 포함시켜 표시한다.
- 캡차 이미지 재생성: 클릭 이벤트를 통해 새로운 캡차 이미지를 요청하고 화면을 갱신한다.