AIで作るHTMLテンプレート商品、オフライン配布のつもりが外部参照を残す

AIで作るHTMLテンプレート商品、オフライン配布のつもりが外部参照を残す

ダウンロードしてすぐ開ける、1 枚の HTML テンプレートを商品にするつもりでした。見た目を整えるために外部の CSS を読み、利用状況を見るために外部の script を置くと、単一ファイルでも外に依存します。さらに送信先が/orderのフォームは、ローカルで開いた時に使い道がありません。

2026 年 10 月 3 日、こうした AI 生成ページで起こりがちな混入を、再現用の短い HTMLで検査しました。実際の顧客データや販売中の商品は使っていません。最初の検査は 4 件、依存を外した版は 0 件です。ただし、0 件は「この検査が見る箇所に問題がない」という意味に限ります。

前回完了時と今回完了後

前回は商品カバーの PNG を WebP へ変換し、来歴の印が残るか確かめました。画像ファイルの出所を見ましたが、配布する HTML が外部に何を求めるかは見ていません。

時点確認したもの残る課題
前回完了時商品カバーの署名とXMPを変換前後で確認しましたHTMLの参照先は対象外です
今回完了後HTMLのsrc、href、actionとscriptの有無を確認しましたCSS内やJavaScript内の通信は別に調べます

飛ばせる章: HTMLの参照先の仕組みを知っている場合は、「同じ検査を修正前後に通す」から進めます。

なぜ単一ファイルを先に疑うのか

「HTML を 1 枚渡せば、購入者はネット接続なしで使える」という前提は、ファイル数だけでは決まりません。<link>は外部のスタイルシートを参照できます。<script src>も別の場所のコードを読みます。<form action>は送信先を指定します。見た目を確認するだけでは、参照先が商品に含まれているか分かりません。

今回の受け入れ条件は狭くしました。配布候補の HTML にhttp://、https://、//で始まる参照がないこと、サイトのルートを前提とする/始まりの参照がないこと、そして script がないことです。外部 URL そのものが悪いのではありません。今回は「単一 HTML として持ち歩ける商品」を作るので、依存の有無を先に確かめます。

[AIを使ってHTML商品の案を作る]
               ↓
[人が配布候補を1ファイルへ整理]
               ↓
[HTMLの参照先とscriptを静的検査]
       ├─ findings>0 → 依存を外すか、同梱方針を決める
       └─ findings=0 → 別途、ブラウザでオフライン操作を確認
                               ↓
                         [人が販売可否を判断]

用語

用語この回での意味
外部参照商品ファイルの外にあるURLへ、HTMLがアクセスする指定です
ルート相対パス/orderのように先頭が/のパスです。商品フォルダ内の相対パスとは違います
srcscriptや画像などの参照元を記すHTML属性です
hreflinkやaなどの参照先を記すHTML属性です
actionフォームの送信先を記すHTML属性です
静的検査ブラウザを起動せず、ファイルの記述を調べる方法です
HTMLParserPython標準ライブラリのHTML解析用クラスです

同じ検査を修正前後に通す

試した環境の Python は次の版です。

python3 --version
Python 3.13.5

下のコマンドはファイルを作らず、2 つの再現用 HTML をメモリ上で解析します。example.invalidは接続先として使うためではなく、外部参照がどこにあるかを示すダミーです。通信は行いません。

python3 -c 'from html.parser import HTMLParser
class Audit(HTMLParser):
 def __init__(self):
  super().__init__(); self.findings=[]
 def handle_starttag(self, tag, attrs):
  fields=dict(attrs)
  if tag=="script": self.findings.append("script: review required")
  for key in ("src", "href", "action"):
   value=fields.get(key, "") or ""
   if value.startswith(("http://", "https://", "//")):
    self.findings.append(f"{tag}.{key}: remote {value}")
   elif value.startswith("/"):
    self.findings.append(f"{tag}.{key}: root path {value}")
