Workers + KV で自前の短縮 URL サービスを構築:入門から実践まで
なぜ自前の短縮 URL サービスを構築するのか?
以前使っていたサードパーティの短縮 URL サービスを約 2 年間利用していました。ある朝、すべての短縮リンクが無効になっていることに気づきました——事業者が突然サービス終了を発表したのです。SNS で共有した数百のリンクが 404 になってしまいました。
そのとき思いました。完全に自分だけの短縮 URL サービスを作れないだろうか?データを自分で管理し、好きなようにカスタマイズでき、サードパーティのサービス終了を心配しなくて済むものを。
調べてみると、Cloudflare Workers + KV ストレージがこの要件にぴったりでした。
- 無料枠が非常に大きい(1 日 10 万リクエスト)
- 世界 200 以上の拠点で、アクセス速度が速い
- デプロイが簡単、数行のコードで動く
- データは完全に自分のもの、保存期間も自由
この記事では、Workers + KV で自前の短縮 URL サービスを構築した方法を共有します。カスタム短縮コードやアクセス統計なども含め、コードはすべて掲載するので、手順どおり進めれば 30 分程度で公開できます。
なぜ Workers + KV なのか?
Cloudflare Workers とは?
簡単に言えば、Workers は Cloudflare のエッジネットワーク上で動く Serverless 関数です。コードを書けば、世界 200 以上の拠点に自動デプロイされ、ユーザーは最寄りのノードにルーティングされるため、レイテンシが非常に低くなります。
重要なのは、無料枠が非常に手厚いことです。
- 1 日 10 万リクエスト
- 1 リクエストあたり 10ms の CPU 時間
- 個人利用や小規模チームなら十分
KV ストレージの利点
KV(Key-Value)ストレージは、Cloudflare が提供する分散型キーバリューデータベースで、エッジコンピューティング向けに最適化されています。
- 読み取りが超高速:中央値 12ms。データがエッジノードにキャッシュされるため
- グローバル同期:書き込み後 60 秒以内に全世界のノードに同期
- 無料枠:1 日 10 万回読み取り、1000 回書き込み
短縮 URL サービスには KV が最適です。
- 短縮コードを key、元の URL を value
- 読み多く書き少ないシナリオ(作成は少なく、アクセスは多い)
- グローバル分散で、どこからアクセスしても速い
サードパーティの短縮 URL サービスとの比較
| 特性 | サードパーティ | 自前 Workers + KV |
|---|---|---|
| データ管理 | データは外部 | 完全に自分のもの |
| カスタマイズ | 機能固定 | 自由にカスタマイズ |
| 安定性 | サービス終了の可能性 | Cloudflare 基盤 |
| 広告 | 中間ページあり | 広告なし |
| コスト | 有料の可能性 | 基本無料 |
| アクセス速度 | 事業者次第 | グローバルエッジネットワーク |
ゼロから短縮 URL サービスを構築する
理論はここまで。実践に入りましょう。
準備
1. Cloudflare アカウントを登録
cloudflare.com でアカウントを作成してください。無料プランで十分です。
2. Wrangler CLI をインストール
Wrangler は Cloudflare 公式の CLI ツールで、Workers プロジェクトを管理します。
npm install -g wrangler
# または yarn
yarn global add wrangler
インストール後、Cloudflare アカウントにログインします。
wrangler login
ブラウザが開くので、許可をクリックするだけです。
3. プロジェクトを作成
mkdir my-shortlink
cd my-shortlink
wrangler init
プロンプトに従い、JavaScript プロジェクトを作成します(TypeScript も可)。
Step 1:KV 名前空間を作成
KV ストレージは先に「名前空間(Namespace)」を作成する必要があります。データベースのテーブルのようなものと考えてください。
以下のコマンドを実行します。
# 本番環境用 KV 名前空間を作成
wrangler kv namespace create SHORTLINKS
# プレビュー環境用 KV 名前空間を作成(ローカルテスト用)
wrangler kv namespace create SHORTLINKS --preview
実行後、次のような 2 つの ID が返されます。
{ binding = "SHORTLINKS", id = "abc123..." }
{ binding = "SHORTLINKS", preview_id = "def456..." }
重要:この 2 つの ID をメモしておいてください。後で使います。
次に wrangler.toml を編集し、KV バインディングを追加します。
name = "my-shortlink"
main = "src/index.js"
compatibility_date = "2025-12-01"
# KV 名前空間バインディング
kv_namespaces = [
{ binding = "SHORTLINKS", id = "あなたの production ID", preview_id = "あなたの preview ID" }
]
binding = "SHORTLINKS" により、コード内から env.SHORTLINKS でこの KV ストレージにアクセスできます。
Step 2:基本的な短縮 URL 機能を実装
コアコードを書きます。src/index.js を開き、以下を記述します。
export default {
async fetch(request, env) {
const url = new URL(request.url);
const path = url.pathname.slice(1); // 去掉开头的 /
// 处理根路径
if (path === '') {
return new Response('欢迎使用短链服务!', { status: 200 });
}
// GET 请求:短链重定向
if (request.method === 'GET') {
// 从 KV 中查询短码对应的原始 URL
const targetUrl = await env.SHORTLINKS.get(path);
if (targetUrl) {
// 找到了,301 重定向
return Response.redirect(targetUrl, 301);
} else {
// 没找到,返回 404
return new Response('短链不存在', { status: 404 });
}
}
// POST 请求:创建短链
if (request.method === 'POST') {
try {
const body = await request.json();
const { url: targetUrl, code } = body;
// 基本校验
if (!targetUrl) {
return new Response('缺少 url 参数', { status: 400 });
}
// 生成短码
const shortCode = code || generateRandomCode();
// 检查短码是否已存在
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
return new Response('短码已存在', { status: 409 });
}
// 存入 KV
await env.SHORTLINKS.put(shortCode, targetUrl);
// 返回结果
return new Response(JSON.stringify({
shortCode,
shortUrl: `${url.origin}/${shortCode}`,
targetUrl
}), {
status: 201,
headers: { 'Content-Type': 'application/json' }
});
} catch (error) {
return new Response('请求格式错误', { status: 400 });
}
}
// 其他请求方法不支持
return new Response('方法不允许', { status: 405 });
}
};
// 生成随机短码(6位字母数字组合)
function generateRandomCode(length = 6) {
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let code = '';
for (let i = 0; i < length; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
return code;
}
コードの説明:
GETリクエスト:ユーザーがyourdomain.com/abc123にアクセスすると、KV からabc123に対応する元の URL を取得し、301 リダイレクトPOSTリクエスト:urlと任意のcodeパラメータを受け取り、codeがなければランダム生成して KV に保存generateRandomCode:6 桁のランダム英数字を生成
Step 3:ローカルテスト
コードが書けたら、まずローカルでテストします。
wrangler dev
ローカルサーバーが起動します。通常は http://localhost:8787 です。
短縮 URL 作成のテスト:
curl -X POST http://localhost:8787 \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
返却例:
{
"shortCode": "aBc123",
"shortUrl": "http://localhost:8787/aBc123",
"targetUrl": "https://example.com"
}
短縮 URL アクセスのテスト:
ブラウザで http://localhost:8787/aBc123 を開くと、https://example.com にリダイレクトされるはずです。
問題なければ、基本機能は OK です。
Step 4:カスタム短縮コードのサポートを追加
上記のコードはすでにカスタム短縮コードに対応しています。POST リクエストに code パラメータを付けるだけです。
curl -X POST http://localhost:8787 \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "code": "my-link"}'
より堅牢にするため、バリデーションを追加できます。
// 在 POST 请求处理部分,生成短码之前加上这段
// 如果用户提供了自定义短码,校验格式
if (code) {
// 只允许字母、数字、连字符
if (!/^[a-zA-Z0-9-]+$/.test(code)) {
return new Response('短码格式不正确(仅支持字母、数字、连字符)', { status: 400 });
}
// 长度限制
if (code.length < 3 || code.length > 20) {
return new Response('短码长度必须在 3-20 之间', { status: 400 });
}
}
特殊文字や長すぎる短縮コードなど、不適切な短縮コードの作成を防げます。
Step 5:アクセス統計を実装
短縮 URL 機能だけでなく、各リンクのアクセス回数も知りたい場合があります。
考え方:
- 短縮 URL アクセス時に、リダイレクトと同時にアクセス回数を +1
- 統計データも KV に保存。key の形式は
stats:{shortCode}
GET リクエスト部分のコードを修正します。
// GET 请求:短链重定向
if (request.method === 'GET') {
const targetUrl = await env.SHORTLINKS.get(path);
if (targetUrl) {
// 异步更新访问统计(不阻塞重定向)
const statsKey = `stats:${path}`;
// 后台更新统计,不影响重定向速度
env.SHORTLINKS.get(statsKey).then(count => {
const newCount = (parseInt(count) || 0) + 1;
env.SHORTLINKS.put(statsKey, newCount.toString());
});
return Response.redirect(targetUrl, 301);
} else {
return new Response('短链不存在', { status: 404 });
}
}
統計照会 API を追加:
// 在 GET 请求处理前,加上这个判断
if (path.startsWith('stats/')) {
const shortCode = path.slice(6); // 去掉 stats/ 前缀
const statsKey = `stats:${shortCode}`;
const count = await env.SHORTLINKS.get(statsKey);
return new Response(JSON.stringify({
shortCode,
visits: parseInt(count) || 0
}), {
headers: { 'Content-Type': 'application/json' }
});
}
http://localhost:8787/stats/abc123 にアクセスすれば、特定の短縮 URL のアクセス回数を照会できます。
注意:KV はアトミック操作に非対応のため、高並行時のアクセス統計は不正確になる可能性があります。精密な統計が必要なら Durable Objects を使うべきですが、個人利用の大半のシナリオではこの方法で十分です。
Step 6:本番環境にデプロイ
テストに問題がなければ、Cloudflare のグローバルネットワークにデプロイできます。
wrangler deploy
デプロイ成功後、Wrangler は https://my-shortlink.your-subdomain.workers.dev のような URL を返します。
この URL が短縮 URL サービスのエンドポイントです。グローバルアクセス、高速配信。
カスタムドメインのバインド(任意):
独自ドメイン(例:short.example.com)がある場合、Cloudflare Dashboard からバインドできます。
- Workers & Pages ページに移動
- 対象の Worker を選択
- Settings > Triggers をクリック
- Custom Domain を追加
バインド後、https://short.example.com/abc123 のような URL で短縮 URL にアクセスできます。
応用機能
基本機能ができたら、さらに以下の機能を追加できます。
1. 短縮 URL の一括作成
複数の短縮 URL を一度に作成する一括 API を追加できます。
// 在 POST 请求处理部分,添加批量创建逻辑
if (request.method === 'POST' && url.pathname === '/batch') {
try {
const body = await request.json();
const links = body.links; // 格式:[{url, code?}, ...]
if (!Array.isArray(links)) {
return new Response('links 必须是数组', { status: 400 });
}
const results = [];
for (const link of links) {
const { url: targetUrl, code } = link;
const shortCode = code || generateRandomCode();
// 检查是否已存在
const existing = await env.SHORTLINKS.get(shortCode);
if (!existing) {
await env.SHORTLINKS.put(shortCode, targetUrl);
results.push({ shortCode, targetUrl, success: true });
} else {
results.push({ shortCode, targetUrl, success: false, error: '短码已存在' });
}
}
return new Response(JSON.stringify({ results }), {
headers: { 'Content-Type': 'application/json' }
});
} catch (error) {
return new Response('请求格式错误', { status: 400 });
}
}
呼び出し例:
curl -X POST http://localhost:8787/batch \
-H "Content-Type: application/json" \
-d '{
"links": [
{"url": "https://example1.com", "code": "link1"},
{"url": "https://example2.com"}
]
}'
2. 有効期限の設定
KV は TTL(Time To Live)をサポートしており、短縮 URL を自動的に期限切れにできます。
// 在存入 KV 时,添加 expirationTtl 参数
await env.SHORTLINKS.put(shortCode, targetUrl, {
expirationTtl: 86400 // 24小时后自动删除,单位:秒
});
ユーザーに有効期限をカスタマイズさせる場合:
const { url: targetUrl, code, ttl } = body;
const options = {};
if (ttl) {
options.expirationTtl = parseInt(ttl);
}
await env.SHORTLINKS.put(shortCode, targetUrl, options);
3. アクセス制御
誰でも短縮 URL を作成できる状態にしたくない場合、シンプルな API Token 認証を追加できます。
// 在 wrangler.toml 里添加环境变量
# [vars]
# API_TOKEN = "your-secret-token"
// 在 POST 请求处理前,添加验证
if (request.method === 'POST') {
const token = request.headers.get('Authorization');
if (token !== `Bearer ${env.API_TOKEN}`) {
return new Response('未授权', { status: 401 });
}
// ... 后续创建短链逻辑
}
呼び出し時に token を付与:
curl -X POST http://localhost:8787 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-token" \
-d '{"url": "https://example.com"}'
4. 悪用防止(Rate Limiting)
大量の短縮 URL を悪意を持って作成されるのを防ぐため、シンプルなレート制限を追加できます。
// 使用 IP 地址作为限流标识
const clientIp = request.headers.get('CF-Connecting-IP');
const rateLimitKey = `ratelimit:${clientIp}`;
// 获取当前计数
const count = await env.SHORTLINKS.get(rateLimitKey);
if (parseInt(count) >= 10) {
return new Response('请求过于频繁,请稍后再试', { status: 429 });
}
// 计数 +1,设置 1 小时过期
const newCount = (parseInt(count) || 0) + 1;
await env.SHORTLINKS.put(rateLimitKey, newCount.toString(), {
expirationTtl: 3600 // 1小时
});
この方法で、各 IP あたり 1 時間に最大 10 個の短縮 URL 作成に制限できます。
パフォーマンス最適化とベストプラクティス
パフォーマンス最適化のコツ
1. キャッシュ戦略
KV の読み取り自体は速い(中央値 12ms)ですが、さらに速くしたい場合は Worker メモリにキャッシュ層を追加できます。
// 使用 Map 作为简单的内存缓存
const cache = new Map();
const targetUrl = cache.get(path) || await env.SHORTLINKS.get(path);
if (targetUrl) {
cache.set(path, targetUrl);
return Response.redirect(targetUrl, 301);
}
ただし Worker のメモリは永続化されないため、再起動後は失われます。
2. KV 書き込み回数の削減
KV の無料枠は 1 日 1000 回書き込みです。アクセス統計の書き込みが多すぎると超過する可能性があります。
解決策:
- Durable Objects で統計を処理(アトミック操作対応)
- N 回アクセスに 1 回だけ KV に書き込む
- Cloudflare Analytics Engine を利用
3. CORS 設定
短縮 URL サービスをフロントエンドから呼び出す場合、CORS ヘッダーを忘れずに追加してください。
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
};
// OPTIONS 请求处理
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
// 在返回响应时添加 CORS 头
return new Response(body, {
headers: { ...headers, ...corsHeaders }
});
コスト管理
Cloudflare Workers の無料枠は非常に手厚いですが、以下に注意してください。
無料枠:
- 1 日 10 万リクエスト
- KV:1 日 10 万回読み取り、1000 回書き込み
- 1 リクエストあたり 10ms の CPU 時間
無料枠超過時のコスト(Workers Paid プラン、$5/月〜):
- 100 万リクエストあたり $0.50
- KV 読み取り 100 万回あたり $0.50
- KV 書き込み 100 万回あたり $5.00
- KV ストレージ $0.50/GB/月
個人利用なら、基本無料枠を超えることはありません。小規模チームでも 1 日数万アクセスまで対応できます。
リクエスト数を節約するコツ:
- 302 ではなく 301 リダイレクト(ブラウザがキャッシュ)
- 静的リソース(管理ページなど)は Workers Pages でホストし、Worker リクエスト数を消費しない
- TTL を適切に設定し、期限切れリンクを自動クリーンアップ
セキュリティの考慮事項
1. 悪意ある短縮 URL の防止
短縮 URL サービスを公開すると、悪意あるサイトのリンクを短縮する悪用の可能性があります。
推奨:
- API Token 認証を追加
- 既知の悪意あるドメインのブラックリストでフィルタ
- 作成者 IP を記録して追跡可能に
2. 短縮コード衝突の防止
6 桁の英数字は 62^6 ≈ 568 億通りで、衝突の可能性は低いですが、確認は必要です。
// 创建短链时,检查是否已存在
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
return new Response('短码已存在', { status: 409 });
}
3. 転送先 URL の制限
ホワイトリストで特定ドメインへのリダイレクトのみ許可できます。
const allowedDomains = ['example.com', 'mywebsite.com'];
const targetDomain = new URL(targetUrl).hostname;
if (!allowedDomains.some(d => targetDomain.endsWith(d))) {
return new Response('不允许的目标域名', { status: 403 });
}
実際の使用感
構築後、数か月間利用しています。実際の使用感を共有します。
メリット:
- 本当に速い:グローバルアクセスのレイテンシは基本 50ms 以内。以前使っていたサードパーティより大幅に速い
- 安定:Cloudflare のネットワークは非常に安定。ダウンタイムはほぼ経験なし
- 手間いらず:デプロイ後は放置で OK。自動スケール、トラフィック急増も心配不要
- 無料:1 日のリクエスト数は数千程度。完全に無料枠内
小さな落とし穴:
- KV 書き込み遅延:KV は結果整合性のため、書き込み後に数十秒かかる場合がある。ただし短縮 URL 作成直後に即アクセスされることは稀なので、短縮 URL シナリオでは影響は小さい
- 統計の精度:KV はアトミック操作非対応。高並行時に統計に誤差が出る。精密な統計が必要なら Durable Objects だが、無料枠超過後はコスト増
今後の計画:
- シンプルな Dashboard を Workers Pages で構築し、短縮 URL を可視化管理
- Cloudflare Analytics を連携し、詳細なアクセスデータ(参照元、地域など)を確認
- QR コード生成機能を追加し、オフライン共有を容易に
まとめ
Cloudflare Workers + KV で短縮 URL サービスを構築するのは、本当に速くて安い方法です。コアコードは 100 行未満、デプロイは 1 コマンド。何よりデータが完全に自分の手元にあり、サードパーティのサービス終了を心配する必要がありません。
同様のニーズがあるなら、ぜひ試してみてください。コードはすべて掲載したので、手順どおり進めれば 30 分程度で公開できます。
コアステップのおさらい:
- Cloudflare アカウントを登録し、Wrangler をインストール
- KV 名前空間を作成し、wrangler.toml を設定
- GET(リダイレクト)と POST(短縮 URL 作成)を処理するコードを書く
- ローカルテスト後、本番にデプロイ
統計、一括作成、有効期限などの機能は後から追加できます。コードが自分の手元にあるので、好きなように改修できる——この感覚は本当に気持ちいいものです。
ご質問があればコメントでお気軽にどうぞ。あなたも自前の短縮 URL サービスを構築できることを願っています。
Cloudflare Workers + KV で自前の短縮 URL サービスを構築する完全手順
短縮 URL 作成、リダイレクト、アクセス統計などを含む短縮 URL サービスをゼロから構築し、30 分で公開
⏱️ 目安時間: 30 分
- 1
ステップ1: 準備:Cloudflare アカウント登録と Wrangler CLI のインストール
ステップ 1:Cloudflare アカウントを登録
• cloudflare.com でアカウントを作成。無料プランで十分です
ステップ 2:Wrangler CLI をインストール
• Wrangler は Cloudflare 公式の CLI ツールで、Workers プロジェクトを管理します
• 実行:npm install -g wrangler
• または:yarn global add wrangler
• インストール後、Cloudflare アカウントにログイン:wrangler login
• ブラウザが開くので、許可をクリックするだけです
ステップ 3:プロジェクトを作成
• mkdir my-shortlink
• cd my-shortlink
• wrangler init
• プロンプトに従い、JavaScript プロジェクトを作成(TypeScript も可) - 2
ステップ2: KV 名前空間の作成と wrangler.toml の設定
KV 名前空間を作成:
方法 1:Cloudflare Dashboard
• Workers & Pages → KV に移動
• Create a namespace をクリック
• 名前を入力(例:SHORTLINKS)して作成
方法 2:コマンドライン
• wrangler kv:namespace create SHORTLINKS
wrangler.toml を設定:
wrangler.toml を開き、末尾に KV バインディング設定を追加:
[[kv_namespaces]]
binding = "SHORTLINKS"
id = "あなたの名前空間 ID"
これでコード内から env.SHORTLINKS で KV にアクセスできます - 3
ステップ3: コアコードの作成:短縮 URL 作成とリダイレクト機能
コア機能の実装:
1. 短縮コードの生成:
• カスタム短縮コードとランダム生成に対応
• 6 桁の英数字の組み合わせが使える
• 62^6≈568 億通りで、衝突の可能性は低い
2. KV への保存:
• 短縮コードを key、元の URL を value として保存
• metadata(作成日時、アクセス回数など)も保存可能
3. リダイレクト:
• GET リクエスト時に KV から元の URL を読み取り
• 302 リダイレクトで元の URL へ転送
4. アクセス統計:
• アクセス回数と時刻を記録
• KV の metadata に保存可能
コード例:
• GET リクエスト(リダイレクト):URL パスから短縮コードを取得し、KV から元の URL を読み取り、存在すれば 302 リダイレクト、なければ 404
• POST リクエスト(短縮 URL 作成):元の URL と任意のカスタム短縮コードを受け取り、短縮コードを生成、衝突防止のため存在確認、KV に保存、短縮 URL を返却 - 4
ステップ4: ローカルテストと本番デプロイ
ローカルテスト:
1. wrangler dev でローカル開発サーバーを起動
2. 短縮 URL 作成とリダイレクト機能をテスト
curl でテスト:
• 短縮 URL 作成:
curl -X POST http://localhost:8787/create -H "Content-Type: application/json" -d '{"url":"https://example.com"}'
• 短縮 URL にアクセス:
curl -L http://localhost:8787/abc123
(元の URL にリダイレクトされます)
本番デプロイ:
• 実行:wrangler deploy
• Wrangler が Worker を Cloudflare に自動デプロイ
• デプロイ成功後、次の形式の URL が表示されます:
your-worker-name.your-subdomain.workers.dev
• これで短縮 URL サービスが公開されました! - 5
ステップ5: 応用機能とセキュリティの考慮事項
応用機能:1) アクセス統計(アクセス回数と時刻を記録し、KV の metadata に保存、アクセスのたびにカウント更新);2) 有効期限(短縮 URL に有効期限を設定し、期限切れで自動無効化);3) 一括作成(複数の短縮 URL を一度に作成);4) 管理画面(Workers Pages でシンプルな Dashboard を構築し、短縮 URL を可視化管理)。セキュリティ:1) 悪意ある短縮 URL の防止(API Token 認証、既知の悪意あるドメインのブラックリスト、作成者 IP の記録);2) 短縮コード衝突の防止(6 桁英数字は 62^6≈568 億通りで衝突は稀だが、作成時に存在確認が必要);3) 転送先 URL の制限(ホワイトリストで特定ドメインへのリダイレクトのみ許可)。リクエスト数を節約するコツ:302 ではなく 301 リダイレクト(ブラウザがキャッシュ)、静的リソース(管理ページなど)は Workers Pages でホストして Worker リクエスト数を消費しない、TTL を適切に設定して期限切れリンクを自動クリーンアップ。
FAQ
なぜ自前の短縮 URL サービスを構築するのか?Workers + KV にはどんな利点がある?
Workers + KV の利点:
• 無料枠が非常に大きい(1 日 10 万リクエスト)
• 世界 200 以上の拠点でアクセス速度が速い
• デプロイが簡単、数行のコードで動く
• データは完全に自分のもの、保存期間も自由
サードパーティとの比較:
• データ管理(サードパーティはデータが外部、自前は完全管理)
• カスタマイズ(サードパーティは機能固定、自前は自由)
• 安定性(サードパーティは終了の可能性、自前は Cloudflare 基盤)
• 広告(サードパーティは中間ページあり、自前は広告なし)
• コスト(サードパーティは有料の可能性、自前は基本無料)
• アクセス速度(サードパーティは事業者次第、自前はグローバルエッジネットワーク)
KV ストレージにはどんな利点がある?短縮 URL サービスに適している理由は?
KV ストレージの利点:
• 読み取りが超高速、中央値 12ms(データがエッジノードにキャッシュされるため)
• グローバル同期、書き込み後 60 秒以内に全世界のノードに同期
• 無料枠:1 日 10 万回読み取り、1000 回書き込み
短縮 URL サービスには KV が最適:
• 短縮コードを key、元の URL を value
• 読み多く書き少ないシナリオ(作成は少なく、アクセスは多い)
• グローバル分散でどこからアクセスしても速い
無料枠:
• Workers:1 日 10 万リクエスト
• KV:1 日 10 万回読み取り、1000 回書き込み
• 個人利用なら十分。小規模チームでも 1 日数万アクセスまで対応
無料枠超過時のコスト(Workers Paid プラン $5/月〜):
• 100 万リクエストあたり $0.50
• KV 読み取り 100 万回あたり $0.50
• KV 書き込み 100 万回あたり $5.00
• KV ストレージ $0.50/GB/月
短縮 URL サービスをゼロから構築するには?具体的な手順は?
ステップ 1:Cloudflare アカウントを登録(cloudflare.com で無料アカウントを作成)
ステップ 2:Wrangler CLI をインストール(npm install -g wrangler を実行し、wrangler login でログイン)
ステップ 3:プロジェクトを作成(mkdir my-shortlink、cd my-shortlink、wrangler init)
KV 名前空間の作成と設定:
• Cloudflare Dashboard で Workers & Pages → KV に移動し、Create a namespace をクリック、名前(例:SHORTLINKS)を入力して作成
• またはコマンドラインで:wrangler kv:namespace create SHORTLINKS
wrangler.toml の設定:
• wrangler.toml を開き、末尾に KV バインディング設定を追加
• これでコード内から env.SHORTLINKS で KV にアクセスできます
コアコードの作成:
GET リクエスト(リダイレクト):
• URL パスから短縮コードを取得
• KV から元の URL を読み取り
• 存在すれば 302 リダイレクト、なければ 404
POST リクエスト(短縮 URL 作成):
• 元の URL と任意のカスタム短縮コードを受け取り
• 短縮コードを生成(カスタムがなければランダム生成)
• 衝突防止のため存在確認
• KV に保存し、短縮 URL を返却
ローカルテストとデプロイ:
• wrangler dev でローカル開発サーバーを起動し、短縮 URL 作成とリダイレクトをテスト
• wrangler deploy で本番にデプロイ
短縮 URL サービスのコア機能はどう実装する?
1) 短縮コードの生成:
• カスタム短縮コードとランダム生成に対応
• 6 桁の英数字で 62^6≈568 億通り、衝突の可能性は低い
2) KV への保存:
• 短縮コードを key、元の URL を value
• 作成日時、アクセス回数などの metadata も保存可能
3) リダイレクト:
• GET リクエスト時に KV から元の URL を読み取り
• 302 リダイレクトで元の URL へ転送
4) アクセス統計:
• アクセス回数と時刻を記録
• KV の metadata に保存し、アクセスのたびにカウント更新
コード例:
GET リクエスト(リダイレクト):
• URL パスから短縮コードを取得
• KV から元の URL を読み取り
• 存在すれば 302 リダイレクト、なければ 404
POST リクエスト(短縮 URL 作成):
• 元の URL と任意のカスタム短縮コードを受け取り
• 短縮コードを生成(カスタムがなければランダム生成)
• 衝突防止のため存在確認
• KV に保存(短縮コードを key、元の URL を value)
• 短縮 URL を返却
応用機能:
• アクセス統計(アクセス回数と時刻を記録)
• 有効期限(短縮 URL に有効期限を設定し、期限切れで自動無効化)
• 一括作成(複数の短縮 URL を一度に作成)
• 管理画面(Workers Pages で Dashboard を構築し、短縮 URL を可視化管理)
短縮 URL サービスを使う際のセキュリティ上の考慮事項は?
1) 悪意ある短縮 URL の防止:
• 短縮 URL サービスを公開すると、悪意あるサイトのリンクを短縮する悪用の可能性
• 推奨:
- API Token 認証を追加
- 既知の悪意あるドメインのブラックリストでフィルタ
- 作成者 IP を記録して追跡可能に
2) 短縮コード衝突の防止:
• 6 桁英数字は 62^6≈568 億通りで衝突は稀だが、確認は必要
• 短縮 URL 作成時に存在確認:
const existing = await env.SHORTLINKS.get(shortCode);
if (existing) {
return new Response('短码已存在', { status: 409 });
}
3) 転送先 URL の制限:
• ホワイトリストで特定ドメインへのリダイレクトのみ許可:
const allowedDomains = ['example.com', 'mywebsite.com'];
const targetDomain = new URL(targetUrl).hostname;
if (!allowedDomains.some(d => targetDomain.endsWith(d))) {
return new Response('不允许的目标域名', { status: 403 });
}
リクエスト数を節約するコツ:
• 302 ではなく 301 リダイレクト(ブラウザがキャッシュ)
• 静的リソース(管理ページなど)は Workers Pages でホストして Worker リクエスト数を消費しない
• TTL を適切に設定して期限切れリンクを自動クリーンアップ
実際の使用感はどう?メリットとデメリットは?
メリット:
• 本当に速い(グローバルアクセスのレイテンシは基本 50ms 以内、以前使っていたサードパーティより大幅に速い)
• 安定(Cloudflare のネットワークは非常に安定、ダウンタイムはほぼ経験なし)
• 手間いらず(デプロイ後は放置で OK、自動スケール、トラフィック急増も心配不要)
• 無料(1 日のリクエスト数は数千程度、完全に無料枠内)
小さな落とし穴:
• KV 書き込み遅延(KV は結果整合性のため、書き込み後に数十秒かかる場合があるが、短縮 URL 作成直後に即アクセスされることは稀なので影響は小さい)
• 統計の精度(KV はアトミック操作非対応、高並行時に統計に誤差。精密な統計が必要なら Durable Objects だが、無料枠超過後はコスト増)
今後の計画:
• シンプルな Dashboard を Workers Pages で構築し、短縮 URL を可視化管理
• Cloudflare Analytics を連携し、詳細なアクセスデータ(参照元、地域など)を確認
• QR コード生成機能を追加し、オフライン共有を容易に
5分で読めます · 公開日: 2025年12月1日 · 更新日: 2026年6月8日
Cloudflare フルスタック実践
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
S3 の転送料金が毎月数千ドル?R2 へ 3 ステップで移行し 90% 削減(実例付き)
S3 の転送料金で請求が膨らんでいませんか?Cloudflare R2 への移行で出口料金ゼロ、年間 $10,896 以上の節約も。3 つの移行方式比較、API 互換性の実測、30 分でできる移行手順とコスト試算、完全操作ガイド付き。
第 14 / 23 記事
次の記事
フロントに API Key を置いて不正利用された?Workers プロキシで 5 分、キーを守り毎日 10 万リクエスト無料
フロントから API を直接叩くとキーが漏えいし、不正利用されるリスクがあります。Cloudflare Workers で無料の API プロキシを構築する方法を解説。5 分でデプロイでき、API Key はサーバー側の環境変数に安全保管。毎日 10 万リクエスト無料、CORS 問題も解決。
第 16 / 23 記事
関連記事
Cloudflare無料版の制限2026:Free、Pro、Business料金比較
Cloudflare無料版の制限2026:Free、Pro、Business料金比較
Cloudflare Pages で静的ブログをデプロイする完全ガイド:5 大フレームワークの設定で落とし穴を避ける
Cloudflare Pages で静的ブログをデプロイする完全ガイド:5 大フレームワークの設定で落とし穴を避ける
Cloudflare Pages でフロントエンドをデプロイする完全ガイド:React/Vue/Next.js の設定とエラー対処
コメント
GitHubアカウントでログインしてコメントできます