Firefox で拡張機能がLAN内のサーバーアクセスに関して動作しない

この記事を作った動機 Chromium 系列のブラウザでは動いていた拡張機能が、Firefox では動かないということがあった。原因を調査してみたところ、ネットワーク周りに問題があり、manifest.json の修正で解決できそうなことが分かった。 問題が解決するまでに試したことを記録しておきたい。 前提 拡張機能はLANにあるサーバーにアクセスすることで動作する LANにあるサーバーにアクセスするときに Firefox の環境にてエラーが発生する LAN内へのサーバーへのアクセスは、HTTPsを用いた通信であり、Firefox側にすでに証明書が入っている LAN内へのサーバーへのアクセスは、直接ブラウザでURLを叩く分には正常に動作する LAN内へのサーバーアクセスは、直接のIP指定ではなく、専用にLAN内だけで通用するドメインをあてがっている 試したこと 実装をXMLHttpRequestからfetchに変更 -> 効果なし manifest.jsonのmatchesに拡張機能がアクセスするドメインの追加 -> 効果なし manifest.jsonのpermissionsに対象ドメインを追加 -> 効果あり fetchでsame-origin -> 効果なし let res = await window.fetch(url, { credentials: 'same-origin' }) 現状のmanifest.jsonの例 { "manifest_version": 2, "name": "ext name", "description": "test123", "version": "2.2", "permissions": [ "activeTab", "https://my.domain/*" ], "icons": { "128": "imgs/test.png" }, "browser_action": { "default_popup": "action/pop.html", "default_icon": { "128": "imgs/test.png" } }, "content_scripts": [ { "js": [ "scripts/dist/bundle.js" ], "matches": [ "https://www.target.com/*", "https://my.domain/*", "https://*.my.domain/*" ] } ], "background": { "scripts": ["scripts/background.js"], "persistent": false }, "browser_specific_settings": { "gecko": { "id": "omited" } } } 参考にしたサイトとか Firefox Won’t Open Local IP Addresses? Fix It https://browserhow.com/fix-firefox-blocking-access-to-local-ip-addresses/ (2026年11月4日) Firefox add-on local area network communication capabilities - Stack Overflow https://stackoverflow.com/questions/20060162/firefox-add-on-local-area-network-communication-capabilities (2026年11月4日) 1829925 - AV software Avira breaks websites https://bugzilla.mozilla.org/show_bug.cgi?id=1829925 (2026年11月4日) ローカルLLM (Qwen-3.8-27B) (2026年11月4日)

2026年11月4日

Google-Chrome をデバックモードで開き、ローカルホスト上で待機させたい

この記事を作った動機 Google-Chrome を開発用に使っており、裏でデバックをするための実装をしていたところ、Chromeがデバッグモードとして上手く動作しないことが分かったので簡易的なメモが欲しい。 問題点 Linux 環境にて、単にローカルホストにデバックソケットを立てるように指示するだけでは不十分で、Chromeがデバックモードで立ち上がらない。すでにすべてのChromeインスタンスをpkill chromeなどで完全に排除した状態から始めて、その症状が再現する。 google-chrome-stable --remote-debugging-port=5588 対処 プロファイルの情報を保存するディレクトリを指定すると、デバックモードとして立ち上がった。以下はLinux環境向けの例であり、各自どのディレクトリにプロファイルを保存するかはOSなどに合わせて合わせる必要がある。 google-chrome-stable --remote-debugging-port=5588 --user-data-dir="/tmp/chrome_debug" 利便性の観点 /tmpはLinuxでRAM上に作成される起動時に一時的に確保されるディスク領域であり、再起動したりすると内容が消える。Guestモードに近い使い方をしたいときに有効であるが、それだといちいちブラウザを一番最初に起動した扱いとなり、初期セットアップのWindowsでいうところのOOBEみたいなのが出てきてしまう。そこで以下のオプションを指定することでそれらを抑制し、すぐにブラウザが使えるようにできる。 # --no-first-run --no-default-browser-check google-chrome-stable --remote-debugging-port=5588 --user-data-dir="/tmp/chrome_debug" --no-first-run --no-default-browser-check Chrome がデバッグモードで動いているかの検証方法 以下のURLにFirefoxなどの別のブラウザでアクセスし、JSON応答が帰ってくるか確かめる。帰ってこない場合、Chromeがデバッグモードで起動していないか、ポートが衝突しているなどのネットワーク上の不具合である可能性がある。 http://127.0.0.1:5555/json/version 参考にしたサイトとか Access local servers and Chrome instances with port forwarding | Chrome DevTools | Chrome for Developers https://developer.chrome.com/docs/devtools/remote-debugging/local-server/ (2026年10月30日) Gemma-4-31B (ローカルLLM) (2026年10月30日)

