解決 CKEditor 圖片水平排版在前端顯示為垂直排列的問題

前言:編輯器與前端的排版不一致之謎 在開發多平台醫療健康應用時,我們採用了現代化的技術棧: 後端 CMS:Strapi v5.15.1(Headless CMS) 前端框架:Vue.js 3 富文本編輯器:CKEditor 5 資料傳輸:GraphQL API 這個組合在大多數情況下運作良好,編輯者可以在 Strapi 後台使用 CKEditor 輕鬆編輯富文本內容,前端 Vue.js 應用透過 GraphQL 獲取並渲染這些內容。 然而,我們遇到了一個令人困惑的問題: 在 Strapi 後台使用 CKEditor 精心排版的水平並排圖片,到了前端網頁卻變成了垂直排列。 這個問題不僅影響了內容的視覺呈現,也破壞了編輯者的排版意圖。更重要的是,這讓非技術背景的內容編輯者感到困惑:「為什麼我在後台看到的排版,到了網站上就變了?」 這篇文章將深入探討這個問題的根本原因,並提供系統性的解決方案。 問題現象與環境說明 內容流程架構 我們的內容從編輯到展示的完整流程如下: 問題的具體表現 預期行為: 在 Strapi CKEditor 後台,編輯者將兩張圖片設定為水平並排: <!-- CKEditor 生成的 HTML 結構 --> <figure class="image" style="float:left"> <img src="/uploads/image1.webp" alt="圖片1"> <figcaption>圖片1說明</figcaption> </figure> <figure class="image" style="float:left"> <img src="/uploads/image2.webp" alt="圖片2"> <figcaption>圖片2說明</figcaption> </figure> 實際現象: 前端 Vue.js 渲染後,圖片變成垂直排列: 兩張圖片沒有並排顯示,而是一張接著一張垂直堆疊。 技術環境詳情 Strapi CKEditor 配置(config/schema.json): { "kind": "collectionType", "collectionName": "articles", "info": { "singularName": "article", "pluralName": "articles", "displayName": "文章" }, "attributes": { "title": { "type": "string" }, "content": { "type": "customField", "options": { "preset": "defaultHtml" }, "customField": "plugin::ckeditor5.CKEditor" } } } Vue.js 前端渲染組件(ServiceDetailView.vue): ...

August 1, 2025 · 9 分鐘 · Peter

Vue.js SPA 社交分享完整指南:解決 Facebook/LINE OpenGraph 爬蟲問題

引言:當精美的網站變成分享時的「無名氏」 在現代 Web 開發中,社交媒體分享功能是不可或缺的一部分。當用戶在 Facebook、LINE 或其他社交平台分享你的網站連結時,你希望顯示的是精美的預覽卡片,而不是空白或錯誤的資訊。 然而,對於使用 Vue.js、React、Angular 等前端框架開發的單頁應用程式(SPA),這個看似簡單的需求卻隱藏著技術挑戰。 本文將完整記錄從問題發現、原因分析、到解決方案實作的全過程。 問題發現:為什麼分享連結總是顯示預設值? 場景描述 我的平台 www.abc.com 是一個基於 Vue.js 3 + Strapi CMS 的網站。某天,我發現一個嚴重問題: 當用戶分享服務頁面(如 https://www.abc.com/service-us/6)到 Facebook 或 LINE 時,顯示的預覽資訊總是預設值,而非該服務的實際標題和描述。 實際情況對比: 情境 期望結果 實際結果 分享服務頁面 顯示「專業網站開發服務」 顯示「ABCDEFG(預設標題)」 分享部落格文章 顯示文章標題與摘要 顯示網站預設描述 分享產品頁面 顯示產品圖片與名稱 顯示網站 Logo 診斷工具測試 使用 Facebook Open Graph Debugger 測試後發現: 爬蟲抓取到的 HTML: <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="UTF-8"> <title>ABCDEFG</title> <meta property="og:title" content="ABCDEFG"> <meta property="og:description" content="預設網站描述"> <!-- 沒有任何動態內容! --> </head> <body> <div id="app"></div> <script src="/assets/index.js"></script> </body> </html> ⚠️ 關鍵發現: 爬蟲只看到靜態的 HTML 模板,完全沒有 JavaScript 執行後動態生成的 meta 標籤。 ...

July 31, 2025 · 11 分鐘 · Peter

前端登入失敗的真兇:深入理解 CORS 問題與實戰解法

前言:那個令人抓狂的錯誤訊息 在開發前後端分離的 Web 應用時,幾乎每位工程師都曾遇過這個令人頭痛的錯誤: Access to fetch at 'http://localhost:1337/api/auth/local' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 這個錯誤通常發生在最關鍵的時刻: 前端登入功能即將完成,卻無法呼叫後端 API 串接第三方服務時,資料無法正常取得 部署到測試環境後,原本運作正常的功能突然失效 CORS(Cross-Origin Resource Sharing,跨來源資源共用)是現代 Web 開發中的核心安全機制,但也是許多開發者的痛點。這篇文章將從基礎原理到實戰應用,帶你完整理解 CORS 的運作方式,並提供實際可用的解決方案。 為什麼需要 CORS?從同源政策說起 同源政策的誕生 在理解 CORS 之前,我們需要先認識「同源政策」(Same-Origin Policy, SOP)。這是瀏覽器最基本的安全機制,在 1995 年 Netscape Navigator 2.0 引入 JavaScript 時就已經存在。 同源政策的目的:防止惡意網站讀取另一個網站的敏感資料。 想像一個情境:你登入了網路銀行(https://bank.com),此時你的瀏覽器保存了銀行的登入 Cookie。如果沒有同源政策,當你不小心訪問了一個惡意網站(https://evil.com),該網站的 JavaScript 就能透過你的瀏覽器向 https://bank.com 發送請求,並讀取你的帳戶資料。 同源政策阻止了這種攻擊:https://evil.com 的 JavaScript 無法讀取 https://bank.com 的回應內容。 什麼是「同源」? 兩個 URL 被視為同源,必須滿足以下三個條件: ...

July 1, 2025 · 9 分鐘 · Peter

解決 macOS 上 Rollup rollup.darwin-arm64.node 模組錯誤與 Gatekeeper 阻擋問題

前言 使用 Apple Silicon Mac 開發前端專案時,你有沒有遇過這種情況:npm install 明明成功了,但執行 npm run dev 時 Vite 卻突然翻臉不認人,噴出一堆關於 rollup.darwin-arm64.node 的錯誤? 更慘的是,macOS 還會彈出一個視窗說「無法打開 rollup.darwin-arm64.node,因為無法驗證開發者」——彷彿你的電腦在暗示你下載了什麼奇怪的東西。 別擔心,這不是你的問題(好吧,也不完全是 Apple 的問題),而是 npm + Gatekeeper 的經典組合技。本文將帶你徹底理解並解決這個惱人的問題。 問題現象 當你在 Apple Silicon Mac 上執行 Vite/Rollup 專案時,可能會遇到以下錯誤: 錯誤 1:模組找不到 Error: Cannot find module '@rollup/rollup-darwin-arm64' Require stack: - /project/node_modules/rollup/dist/native.js 錯誤 2:系統策略拒絕載入 Error: dlopen(/project/node_modules/@rollup/rollup-darwin-arm64/rollup.darwin-arm64.node, 0x0001): code signature in (...) not valid for use in process: library load disallowed by system policy 錯誤 3:Gatekeeper 彈窗警告 macOS 直接彈出視窗:「無法打開 rollup.darwin-arm64.node,因為無法驗證開發者」 ...

January 1, 2024 · 2 分鐘 · Peter