2011-06-15
■[JavaScript][node.js]expressでpostでundefined
console.logでpostしたデータを確認しようとすると、
undefinedとなってしまうのがなかなか解決しなかった。
にわか知識ではつらい。。。
環境:
Mac OS X 10.6.7
node.js 0.4.8
express 2.3.7
とりあえず、このあたりを参考に:
node.js+expressでPOSTパラメーターを取得する方法 ::ハブろぐ
HideYukiSaito.com: The Leading Hide Yuki Saito Site on the Net
html(index.htmlという名前で)のform部分はこんな感じ:
<form action="/" method="post"> <input type="text" name="user[name]" /> <input type="submit" value="送信" /> </form>
で、server.jsというファイルを用意して(元ネタは前の記事を参照)、
postの部分は以下のような感じ:
app.use(express.bodyParser()); app.post('/', function(req, res){ console.log(req.body); res.redirect('back'); });
res.redirect('back');
がないと、ブラウザでレスポンスが返ってこなかった。。。
$ node server.js
(以下が表示、されるようにconsole.logを書いておく。)
Server running at http://127.0.0.1:8124/
ブラウザで、
undefined
と表示される。
ググッてみると、
bodyParserがないから、というのがヒットするけど、あるんだけどね。。。
で、
HideYukiSaito.com: The Leading Hide Yuki Saito Site on the Net
を見直して、
bodyParser()をconfigureで指定したところ、postした中身が表示された。
修正したserver.jsは以下。
// モジュールの読み込み var express = require('express'); // サーバーを作成 var app = express.createServer(); // configure app.configure(function() { app.use(express.bodyParser()); }); // '/'のリクエストハンドラ app.get('/', function(req, res) { res.sendfile('index.html'); }); // post app.post('/', function(req, res) { console.log(req.body); res.redirect('back'); }); // サーバーを起動 app.listen(8124, '127.0.0.1'); console.log('Server running at http://127.0.0.1:8124/');
で、「おれ」とか入力してpostすると、
ターミナルに以下のように表示された。
{ user: { name: 'おれ' } }
2011-05-26
■[JavaScript][node.js]express使おうとしら、Error: Cannot find module 'express'
それほど悩まなくてもいいのかもしれないけど、
慣れてないので書いておく。
Macだけど。
node.jsの設置は以下を参考に:
エラーにたどり着くまでの手順をざっと。
1. ターミナルを起動。
2. 一般ユーザーのホームディレクトリ下に設置するので、
$ mkdir nodejs
$ cd nodejs
3. naveをインストール。
$ git clone http://github.com/isaacs/nave.git
~/nodejs/nave
が作成される。
naveを使うと、node.jsの更新、バージョンの切り替えが楽、とか。
$ cd nave
$ ./nave.sh install latest
結構時間がかかった。
5. node.jsを使えるようにする。
$ ./nave.sh use latest
6. バージョンを確認。
$ node -v
v0.4.7
と表示された。
7. 続けて、npmをインストール。
$ curl http://npmjs.org/install.sh | sh
途中で、
Is this OK? enter 'yes' or 'no'
と問われるので、「yes」と入力。
8. サーバー用のディレクトリを作って、example.jsを設置する。
$ cd ~
$ mkdir node_server
$ cd node_server
「node_server」ディレクトリ内にexample.jsを設置。
example.jsの中身は上の参考サイトを参照:
9. example.jsを動かしてみる。
$ node example.js
パスが通ってないので動きません。
(node command not found)
10. .bash_profileにパスを記述して、node.jsのパスを通す。
$ cd ~
vi .bash_profile
以下を記述。
# node.js
NODE_PATH=~/.nave/installed/0.4.7/bin
export NODE_PATH
node.jsの本体の位置を、
「NODE_PATH=」以下に記述。
参考:
11. パスの記述を有効化。
$ source .bash_profile
12. 再度、example.jsを動かす。
$ cd ~/node_server
$ node example.js
ブラウザで、
にアクセスしてみると、
Hello, World
と表示された。
続いてexample2.jsもやってみてうまくいった(詳細は割愛)。
13. 続いてserver.jsをやってみるので、expressをインストール。
$ cd ~/nodejs/nave
$ npm install experss
以下が表示された。
mime@1.2.2 ./node_modules/express/node_modules/mime
connect@1.4.1 ./node_modules/express/node_modules/connect
qs@0.1.0 ./node_modules/express/node_modules/qs
express@2.3.7 ./node_modules/express
14. server.jsを実行してみる。
$ cd ~/node_server
$ node server.js
で、タイトルのエラーにたどりつく。
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Cannot find module 'express'
at Function._resolveFilename (module.js:320:11)
at Function._load (module.js:266:25)
at require (module.js:348:19)
at Object.<anonymous> (/Users/(ユーザー名)/node_server/server.js:2:15)
at Module._compile (module.js:404:26)
at Object..js (module.js:410:10)
at Module.load (module.js:336:31)
at Function._load (module.js:297:12)
at Array.<anonymous> (module.js:423:10)
at EventEmitter._tickCallback (node.js:126:26)
expressがどこにあるかわかんねーよ、
と言われてるんで、
どこにあるか教えてあげないと動いてくれない。
ここで疑問に思ったのが、
- expressはどこに入ってるのか?
- node.jsはどこにあるものを見つけてくれるのか?
というあたり。
2点目については、
$ node -e require.paths
で確認できる。
参考:
1点目については、
expressのインストール時に、
express@2.3.7 ./node_modules/express
と出たのを頭の片隅に置いておく。
手順10の、node.js本体の位置を環境設定のところであっさり通り過ぎましたが、
ホームディレクトリ直下には、いつの間にやら、
.nave
.npm
というディレクトリができていた。
node.jsは.naveの下だったので、
.npmの下をさがすと、
~/.npm/express/2.3.7/package/bin
にexpressがあったので、これを.bash_profileに指定してみたけど動かず。
で、2点目の、
$ node -e require.paths
をやってみると、
[ '/Users/(ユーザー名)/.nave/installed/0.4.7/bin',
'/Users/(ユーザー名)/.node_modules',
'/Users/(ユーザー名)/.node_libraries']
と表示。
1行目は、手順10で追加したもの。
2行目、3行目は実在していない。
expressの位置はわからんよね、というのがよくわかった。
ディレクトリ構成とか、コマンドの実行位置とか、よくわからず...。
いろいろと調べて、node.jsのマニュアルのモジュールの最後のところをよく読む。
「Addenda: Package Manager Tips」のところ。
で、また探してみると、
~/nodejs/nave/node_module
にexpressがあったので、
.bash_profileを以下のように編集。
# node.js
NODE_PATH=~/.nave/installed/0.4.7/bin
#express
NODE_PATH=$NODE_PATH:~/nodejs/nave/node_modules
export NODE_PATH
有効化。
$ source .bash_export
で、server.jsがやっと動いた。
そしてその後、node.jsを0.4.8に更新し、
$ node -e require.paths
をやってみると、
[ '/Users/(ユーザー名)/.nave/installed/0.4.8/lib/node',
'/Users/(ユーザー名)/.node_modules',
'/Users/(ユーザー名)/.node_libraries',
'/Users/(ユーザー名)/.nave/installed/0.4.8/lib/node' ]
と出た。うーん。
.bash_profileの中身が書き換えられたわけではないので、
$ source .bash_profile
$ node -e require.paths
で、
[ '/Users/(ユーザー名)/.nave/installed/0.4.7/bin',
'/Users/(ユーザー名)/nodejs/nave/node_modules',
'/Users/(ユーザー名)/.node_modules',
'/Users/(ユーザー名)/.node_libraries',
'/Users/(ユーザー名)/.nave/installed/0.4.8/lib/node' ]
となった。
~/.node_modules
を作って、そこにnpmでモジュールがインストールされるようにしとけばよさげなんだけど、
とりあえずディレクトリは作っておく。
ディレクトリがあれば、その場所にモジュールをインストールしてくれる、
とかだといいけど。。。
あとでほかのモジュールをいれるので、そのときにまた確認。
追記
id:koichikさんのコメントを参考に、mongooseをローカルインストールしてみようとする、
が、またいろいろと壁が。。。
15. nodeのパスをもう1度。
まず、
$ cd ~/nodejs/nave
$ npm install mongoose
で、
bash: npm: command not found
となる。
この時点で、node.jsを0.4.8にしたので、
npmはバージョンごとにインストールしなければいかのか、
と思った、のはただの勘。
npmを再インストールしようと、
$ cd ~/nodejs/nave/
$ curl http://npmjs.org/install.sh | sh
(以下が表示)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 101 3874 101 3874 0 0 4893 0 --:--:-- --:--:-- --:--:-- 1101 3874 101 3874 0 0 4892 0 --:--:-- --:--:-- --:--:-- 11164
npm cannot be installed without nodejs.
Install node first, and then try again.
Maybe node is installed, but not in the PATH?
Note that running as sudo can change envs.
PATH=(云云...)
nodeコマンドが認識されないし。。。
「PATH=」の部分に0.4.8のパスはなし。
で、また、.bash_profileを編集。
NODE_PATHではなくて、PATHで指定。
PATH=$PATH:~/.nave/installed/0.4.8/bin
export PATH
で、動くようになった。
16. 「node_server」ディレクトリ以下に、「node_modules」ディレクトリ作成。
$ cd ~/node_server
$ mkdir node_modules
17. npmをnode.js 0.4.8用にインストール。
npmのインストール先は、
~/.nave/installed/0.4.7/lib/node_modules
だった。。。
参考:
(Ubuntu で) Node.js 開発環境構築手順 - pekodeco のじんどぅ?
今回はホームディレクトリ直下で。
$ cd ~
$ curl http://npmjs.org/install.sh | sh
あとは手順7と同じ。
18. mongooseをインストール。
$ cd ~/node_server
$ npm install mongoose
(以下が表示)
mongoose@1.3.7 ./node_modules/mongoose
└── hooks@0.1.6
↓
~/node_server/node_modules/
に「mongoose」ディレクトリが作成された。
2009-11-11
■[JavaScript]fieldset要素はelements配列で取得される
入力フォームが設置された古いWebページの改修をやっていて引っかかる。
元のHTMLでは、form要素内に、inputやtextareaなどの操作する要素しか設置されていなくて、
それらをJavaScriptで以下のように取得していた。
for(var i = 0; i < form.elements.length; i++) { form.elements[i]....(do something) }
で、このHTMLはtableレイアウトで組まれていたので、
XHTML+CSSで組み直したときに、
fieldset要素とかを使ってがんばってマークアップしたんだけど、
同じJavaScriptを適用したところ、ループのところでエラーが出るようになった。
例えば、こんな感じのHTML:
<form method="post" name="form1" action="#"> <fieldset> <legend>フォームテスト</legend> <label for="input01">input01</label><input type="text" name="input01" /> <input type="checkbox" name="check01" /><label for="check01">check01</label> </fieldset> <input type="submit" name="btn_submit" value="submit" /> </form>
該当箇所はtype属性を取得していたところで、
form.elements[i].type is undefined
などと、Firebugで表示される。
alert(form.elements[i].type);
とすると、
undefined
text
checkbox
submit
と出てくる。
alert(form.elements[i]);
とすると、
object HTMLFieldSetElement
object HTMLInputElement
object HTMLInputElement
object HTMLInputElement
と出てくる。
というわけで、
fieldset要素は、elements配列で取得される、ということが確認できた。
legend要素は取得されていない。
fieldset要素にtype属性は指定していないから、
undefined
になる。
fieldset要素についてはこちらを参照:
type属性はない。
ここで、
alert(form.elements[i].getAttribute("type"));
としてみると、
null
text
checkbox
submit
となる。
なので、
for(var i = 0; i < form.elements.length; i++) { if(form.elements[i].getAttribute("type") != null){ if(form.elements[i].getAttribute("type") == text) { (do something) } } }
という感じで条件をつけると、とりあえずエラーは回避できる。
2009-10-27
■[JavaScript]window.open()でnameを指定する場合の注意事項
こちらを参照:
window.nameは何?ってとこなんだけど、
framesetにつけられたname属性を参照したりするらしい。
window.open()の第2引数に名前を指定をすると、
新しく開いたウィンドウ(windowオブジェクト)に対して名前をつけられる。
で、クリックイベントが発生すると同じ関数を呼び出す複数の要素(ボタンなど)があったとき、
最初のクリックで新しいwindowオブジェクトが作られ、
2回目以降は、最初に開いたウィンドウの中身が置き換えられる。
というわけで、元のウィンドウとは別のウィンドウにしたいけど、
毎回ウィンドウを開くのはやだ、という場合に第2引数を指定すると、
意図通りの動作にできる。
で、この第2引数を指定するときに注意しなければならないのが、最初の引用。
半角英数以外のものが含まれていると、
クリックイベント発生時に、IEのステータスバーにエラーが出るんだけど、とりあえずウィンドウは開く。
だけど、毎回新しいウィンドウが開いてしまう。
今回引っかかったのは、半角スペースだった。
name属性だと思うと、半角スペースは使わないようにするという意識があるが、
制限は半角英数なので、アンダーバーもだめ。
アンダーバーは使いたくなってしまうから注意が必要。
この現象を確認したIEのバージョンは、6と8。
2009-10-01
■[JavaScript][DOM]nextSiblingは何を取得するか
自分で確認しないと身に染みないので。
以下のようなHTMLを作成。
<table> <tbody> <tr> <th>見出し1</th> <td id="data1_1">data1_1</td> <td id="data1_2">data1_2</td> </tr> <tr> <th>見出し2</th> <td id="data2_1">data2_1</td><td>data2_2</td> </tr> </tbody> </table> <div id="div_idtest"> <p id="p_1"> これは、(ここで改行) <abbr id="abbr1_1">ここはabbr要素(ここで改行)</abbr> <span id="span1_1">ここはspan要素(ここで改行)</span> です。(ここで改行) </p> <p id="p_2"> これは、(ここで改行) <abbr id="abbr2_1">ここはabbr要素(改行なし)</abbr><span id="span2_1">ここはspan要素(ここで改行)</span> です。(ここで改行) </p> <p id="p_3">3つ目のpタグ(改行なし)</p><p id="p_4">4つ目のpタグ</p> </div>
<td id="data1_1">のnextSiblingを確認(table要素:改行ありの場合)
ノードタイプを確認してみる。
HTML:
<td id="data1_1">data1_1</td> <td id="data1_2">data1_2</td>
var data1_1 = document.getElementById("data1_1"); alert(data1_1.nextSibling.nodeType);
各ブラウザごとの結果:
- Internet Explorer 6:1
- Internet Explorer 8:1
- Firefox 3.5:3
- Safari 4:3
ノードタイプ1は、要素ノード、
ノードタイプ3は、テキストノード。
ノードバリューを取得してみると、
var data1_1 = document.getElementById("data1_1"); alert(data1_1.nextSibling.nodeValue);
各ブラウザごとの結果:
- Internet Explorer 6:null
- Internet Explorer 8:null
- Firefox 3.5:(空)
- Safari 4:(空)
ノードネームを取得してみると、
var data1_1 = document.getElementById("data1_1"); alert(data1_1.nextSibling.nodeName);
各ブラウザごとの結果:
- Internet Explorer 6:TD
- Internet Explorer 8:TD
- Firefox 3.5:#text
- Safari 4:#text
IEは要素ノード(<td id="data1_2">)を参照しているので、
nodeValueを取得しようとするとnullが返ってくる。
FirefoxとSafariでは、</td>のあとの改行が取得されるので、alertに何も表示されない。
<td id="data2_1">のnextSiblingを確認(table要素:改行なしの場合)
ノードタイプを確認してみる。
HTML:
<td id="data2_1">data2_1</td><td>data2_2</td>
var data2_1 = document.getElementById("data2_1"); alert(data2_1.nextSibling.nodeType);
各ブラウザごとの結果:
- Internet Explorer 6:1
- Internet Explorer 8:1
- Firefox 3.5:1
- Safari 4:1
この場合、2つのtd要素が改行なしで記述されているので、
すべてのブラウザで、2つ目のtd要素が取得されている。
<p id="p_1">のnextSiblingを確認(ブロック要素:改行ありの場合)
ノードタイプを確認してみる。
HTML:
<p id="p_1"> これは、(ここで改行) <abbr id="span1_1">ここはabbr要素(ここで改行)</abbr> <span id="abbr1_1">ここはspan要素(ここで改行)</span> です。(ここで改行) </p> <p id="p_2"> これは、(ここで改行) <abbr id="abbr2_1">ここはabbr要素(改行なし)</abbr><span id="span-2_1">ここはspan要素(ここで改行)</span> です。(ここで改行) </p>
var p_1 = document.getElementById("p_1"); alert(p_1.nextSibling.nodeType);
各ブラウザごとの結果:
- Internet Explorer 6:1
- Internet Explorer 8:1
- Firefox 3.5:3
- Safari 4:3
ノードバリューを取得してみると、
var p_1 = document.getElementById("p_1"); alert(p_1.nextSibling.nodeValue);
各ブラウザごとの結果:
- Internet Explorer 6:null
- Internet Explorer 8:null
- Firefox 3.5:(空)
- Safari 4:(空)
IEは要素ノード(<p id="p_2">)を参照しているので、
nodeValueを取得しようとするとnullが返ってくる。
FirefoxとSafariでは、</p>のあとの改行が取得されるので、alertに何も表示されない。
<p id="p_3">のnextSiblingを確認(ブロック要素:改行なしの場合)
ノードタイプを確認してみる。
HTML:
<p id="p_3">3つ目のpタグ(改行なし)</p><p id="p_4">4つ目のpタグ</p>
var p_3 = document.getElementById("p_3"); alert(p_3.nextSibling.nodeType);
各ブラウザごとの結果:
- Internet Explorer 6:1
- Internet Explorer 8:1
- Firefox 3.5:1
- Safari 4:1
id属性を確認してみる。
var p_3 = document.getElementById("p_3"); alert(p_3.nextSibling.getAttribute("id"));
各ブラウザごとの結果:
- Internet Explorer 6:p_4
- Internet Explorer 8:p_4
- Firefox 3.5:p_4
- Safari 4:p_4
この場合、2つのp要素が改行なしで記述されているので、
すべてのブラウザで、2つ目のp要素が取得されている。
<abbr id="abbr1_1">のnextSiblingを確認(インライン要素:改行ありの場合)
ノードタイプを確認してみる。
HTML:
<abbr id="abbr1_1">ここはabbr要素(ここで改行)</abbr> <span id="span1_1">ここはspan要素(ここで改行)</span>
var abbr1_1 = document.getElementById("abbr1_1"); alert(abbr1_1.nextSibling.nodeType);
各ブラウザごとの結果:
- Internet Explorer 6:3
- Internet Explorer 8:3
- Firefox 3.5:3
- Safari 4:3
ノードバリューを確認してみる。
var abbr1_1 = document.getElementById("abbr1_1"); alert(abbr1_1.nextSibling.nodeValue);
各ブラウザごとの結果:
- Internet Explorer 6:ここはabbr要素(ここで改行)
- Internet Explorer 8:(空)
- Firefox 3.5:(空)
- Safari 4:(空)
IE6はabbr要素をサポートしていない。
IE Developper Toolbarで確認すると、
「ここはabbr要素(ここで改行)」の部分は、
abbr要素の子要素ではなく、兄弟要素として扱われている。
下記のようにspanとabbrを入れ替えて、span要素のnextSiblingを確認してみる。
HTML:
<span id="span1_2">ここはspan要素(ここで改行)</span> <abbr id="abbr1_2">ここはabbr要素(ここで改行)</abbr>
ノードタイプ:
var span1_2 = document.getElementById("span1_2"); alert(span1_2.nextSibling.nodeType);
- Internet Explorer 6:3
- Internet Explorer 8:3
- Firefox 3.5:3
- Safari 4:3
ノードバリュー:
var span1_2 = document.getElementById("span1_2"); alert(span1_2.nextSibling.nodeValue);
- Internet Explorer 6:(空)
- Internet Explorer 8:(空)
- Firefox 3.5:(空)
- Safari 4:(空)
さらにspan要素の後にテキストを追加してみる。
HTML:
<span id="span1_2">ここはspan要素</span>ここにてきすと(ここで改行) <abbr id="abbr1_2">ここはabbr要素(ここで改行)</abbr>
ノードバリュー:
var span1_2 = document.getElementById("span1_2"); alert(span1_2.nextSibling.nodeValue);
- Internet Explorer 6:ここにてきすと(ここで改行)
- Internet Explorer 8:ここにてきすと(ここで改行)
- Firefox 3.5:ここにてきすと(ここで改行)
- Safari 4:ここにてきすと(ここで改行)
まあ、ブロック要素内なので、改行だろうとテキストだろうとテキストノードはテキストノードであると。
<abbr id="abbr2_1">のnextSiblingを確認(インライン要素:改行なしの場合)
ノードタイプを確認してみる。
HTML:
<abbr id="abbr2_1">ここはabbr要素(改行なし)</abbr><span id="span2_1">ここはspan要素(ここで改行)</span>
var abbr2_1 = document.getElementById("abbr2_1"); alert(abbr2_1.nextSibling.nodeType);
各ブラウザごとの結果:
- Internet Explorer 6:3
- Internet Explorer 8:1
- Firefox 3.5:1
- Safari 4:1
ノードバリューを確認してみる。
var abbr2_1 = document.getElementById("abbr2_1"); alert(abbr2_1.nextSibling.nodeValue);
各ブラウザごとの結果:
- Internet Explorer 6:ここはabbr要素(改行なし)
- Internet Explorer 8:null
- Firefox 3.5:null
- Safari 4:null
abbr要素とspan要素を入れ替えてみる。
HTML:
<span id="span2_2">ここはabbr要素(改行なし)</span><abbr id="abbr2_2">ここはspan要素(ここで改行)</abbr>
ノードタイプ:
var span2_2 = document.getElementById("span2_2"); alert(span2_2.nextSibling.nodeType);
各ブラウザごとの結果:
- Internet Explorer 6:1
- Internet Explorer 8:1
- Firefox 3.5:1
- Safari 4:1
ノードネーム:
var span2_2 = document.getElementById("span2_2"); alert(span2_2.nextSibling.nodeName);
各ブラウザごとの結果:
- Internet Explorer 6:ABBR
- Internet Explorer 8:ABBR
- Firefox 3.5:ABBR
- Safari 4:ABBR
まとめ
やってみると大したことではないような気もするけど、IE6のおかげで結構混乱してたな。
とりあえず、以下の3点。
- HTML内のブロック要素間、table要素間の改行について、IEは無視、そのほかはノードと解釈。
- インライン要素間の改行について、各ブラウザとも改行をノード(普通にテキストノード)と解釈。
- IE6ではサポートしていない要素を使うときは注意する。
3点目については、nextSibling以外についても注意する。
対応については、とりあえずその都度検討。