for name, body in [("before", "<link rel=stylesheet href=https://cdn.example.invalid/theme.css><form action=/order><script src=https://metrics.example.invalid/pixel.js></script>"), ("after", "<style>body{color:#17324d}</style><p>問い合わせ先: [email protected]</p>")]:
 audit=Audit(); audit.feed(body)
 print(f"{name}: findings={len(audit.findings)}")
 for finding in audit.findings: print("  " + finding)'
before: findings=4
  link.href: remote https://cdn.example.invalid/theme.css
  form.action: root path /order
  script: review required
  script.src: remote https://metrics.example.invalid/pixel.js
after: findings=0

初稿に相当するbeforeでは、CSS と script が商品外を指します。/orderは配布物の中にあるファイル名ではなく、サイトのルートを前提にした指定です。script には、外部 URL の指摘とは別に「コードの中身を確認する必要がある」という指摘も付けました。

修正版のafterでは、見た目の指定を<style>へ移し、使えない送信フォームと script を外しました。問い合わせ先は表示用の文字にしました。これで失う機能もあります。フォーム送信やアクセス計測が商品に不可欠なら、削って「完成」にするのではなく、ホストするサービスと依存先を設計し直します。

0件でも「通信しない証明」にはならない

この検査は HTML の開始タグにある 3 つの属性しか読みません。たとえば、<style>内の@importやurl()、インラインのイベント属性、srcset、文書を移動させる meta 要素は対象外です。script は内容を解析せず、存在するだけで指摘します。HTMLParser自体も、ブラウザの動作を再現するものではありません。

after: findings=0を「すべての通信がゼロ」と読むのは誤りです。今回は再現例を使った小さな受け入れ検査を作っただけで、商品全体をオフラインで操作した証拠はありません。実物を作ったら、配布するファイルを開き、ネットワークを切った状態で操作を試します。必要なら開発者ツールの Network も見ます。

確認手段分かること分からないこと
このPython検査指定したHTML属性の外部参照とscriptの有無ですCSS内部や動的通信は分かりません
オフラインでの操作接続なしで基本画面を使えるか分かりますあらゆる操作経路の網羅はできません
ブラウザのNetwork確認操作時の実際の要求先を観察できます未操作の機能が何を送るかは分かりません

販売前には、何を「オフラインで使える」と約束するかも書き分けます。閲覧だけできればよいのか、入力結果を保存する必要があるのかで、必要なテストは変わります。

よくあるエラー

症状原因対応
外部CSSの指摘が出ますHTMLがCDNを参照していますライセンスを確認し、同梱または自前のCSSに切り替えます
form.action: root path /orderと出ますサイトの送信先をそのまま残していますローカル商品の仕様から送信を外すか、ホスト型商品として設計します
scriptの指摘が2件出ますscriptの存在と外部srcを別々に数えます片方だけ消して合格扱いにしません
findings=0なのに外部へ要求しますCSS内や別の属性が検査対象外ですブラウザで操作し、Networkを確認します
商品では表示が崩れます参照先を削っただけで必要なCSSを移していませんオフライン状態で画面を見直します
mailto:が検査を通りますこの検査はメールクライアント起動を判定しません配布条件に合わせ、連絡導線を人が確認します

一次情報

資料確認したこと
Python: html.parserHTMLParserを継承して開始タグと属性を読む方法と、HTMLの整合性までは検証しない制限です
MDN: link要素hrefで外部のスタイルシートを指定する仕組みです
MDN: script要素srcで外部スクリプトを参照できる仕組みです
MDN: form要素フォームのactionが送信先を指定することです
MDN: Content Security Policyサイト運営者が読み込み先を制御するHTTPヘッダーの用途です。今回のローカルHTML検査とは別の対策です

AI へ「シンプルなランディングページを」と頼むと、見栄えのよい HTML だけで完成した気になりがちです。私が今回変えたのは、文章の指示ではなく商品の受け入れ条件です。外部参照を見つけたら、削除だけで済ませず、その機能を誰が提供するのかまで決めます。

この記事をシェア