diff --git a/functions/api/qrcode.js b/functions/api/qrcode.js new file mode 100644 index 0000000..41af97a --- /dev/null +++ b/functions/api/qrcode.js @@ -0,0 +1,127 @@ +/* + * Cloudflare Pages Function - QR Code API Proxy + * 解決 CORS 問題並代理請求到 QRCode Monkey API + * https://www.qrcode-monkey.com/qr-code-api-with-logo + */ +export async function onRequestPost(context) { + try { + const request = context.request; + const payload = await request.json(); + + console.log("Received request"); + + // 如果是獲取已生成的圖片 + if (payload.imageUrl) { + const imageUrl = "https://api.qrcode-monkey.com" + payload.imageUrl; + console.log("Fetching image from:", imageUrl); + + const imageResponse = await fetch(imageUrl); + + if (!imageResponse.ok) { + return new Response( + JSON.stringify({ error: "Failed to fetch image" }), + { + status: imageResponse.status, + headers: { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + }, + }, + ); + } + + const imageBlob = await imageResponse.blob(); + return new Response(imageBlob, { + headers: { + "Content-Type": + imageResponse.headers.get("content-type") || "image/png", + "Access-Control-Allow-Origin": "*", + "Cache-Control": "public, max-age=3600", + }, + }); + } + + // 原本的 QR Code 生成邏輯 + console.log("Generating QR Code"); + + const response = await fetch("https://api.qrcode-monkey.com/qr/custom", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + }); + + if (!response.ok) { + const errorText = await response.text(); + console.error("QRCode Monkey API Error:", errorText); + return new Response( + JSON.stringify({ + error: "API request failed", + status: response.status, + details: errorText, + }), + { + status: response.status, + headers: { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "POST, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type", + }, + }, + ); + } + + const contentType = response.headers.get("content-type"); + console.log("Response content type:", contentType); + + if (contentType && contentType.includes("image")) { + const imageBlob = await response.blob(); + return new Response(imageBlob, { + headers: { + "Content-Type": contentType, + "Access-Control-Allow-Origin": "*", + "Cache-Control": "public, max-age=3600", + }, + }); + } + + const data = await response.json(); + return new Response(JSON.stringify(data), { + headers: { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "POST, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type", + }, + }); + } catch (error) { + console.error("Function Error:", error); + return new Response( + JSON.stringify({ + error: "Internal server error", + message: error.message, + }), + { + status: 500, + headers: { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + }, + }, + ); + } +} + +export async function onRequestOptions() { + return new Response(null, { + status: 204, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "POST, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type", + "Access-Control-Max-Age": "86400", + }, + }); +} diff --git a/src/pages/qrcode_generator.js b/src/pages/qrcode_generator.js index 0ef48bc..68f5afb 100644 --- a/src/pages/qrcode_generator.js +++ b/src/pages/qrcode_generator.js @@ -45,13 +45,10 @@ const QRCodeGeneratorPage = () => { console.log("Sending payload:", JSON.stringify(payload, null, 2)); - // 使用 CORS 代理(僅限開發環境) - const isDevelopment = process.env.NODE_ENV === "development"; - const apiUrl = isDevelopment - ? "https://corsproxy.io/?https://api.qrcode-monkey.com/qr/custom" - : "https://api.qrcode-monkey.com/qr/custom"; - try { + // 透過 functions/api/qrcode + const apiUrl = "/api/qrcode"; + const response = await fetch(apiUrl, { method: "POST", headers: { @@ -82,12 +79,17 @@ const QRCodeGeneratorPage = () => { const imageUrl = "https://api.qrcode-monkey.com" + result.imageUrl; console.log("Fetching image from:", imageUrl); - // 使用 CORS 代理(僅限開發環境) - const imgUrl = isDevelopment - ? `https://corsproxy.io/?${imageUrl}` - : imageUrl; + // 透過 functions/api/qrcode + const imgResponse = await fetch("/api/qrcode", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + imageUrl: result.imageUrl, + }), + }); - const imgResponse = await fetch(imgUrl); if (imgResponse.ok) { const blob = await imgResponse.blob(); const url = URL.createObjectURL(blob); @@ -320,44 +322,6 @@ const QRCodeGeneratorPage = () => { )} - - {/* 使用說明 */} -
+ 此教學指南為學習開發 Apple 平臺應用程式的初學者,介紹使用 Swift + 語言與 Xcode 進行應用程式開發的基礎知識。 +
+開始新的課程或是將您的技能提升到一個新水平。 @@ -82,7 +130,7 @@ const SwiftPage = () => { alt={item.title} className="w-full" imgClassName="object-contain" - aspectRatio="3/4" + aspectRatio="16/9" objectFit="contain" />