2026年10月30日

Inputタグにて、zustandのストアを正しく更新したり、ユーザーの入力を正しく受け付けることができない

この記事を作った動機 React + Zustand + TypeScirpt の組み合わせで、Input タグにて躓いたことがあったので記録したい。具体的な症状としては、要素の内容を変更しようとしても、一切微動だにせず、値を変えることができないという症状がある。 問題の挙動 期待する挙動 問題が起こったコード 問題がない部分 // ... <LabelTextEntryItem name="IP / URL" callback={(resultString:string) => { setNetwork((prev) => ({ ...prev, IPorDomainName: resultString })) }} init={getNetwork().IPorDomainName} ></LabelTextEntryItem> // ... 問題がある部分 // ... export function LabelTextEntryItem({ name , init , callback}:{ name:string, init:string , callback:(result:string) => void }){ return <div className="flex flex row mb-4"> <div className="label text-xl noSelect">{name}:</div> <div className="ml-auto"> <HoverAnimation> // 問題の箇所 -------------------- // 問題の箇所 -------------------- <input className="ml-auto text-xl w-30" id="entry" value={init} type="text" onChange={(event:ChangeEvent<HTMLInputElement>) => { callback(event.target.value) }}></input> // 問題の箇所 -------------------- // 問題の箇所 -------------------- </HoverAnimation> </div> </div> } // ... 解決に至った方法 問題が再現する条件として、Zustandで定義したストアの内容をInputタグにて表示するときにvalueの引数としてそれを指定していることがある。解決のためには、defaultValueとしてZustand内の内容を表示するようにすることで解決された。なぜこれで症状が解決するのかは分かってない。コンソールでコールバックが呼ばれたときの内容を確認してみたところ、valueとして引数にZustandの内容を与えても、値自体は更新された値がコールバックに正しく伝達できていることが確認でき、コールバック内の値の更新処理が上手くいかない理由が不明である。defaultValueとvalueのinputタグにおける違いとは多分値の拘束力なのではないか?と思われる。valueに固定値を指定してしまうと、編集不能になるとかでもあるのだろうか? ...

2026年10月14日

npm において、vite: command not found となり、開発サーバを立てられず何もできない問題が起こる

この記事を作った動機 Linux 環境にて簡単に Web アプリを作ろうとしたところ、以下のようになって開発サーバを立ち上げられない事態になり、開発が続行できなくなったということがあって、だいぶ時間を溶かしたので記録を取る。 npm create vite@latest # ... # npx でも症状は同じ npm run dev # npm notice run rss-listing@0.0.0 dev # npm notice run vite # sh: 行 1: vite: command not found 簡単な結論 npm を使ったプロジェクトを立ち上げる際は、フォルダのパスに特殊文字が含まれていないか注意する。:がパスに含まれていた場合、npm はそれを自動的にエスケープするなどの処理をせずに、PATHを登録してしまう。npm の機構によって動的にPATHが正しく登録できないと、npm でインストールされたパッケージのバイナリやスクリプトが必要なタイミングで実行できず、開発を続行できない。BASH の PATH の解釈が不正なところで途切れて、npm の動作に必要なバイナリやスクリプトへのパスが通らず、動作が破綻する。問題の具体例は以下のとおりである。 問題のパスの例 # /home/useName/work/free/2026-08-18-09:16:14-1787012174/ProjectName/node_modules/.bin 問題のパスが npm(npx) によって、PATH に登録される例 # /home/useName/work/free/2026-08-18-09:16:14-1787012174/ProjectName/node_modules/.bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/opt/miniconda3/condabin:/usr/local/bin # 実際にはもっと長く続くが例として途中でちょん切っている。 BASH での解釈のされ方の例 # /home/useName/work/free/2026-08-18-09 # 意図しないところでパスがちょん切れる # 16 # 意図しないところでパスがちょん切れる # 14-1787012174/ProjectName/node_modules/.bin # /home/linuxbrew/.linuxbrew/bin # /home/linuxbrew/.linuxbrew/sbin # /opt/miniconda3/condabin # /usr/local/bin # ... なおこのような問題は、Windows など最初から、":" の文字がフォルダ名などに特殊文字として登録できないファイルシステムを使う環境では起こらないかもしれない。私が、普段の環境で使っているのは、Ext4 というファイルシステムであり、":“がファイル名やフォルダ名に含めることができ、問題が起こったものだと思われる。npm 関連のリポジトリにこれについて Issue を作ったり Pull Request を作るべきかは謎であるが、私はその点に関して自信は何もないので、結局何もしないだろう。 ...

