【環境】
create-nuxt-app: 3.5.2
Nuxt.js: 2.15.2
-> 2.15.4
Vue.js: 2.6.12
Node.js: 12.18.2
-> 14.16.1
序
このエラーは、エラー文は頼りにならないことが多いみたい。
色々なことが原因で、最終的にこういうエラーを吐くことになっているだけなので
毎度、原因を探る作業が必要になりそう。
原因を探るためには、コメントアウトを繰り返し
原因箇所を特定するところから始める。
私の場合は
において、掲題のエラーが出た。
Nginx の設定
気のせい?
以下の記事を書いたのは、Nuxt に触りたての頃。
今振り返ってみると、その後、Nuxt インストール時に
このような現象は起きていないので
気のせいだったかも?
ここまで
Nuxt2.15.2
yarn create nuxt-app hello
と普通にインストールしただけなのに
開発サーバを起動したら
ERROR Cannot read property ‘toLowerCase’ of undefined 11:19:35
at WebSocketServer.handleUpgrade (node_modules/ws/lib/websocket-server.js:193:27)
at WS.handleUpgrade (node_modules/@nuxt/content/lib/ws.js:21:21)
at WS.serve (node_modules/@nuxt/content/lib/ws.js:17:10)
at node_modules/@nuxt/content/lib/middleware.js:12:15
at call (node_modules/connect/index.js:239:7)
at next (node_modules/connect/index.js:183:5)
at next (node_modules/connect/index.js:161:14)
at next (node_modules/connect/index.js:161:14)
at WebpackBundler.middleware (node_modules/@nuxt/webpack/dist/webpack.js:2192:5)
というエラーが出た。
調査
泣きそうになりながら Google 先生へ質問してみた。
nuxt + エラーメッセージ
nuxt Cannot read property ‘toLowerCase’ of undefined
こちらで検索したところ
GitHub:Cannot read property toLowerCase of undefined(2019-07-24)
Qiita:Cannot read property ‘toLowerCase’ of undefinedのとき何を確認すべきか?(2020-12-09)
などが上位にでてきたんだけど
いずれもコーディングミスを原因とするもの。
- HTML の記述ミス
- SSR の問題?(よく理解できなかった)
- javascript による undefine オブジェクトへの参照
どれも新規 Nuxt.js プロジェクトにはありえないので
検索ワードを変更してみることにした。
エラー発生ファイル名 + エラーメッセージ
上記エラーメッセージを引き起こしているファイル名を入れてみた。
WebpackBundler.middleware Cannot read property ‘toLowerCase’ of undefined
で検索すると、WebSocket に関わる記事が最初に出てきた。
中を見ると、エラーメッセージが全く同じ!
@nuxt/content
途中 @nuxt/content が原因っぽいことが書いてあったので
試しに、@nuxt/content を外してインストールしてみると
確かに件のエラーが出ない。
原因その1
更に読み進めると
GitHub:Nginx の WebSocket を有効にすると問題が解消される(2020-10-16)
との返信を見つけた。
解決その1
そこで
Qiita:NginxのリバースプロキシでWebソケットを通す際の設定(2019-12-28)
こちらを参考に、Nginx において WebSocket を有効に設定してみた。
server {
listen 80;
server_name 192.168.56.xxx;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
location / {
proxy_pass http://127.0.0.1:3000;
}
}
これで確かに
@nuxt/content を同梱してインストールしても
件のエラーは出なくなった。
公式
と、ここまで試行錯誤を繰り返した後で
公式に Nginx のリバースプロキシを利用する設定が載っているのを見つけた。
公式:NGINX Using NGINX as a reverse proxy
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
}
server {
listen 80; # the port nginx is listening on
server_name your-domain; # setup your domain here
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
location / {
expires $expires;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000; # set the address of the Node.js instance here
}
}
こちらで試したところ、件のエラーが出た。
WebSocket 有効化
そこで、前述の WebSocket を有効にする設定を加えた。
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
}
server {
listen 80; # the port nginx is listening on
server_name your-domain; # setup your domain here
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
location / {
expires $expires;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000; # set the address of the Node.js instance here
}
}
エラーが出る。。。
直アクセス
curl http://localhost:3000/
と、直接アクセスしたときはエラーが出ないので
やっぱり Nginx の問題だと思われる。
リバースプロキシ排除
location ディレクティブ内のリバースプロキシの設定をコメントアウトしてみた。
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
}
server {
listen 80; # the port nginx is listening on
server_name your-domain; # setup your domain here
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
location / {
expires $expires;
# proxy_redirect off;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_read_timeout 1m;
# proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000; # set the address of the Node.js instance here
}
}
エラーが出ない!
proxy_set_header
いっぱいコメントアウトしたので、選別をしたところ
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
}
server {
listen 80; # the port nginx is listening on
server_name your-domain; # setup your domain here
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
location / {
expires $expires;
proxy_redirect off;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000; # set the address of the Node.js instance here
}
}
これならエラーが出ない。
proxy_set_header があるとエラーが出ることが判明。
リバースプロキシを location の外へ
途方に暮れていたところ
なんとなく、proxy_set_header を location ディレクティブの外へ配置してみた。
map $sent_http_content_type $expires {
"text/html" epoch;
"text/html; charset=utf-8" epoch;
default off;
}
server {
listen 80; # the port nginx is listening on
server_name your-domain; # setup your domain here
gzip on;
gzip_types text/plain application/xml text/css application/javascript;
gzip_min_length 1000;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
location / {
expires $expires;
proxy_redirect off;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000; # set the address of the Node.js instance here
}
}
エラーが出ない!
解決その2???
解決したとは思えないけど
疲れたので、アプリ側を実装するまで、一旦これでよしとする。。。
参考サイト
GitHub:Websocket error using alternative server framework(2020-06-14)
PLEASE SLEEP:nginx の proxy_set_header の継承ではまった(2013-05-18)
-> 調査の過程でこんな記事も見つけたので、一応メモ。古い記事なので、今は仕様が変わっているかも
v-if の使い方(位置)
久しぶりにこのエラーに遭遇した。
エラー
TypeError: Cannot read properties of undefined (reading ‘toLowerCase’)
前回と文言が異なるのは、Nuxt の仕様変更かしらね?
原因
コメントアウトを繰り返し、箇所を特定したところ
~/components/Loader.vue
ここだった。
解決
とりあえず一個上のDOMにv-ifを移動して解決。
ハッカーになりたい!:Nuxt.jsの$route.pathは$nuxt.$route.pathを使え!(2018-09-04)
という記事を見かけたので
こうしたら、エラーが出なくなった。
言われてみれば、元のコードだと
template 直下に v-if が仕込まれているので
状況によっては、template 内が空になるコードとなっている。
これは Nuxt の仕様的に、確かアウトだったような。。。
そのせいか~ 🙄