上一篇文章示範了如何使用 GET 方法去取得 PNG 的 QR Code,這一篇文章則是要示範如何使用 POST 方法去取得 PNG 的 QR Code,並且會使用到 Form 表單來送出資料。
首先我們要在 client.ts
中新增一個 post
的方法,這個方法是用來發送 POST 請求的,程式碼如下:
interface PostData {
url?: string
phone?: string
email?: string
address?: string
foreground?: string
background?: string
dimension?: string
}
class APIClient {
client: AxiosInstance
constructor() {
this.client = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
responseType: 'blob',
headers: {
'Content-Type': 'application/json'
}
})
}
get(path: string, params?: GetParams) {
return this.client.get(path, { params })
}
post(path: string, data: PostData) {
return this.client.post(path, data)
}
}
export type { GetParams, PostData }
export default APIClient
這裡新增了一個 PostData
的型別,這個型別是用來定義 POST 請求的參數,這些參數都是可選的,所以我們使用 ?
來定義。
接下來在 endpoints.ts
中新增路徑:
const Endpoints = {
GenerateQrcode: {
pngType: 'generate_qr',
svgType: 'generate_qr_svg',
}
}
export default Endpoints
最後一個設定要在 generateQrcode
新增一個函式:
import APIClient, { GetParams, PostData } from './client'
import Endpoints from './endpoints'
const apiClient = new APIClient()
// 省略
const generateQrcode = {
// 省略
getSvg: (data: PostData) => {
return apiClient.post(Endpoints.GenerateQrcode.svgType, data)
}
}
export default generateQrcode
主要新增了一個 getSvg
的函式,這個函式是用來取得 SVG 的 QR Code,並且使用 apiClient.post
來發送 POST 請求。
由於原本就已經設定好表單,接下來只要把表單都接上 state,並且在送出的時候,把 state 的資料傳遞進去就可以了。
'use client'
import { useState, FormEvent } from 'react'
import { TextInput, SelectType, SizeSlider, ColorPicker } from './components'
import Image from 'next/image'
import generateQrcode from './lib/api/generateQrcode'
export default function Home() {
const [text, setText] = useState<string>('')
const [qrType, setQrType] = useState<string>('URL')
const [qrSize, setQrSize] = useState<number>(500)
const [qrColor, setQrColor] = useState<string>('#000000')
const [qrBgColor, setQrBgColor] = useState<string>('#ffffff')
const [imgSrc, setImgSrc] = useState<string | null>(null)
const fetchQrcodeSvg = async () => {
try {
const typeMapping: { [key: string]: string } = {
URL: 'url',
電話: 'phone',
地址: 'address',
Email: 'email'
}
const key = typeMapping[qrType as keyof typeof typeMapping]
const data = {
[key]: text,
foreground: qrColor,
background: qrBgColor,
dimensions: qrSize
}
const response = await generateQrcode.getSvg(data)
const blob = new Blob([response.data], { type: 'image/svg+xml' })
const objectURL = URL.createObjectURL(blob)
setImgSrc(objectURL)
} catch (_) {
console.error('Error fetching image:')
}
}
const generateQRCode = async (e: FormEvent) => {
e.preventDefault()
await fetchQrcodeSvg()
}
return (
<main className='flex min-h-screen flex-col items-center justify-between p-24'>
<div className='container mx-auto p-4'>
<h1 className='text-3xl mb-4'>QR Code 製造器</h1>
<form onSubmit={generateQRCode} className='flex flex-col gap-y-5'>
<SelectType qrType={qrType} setQrType={setQrType} />
<TextInput text={text} setText={setText} />
<div className='flex items-center justify-evenly'>
<SizeSlider qrSize={qrSize} setQrSize={setQrSize} />
<ColorPicker
label='選擇顏色'
color={qrColor}
setColor={setQrColor}
/>
<ColorPicker
label='選擇背景顏色'
color={qrBgColor}
setColor={setQrBgColor}
/>
</div>
<div className='flex justify-center mt-5'>
<button
type='submit'
className='bg-green-500 hover:bg-green-100 text-white hover:text-slate-700 font-bold py-2 px-4 rounded text-center'
>
產生 QR Code
</button>
</div>
</form>
{imgSrc ? (
<div className='flex justify-center mt-10'>
<Image src={imgSrc} width={500} height={500} alt='QR Code Image' />
</div>
) : (
'請點擊「產生 QR Code」按鈕'
)}
</div>
</main>
)
}
現在可以判斷不同類型的 QR Code,並且可以設定顏色、背景顏色、大小,並且可以產生 SVG 的 QR Code,這樣子就完成了!
這篇文章示範了如何使用 Form 表單來送出資料,並且使用 POST 方法來取得 SVG 的 QR Code,不過這個表單還有一些問題需要解決,明天見👋!