2026年8月18日

Keyboard Event Tester (For JavaScript)

ツール本体 Keyboard Event Tester Key Value Key: null Code: null Bool Value alt: false ctrl: false meta: false shift: false このツールを作った動機 JavaScript におけるキーボードに関するイベントの戻り値がどうなるか確認できるツールが欲しかったので作っただけである。もともとは、CapsLock を ESC キーとして割り当てる (Keyd,Linux)においてキーボードの再割り当てがうまくいっているか確かめるためのツールとして作っただけである。 ...

2026年7月6日

Trusted Type 関連でエラーが出て、思う様にスクリプトを実行できない

この記事を作った動機 最近ちょっとした JavaScript のツールを作って使おうとしたところ、直接 HTML の文字列を innerHTML として渡すことができないことが分かった。 今の私の理解だと XSS(Cross Site Scripting) 対策のためにテキストデータとして紛れた悪意のある CSS や JavaScript コードなどを実行(反映)しないようにするために、追加された仕組みに引っかかったという認識である。“ポリシー"なるものを定義して、innerHTMLとかに設定されるテキストデータであったHTMLの文字列などを、事前に任意に定義した createHTML などの関数を通して、テキストデータの HTML化などを承認?するような動作を実装する必要があるというイメージである。 エラー内容 function setStyle(){ let style = document.createElement("style") style.innerHTML = ` .positive{ background: red; text-decoration: underline; } .negative{ background: blue; text-decoration: underline; } ` document.body.appendChild(style) } setStyle() // This document requires 'TrustedHTML' assignment. The action has been blocked. 暫定的な対処 以下はとにかく、自分で書いたスクリプトをすぐ動かしたい場合で、動作検証やプライベート目的で、理解したうえで利用することを想定したコード例であり、実用ではセキュリティの問題になるので真面目に悪意のあるコードが実行されないように createHTML などの定義を書く必要がある。 const policy = trustedTypes.createPolicy("my-policy", { createHTML: (s) => s, createScript: (s) => s, }); function setStyle(){ let style = document.createElement("style") style.innerHTML = policy.createHTML(` .positive{ background: red; text-decoration: underline; } .negative{ background: blue; text-decoration: underline; } `) document.body.appendChild(style) } setStyle() 参考にしたサイトとか This document requires ‘TrustedHTML’ assignment. · Issue #482 · killergerbah/asbplayer https://github.com/killergerbah/asbplayer/issues/482 (2026年2月18日) asbplayer/extension/src/pages/youtube-page.ts at dd5f49f3ab97cd5b1eefa2cde113704a125e69b5 · killergerbah/asbplayer https://github.com/killergerbah/asbplayer/blob/dd5f49f3ab97cd5b1eefa2cde113704a125e69b5/extension/src/pages/youtube-page.ts#L18 (2026年2月18日) TrustedTypePolicyFactory: createPolicy() method - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory/createPolicy (2026年2月18日) TrustedTypePolicy - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy (2026年2月18日) Trusted Types API - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API (2026年2月18日)

2026年2月18日

Vite を使って作ったものを Electron アプリとしてバイナリ化する

