From dc4810c8b5496858ac5ccdf5704acaff14647812 Mon Sep 17 00:00:00 2001 From: Qing Bi Liao <78472206+Pencil126@users.noreply.github.com> Date: Tue, 14 Oct 2025 05:25:51 +0000 Subject: [PATCH 1/3] =?UTF-8?q?Fix=20QR=20Code=20API=20=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E8=A7=A3=E6=B1=BA=20CORS=20?= =?UTF-8?q?=E5=95=8F=E9=A1=8C=20Delete=20=E6=9C=89=E9=BB=9E=E7=99=BD?= =?UTF-8?q?=E7=97=B4=E7=9A=84=E4=BD=BF=E7=94=A8=E8=AA=AA=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/api/qrcode.js | 127 ++++++++++++++++++++++++++++++++++ src/pages/qrcode_generator.js | 62 ++++------------- 2 files changed, 140 insertions(+), 49 deletions(-) create mode 100644 functions/api/qrcode.js 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 +129,7 @@ const SwiftPage = () => { alt={item.title} className="w-full" imgClassName="object-contain" - aspectRatio="3/4" + aspectRatio="16/9" objectFit="contain" />
From b33a5bd9973448a4b63cc7ea4b85f938528d8c58 Mon Sep 17 00:00:00 2001
From: Qing Bi Liao <78472206+Pencil126@users.noreply.github.com>
Date: Tue, 14 Oct 2025 05:53:35 +0000
Subject: [PATCH 3/3] Prettier
---
src/pages/swift_res.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/pages/swift_res.js b/src/pages/swift_res.js
index 6b4f5e6..d305da4 100644
--- a/src/pages/swift_res.js
+++ b/src/pages/swift_res.js
@@ -69,7 +69,8 @@ const SwiftPage = () => {
使用 Swift 開發教學指南
(Develop in Swift Tutorials)
- 此教學指南為學習開發 Apple 平臺應用程式的初學者,介紹使用 Swift 語言與 Xcode 進行應用程式開發的基礎知識。 + 此教學指南為學習開發 Apple 平臺應用程式的初學者,介紹使用 Swift + 語言與 Xcode 進行應用程式開發的基礎知識。