Topics

無障礙診斷服務證書和報告現已提供 PDF 格式!

  • column

Liberlogic 的無障礙診斷服務以 HTML 格式提供憑證和報告,但對於以 PDF 格式提供的憑證要求,證書和報告(PDF格式)現在可以簽發了!

PDF網頁無障礙檢查證書

PDF 無障礙合規性報告 (VPAT/ACR)

為了解決這個問題,我們創建了一個系統,該系統在建置過程中自動輸出 PDF 和 HTML。

🛠️ PDF 創建基礎設施:Puppeteer 和環境構建

它可以無頭運行 Chromium 瀏覽器,作為 PDF 生成工具。Puppeteer由於 HTML 最初是用 Astro 建構的,因此引入 Puppeteer 的過程相對順利。

1. 使用本機伺服器保護渲染環境

Puppeteer 使用 Chromium 的列印功能,但它不支援本機 HTML 檔案(file://) 直接地,佈局已損壞問題將會出現。

為了避免這種情況,我們創建了以下環境:

  • 臨時網路伺服器:建造完成後dist用於託管目錄的臨時本機 Web 伺服器(http-server作為 Node.js 的子進程。
  • 穩定的環境:透過伺服器進行木偶操控(http://localhost:8080)以確保與瀏覽器相同的穩定渲染環境。

環境配置和伺服器啟動程式碼(節選)

// プロジェクト定数からドメインを取得し、未設定なら localhost:8080 を使用
const HOST_DOMAIN = SITE_URL || `http://localhost:${PORT}`; 
const BUILD_ROOT = path.join(__dirname, 'dist');
const PORT = 8080;

// --- サーバーの起動ロジック ---
let serverProcess = exec(`npx http-server ${BUILD_ROOT} -p ${PORT} -s --silent`);

// サーバーが起動するまで待機
await new Promise((resolve) => setTimeout(resolve, 2000));

// --- Puppeteerのページアクセス ---
// Puppeteerは localhost:8080 にアクセスし、レンダリングを開始します
const serverUrl = `http://localhost:${PORT}/${REPORT_DIR}/${urlPath}`;
await page.goto(serverUrl, { waitUntil: 'networkidle0' });

2. 應用日文字體

由於產生 PDF 的本機伺服器環境沒有日文字體,因此 PDF 中嵌入的字體將不正確。

  • 字體解決方法:在腳本中,網頁字型參考和套用樣式會在產生 PDF 之前動態插入 DOM 中。這使得使用日文字體輸出 PDF 成為可能。由於 HTML 端優先考慮速度且不使用網頁字體,因此這種動態插入僅應用於 PDF。

動態字體插入程式碼(節錄)

// Webフォントの動的挿入ロジック (page.evaluateでブラウザ側で実行)
await page.evaluate((fontUrl) => {
    // <link>タグを生成してDOMに挿入
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = fontUrl;
    document.head.appendChild(link);
    
    // @media print スタイルを強制的に挿入し、フォントを適用
    const printStyle = document.createElement('style');
    printStyle.textContent = `
      @media print {
        html, body {
          font-family: 'Noto Sans JP', sans-serif !important;
        }
      }
    `;
    document.head.appendChild(printStyle);
}, WEBFONTS_URL);

🚨 最大問題:PDF 連結中的 URL 引用問題

最難的事情是PDF文件之間的鏈接PDF 中嵌入的連結仍然指向本機開發環境的 URL(http://localhost:8080這是因為 Chromium 在載入 HTML 時會將基本 URI 保留為 PDF 連結的基礎。

強制連結使用絕對路徑

為了解決這個問題,我們在部署後強制將連結重寫為完整的絕對路徑,具體步驟如下:

  1. 使用目標網域:項目常數(SITE_URL)到您要部署到的網域(例如,https://example.com得到。
  2. 絕對 URL 建置和替換:在Node.js中取得HTML內容並返回原始連結(/accessibility_report/top/)的,已收購域名從(例如)開始的完整 URLhttps://example.com/accessibility_report/pdf/acr-top.pdf
  3. 重新套用到 DOM:將重寫的 HTML 重新套用到 Chromium(page.setContent())在 PDF 中嵌入連結。部署後的網域牢固地固定在

連結重寫程式碼(節錄)

// 1. 無効化したいリンク(.link-ignore-pdf)を物理的に削除
const ignoreLinkRegex = new RegExp(`(<a\\\\s+[^>]*class=["'][^"']*${ignoreClass}[^"']*["'][^>]*>)(.*?)(<\\/a\\\\s*>)`, 'gi');
content = content.replace(ignoreLinkRegex, '$2'); // <a>タグ全体を中身のテキストに置換

// 2. 詳細ページへのリンクを絶対URLに書き換え
const detailLinkRegex = new RegExp(`href="${reportDirRootLink}([^/]+)\\/"`, 'g');
const detailPdfUrl = `${pdfAbsoluteUrl}/acr-top.pdf`; // 例

content = content.replace(detailLinkRegex, (match, slug) => {
    // リンクを <http://localhost>... ではなく、<https://example.com/>... に強制置換
    return `href="${pdfAbsoluteUrl}/acr-${slug}.pdf"`; 
});

// 3. 最終的なコンテンツをブラウザに再適用し、PDF出力へ
await page.setContent(content, { 
    waitUntil: 'domcontentloaded',
    baseURL: baseUrlForContent
});

🎉 總結

這次由於需要連結PDF檔案這種比較特殊的需求,我們遇到了一些困難,但Puppeteer本身的引進過程相當順利。建造速度很快,我覺得它是一個非常實用的工具!

本次答覆的要點如下:

  • 透過本地伺服器進行渲染可確保穩定性。
  • 動態網頁字體注入以支援日語
  • 透過創建 PDF 之間的鏈接,使鏈接成為絕對路徑

支援PDF格式大大提升了我們服務的便利性。我們將繼續努力,為客戶提供真正有價值的高品質無障礙評估服務!

撰稿人

他從桌面排版領域轉戰網頁設計,迅速成為一位技藝精湛的“大師”,精通標記語言、前端設計、方向指導和無障礙設計。自 Liberlogic 創立以來,他一直活躍於各個領域,如今已成為公司內部的活字典。最近,他沉迷於探索如何利用提示來提高效率,並思考著「我們能否更依賴人工智慧來實現無障礙設計?」他的技術和思維仍在不斷發展。

Futa

IAAP認證的Web無障礙專家(WAS)/標記工程師/前端工程師/網站總監

看看這位員工的文章

我們以可靠的團隊結構和快速的回​​應能力而自豪。

在 Liberogic,我們經驗豐富的員工積極推動專案進展,這也是我們受到客戶高度評價的原因。
我們確保專案經理和主管得到合理分配,以確保整個專案的順利進行。 我們避免因全額承諾而導致不必要的成本增加,並將資源分配給合適的人員和合適的職位,並以快速掌握工作內容、創建和提交預算而聞名。

請注意,我們不積極參與SES式的現場工作。

我們支援幾乎所有主流的專案管理和聊天工具,包括 Slack、Teams、Redmine、Backlog、Asana、Jira、Notion、Google Workspace、Zoom 和 Webex。

案例研究