この記事を作った動機 最近以下の組み合わせでフロントエンドを簡易的に書くということをしていた。 Vite React TypeScript Tailwind CSS zustand それでとりあえず機能的な意味では最低限適当にとりあえず動くという意味ではできたので、気軽に使えるようにしたいと思い、HTTPサーバとか一時的に立てずに、すぐに使えるようにしたかったので、一つのバイナリとしてまとまっていると良いと思った。 そこで色々試したところ、プロジェクト内にElectornプロジェクトを新規作成して、作ったコードをその中のRenderというフォルダ内にそのままコピーし、それをelectron-builderを使って各プラットフォーム向けに一つのバイナリとして作れそうだと調べてみて思った。それでいつものようにそれを実際にやって動くまでがめんどくさかったのでその記録を取る。 バイナリ完成までの試した手順 ※ コマンド実行における作業ディレクトリはViteプロジェクトのルートとする。 Vite プロジェクトを用意する プロジェクトの新規作成 npm create vite # Need to install the following packages: # create-vite@8.2.0 # Ok to proceed? (y) y # # # > npx # > "create-vite" # # │ # ◇ Project name: # │ createElectornAppTest # │ # ◇ Package name: # │ createelectornapptest # │ # ◇ Select a framework: # │ React # │ # ◇ Select a variant: # │ TypeScript # │ # ◇ Use rolldown-vite (Experimental)?: # │ No # │ # ◇ Install with npm and start now? # │ No # │ # ◇ Scaffolding project in /home/username/work/createElectornAppTest... # │ # └ Done. Now run: # # cd createElectornAppTest # npm install # npm run dev ライブラリのインストール npm install zustand npm install tailwindcss @tailwindcss/vite npm install # Command not found が出てきたとき Tailwind CSS の設定 以下を参考にして Tailwind CSS を機能するように設定する。 ...

2026年1月4日

React を使った Web アプリを Android アプリにしたい

この記事を作った動機 React で作った Web アプリを Android に移植しようとしたら超絶めんどくさかったので、記録するだけ。 自分の試した構成 Vite React TypeScript Android Studio (with SDK) npm create vite@latest 使った汎用コマンド集 すべての環境変数をリスト (Windows,PowerShell) gci env:* | sort-object name 環境変数を新規作成 (Windows,PowerShell) # 具体例 ANDROID_HOME にパスを設定する $env:ANDROID_HOME = "C:\Users\[userName]\AppData\Local\Android\Sdk" 特定の環境変数に対してパスを追加 (Windows,PowerShell) # 具体例 ANDROID_HOME にパスを追加設定する $env:ANDROID_HOME += ";C:\Users\[userName]\AppData\Local\Android\Sdk" 準備 Capacitor を使えるようにする 必要なパッケージのインストール npm i @capacitor/core npm i @capacitor/android 初期化する npx cap init android 向けに初期化する npx cap add android ANDROID_HOMEを設定する エラー例 Android SDK のパスが、ANDROID_HOMEとして環境変数に設定されていない場合は、以下のようなエラーが出てくる。 npx cap build android # × Running Gradle build - failed! # [error] # > Configure project :app # WARNING: Using flatDir should be avoided because it doesn't support any meta-data formats. # > Configure project :capacitor-cordova-android-plugins # WARNING: Using flatDir should be avoided because it doesn't support any meta-data formats. # FAILURE: Build failed with an exception. # * What went wrong: # Could not determine the dependencies of task ':app:bundleReleaseResources'. # > SDK location not found. Define a valid SDK location with an ANDROID_HOME environment variable or by setting # the sdk.dir path in your project's local properties file at 'C:\Users\userName\work\TODOListApp\TODO # List\android\local.properties'. # * Try: # > Run with --stacktrace option to get the stack trace. # > Run with --info or --debug option to get more log output. # > Run with --scan to get full insights. # > Get more help at https://help.gradle.org. # BUILD FAILED in 1s ...

2025年11月21日

JavaScript ドラックアンドドロップがうまくいかない

この記事を作った動機 drag and drop の実装について毎回いちいち調べなおしている気がするので、自分用に記録を残したいと思った。 引っかかった内容 drop イベントの受け取り方 単に、dropイベントを設定しただけでは、全く発火しない。dragoverの時点で、preventDefaultする必要があるようである。 ... acceptDropTag(){ // dragover で preventDefault しないことには機能しない this.info.addEventListener("drop",(event) => { this.dragedTagName = event.dataTransfer.getData("text/plain") if(this.dragedTagName != null){ this.setTag(this.dragedTagName) } }) // drop イベントが発火するようにする this.info.addEventListener("dragover",(event) => { event.preventDefault() }) } ... コンソールでは基本dataTransferの中身は見えないことがあるらしい dataTransferの中身は、ブラウザのコンソール内では正しく見えないようである。しかししばらくいろいろ実装を試してみたところ、すでに既存のスクリプト側でdragoverでpreventDefaultして何かしらdropイベントでdataTransferについて読み出したりしている状況において、ブラウザのコンソール側から以下のようなコードを実行してみると内容を見ることができた。 document.querySelector("#videoTable > a:nth-child(5) > div.videoInfoContainer > div.tagInfo").addEventListener("drop",(event) => {console.log(event.dataTransfer.getData("text/plain"))}) // 何かしら内容が表示される。今回はタグ名として、`drive`という文字列を送るようにしていたので、以下のようにコンソールに出てきた。 // drive <- 取得したデータとしてコンソールに出力された内容 dragenter や dragleave では、datatransfer の中身が見えない? dropイベントの発火の仕方が分からないときに、dragenterやdragleaveは発火して、その中にdataTransferの項目もイベントの引数の項目に含まれていたため、dataTransferの存在を知った当初はそれを使おうとしていた。 しかし、自分で試してみたところ、どんなにdragstartでデータを設定しても、event.dataTransfer.items[0] とか event.dataTransfer.getData("text/string") してもエラーにはならないが、空の文字列が返ってきてしまったり何も得られなかった。 document.querySelector("#videoTable > a:nth-child(4) > div.videoInfoContainer > div.tagInfo").addEventListener("dragenter",(event) => {console.log(event)}) // DragEvent {isTrusted: true, dataTransfer: DataTransfer, screenX: 2366, screenY: 676, clientX: 830, …} // temp1 // コンソールで で "Store as global variables" をする。 temp1.dataTransfer.getData("text/plain") '' drag and drop に関する内容 よく使うイベント一覧 dragstart dragover drop 基本的なこと ドラッグされる側 (event はイベントをリッスンするときの引数を意味する) draggable="true"属性を何かしらの形でHTMLタグ側に設定する。 dragstartイベントでドロップされた要素に渡したいデータを設定する。以下二つの選択肢がある。 event.dataTransfer.items.add(data,fromat) する。 event.dataTransfer.setData(format,data) する。 ドロップされる側 (event はイベントをリッスンするときの引数を意味する) dragoverでpreventDefaultして、dropイベントが発火するようにする。 dropイベントで、event.dataTransfer にアクセスしてデータを受け取る。 event.dataTransfer.items[indexNum]する。 event.dataTransfer.getData(format)する。 format 引数で指定する内容 dataTransferでデータをセットしたり読み出すには、データが何であるかタイプを指定する必要がある。ドキュメントのサンプルコードなどを見る限り、それはMIME typeを参照して文字列として指定すればいいと思われる。 ...

2025年11月11日

JavaScript でクラス内の変数にアクセスできない

この記事を作った動機 JavaScript で何度か連発して起こった問題があったので、それを記録する。 問題点 クラス内の関数を何かしらのコールバック関数として直接指定し、呼び出した場合に問題が起こる。その呼び出された関数内では、クラスに付属している変数を参照したり利用することができない。 import { tagListForIndexPage } from "./getTagInfo.js"; class sidebar{ constructor(){ new tagListForIndexPage() this.sidebarElem = document.querySelector(".sidebar") this.showAndHideButton = document.querySelector(".headMenu .headItemContainer .sidebarShowAndHide") this.currentState = "show" this.showAndHideButton.addEventListener("click",() => { if(this.currentState == "hide"){ this.show() }else{ this.hide() } }) // 問題が起こらない部分 // 問題が起こらない部分 this.clacUI() // 問題が起こらない部分 // 問題が起こらない部分 // 問題の部分 // 問題の部分 addEventListener("resize",this.clacUI) // 問題の部分 // 問題の部分 this.hide() } clacUI(){ // 直接クラス内から呼び出されたときは、this.sidebarElemは参照できるが、 // クラス外のコールバックとして”直接”この関数を呼び出すと、this.sidebarElemが参照できずにundefinedでこける。 this.sidebarElem.style.height = String(window.innerHeight - 60) + "px" } show(){ this.currentState = "show" const replacement = this.sidebarElem.getAttribute("class").replaceAll(" hide","") this.sidebarElem.setAttribute("class",replacement) } hide(){ this.currentState = "hide" let replacement = this.sidebarElem.getAttribute("class") if(!replacement.includes("hide")){ replacement += " hide" this.sidebarElem.setAttribute("class",replacement) } } } new sidebar() 解決としたこと 直接this.clacUIをaddEventListenerなどのコールバックとして呼び出すのではなく、匿名関数を一つはさんでからその内部で関数を呼び出すようにした。 ...

2025年11月11日