Vue Routerを使ったサイトで404が発生

Vue Routerを使ったサイトで404が発生してしまった

Vue Routerを使ったサイトで、いきなり途中のURLにジャンプしたり、$router.push(‘/xxx’)した後の表示でF5(リロード)したりしたら、404になってしまった。
vue-cliで開発中は問題なかったのに、buildしてapacheに配備したら404になった。

Not Found
The requested URL /xxx was not found on this server.

Apache Server at www.yamacoco.com Port 80

解決方法

ちゃんと公式ドキュメントに書かれていた。

https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B

mod_rewriteで対応するなら

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

mod_dirが使えるのであれば

<IfModule mod_dir.c>
  FallbackResource /index.html
</IfModule>

まとめ

動かす前にドキュメントは読まなくてはいけない。

同じタグの記事
同じカテゴリの記事

jQueryで部分一致検索

jQueryで部分一致検索

誰かの作った難解なプログラムがある。サーバサイドは手がつけられない。
クライアントサイドはjqueryが利用されている。こちらはなんとかなりそう。

クリックイベントが設定されたelementがあり、その同レベルにinputタグがある。そのinputタグを辿りたい。

parent().find()

同レベルなので、親(Parent)を起点に検索(Find)する。

1
$(this).parent().find(xxx)

selector “input[name$=’.lastName’]”

同レベルにある下記の値を取得したい。

1
<input type="text" name="list[0].lastName" value="Doe" />
1
var lastName = $(this).parent().find("input[name$='.lastName']").val()

取得できた。
“$=”は後方一致として動作する。
ちなみに、前方一致は”^=”。
正規表現のようだ。
部分一致は”*=”。これは正規表現ではない。

まとめ

javascriptのみでプログラムを改修することができた。
jquery便利だ。

同じタグの記事
同じカテゴリの記事

jqueryのバージョンとprop()

jqueryのバージョンとprop()

古いシステムのメンテナンスを行った。
画面周りだけで対応できそうだったので、javascriptを修正した。

しかし、下記の処理でjavascriptエラーになった。

1
2
3
if ( $('#chkAgree').prop('checked') ) {
    ///
}

jquery.prop()

チェックボックスの状態を取得するのに、prop()で取得しようとしたが、
この部分がエラーになっていた。
jqueryのドキュメントページによると、prop()はjquery1.6から利用できるようだ。
現在利用しているjqueryのバージョンは?

jqueryのバージョン取得方法

1
alert($.fn.jquery);

1.4.3が返ってきた。どおりでエラーになるはずだ。

対処方法

jquery1.6以降ではやってはいけないが、1.4では下記のようにする。

1
2
3
if ( $('#chkAgree').attr('checked') ) {
    ///
}

注意

jquery1.6以降でもattr()は存在するが、htmlに書かれた属性を取得するためのメソッドとして存在する。
jquery1.6以降で画面に表示された情報などを動的に取得する場合はpropメソッドを利用する。

同じタグの記事
同じカテゴリの記事

html data-* 属性

html data-* 属性

今更だが、html5では任意のタグにdata-*属性を設定できる。
設定したdata属性は、簡単に取得することができる。

サンプルHTML

1
2
3
4
5
6
7
8
9
10
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>data attribute test</title>
  </head>
  <body>
    <span id="data1" data-my-test-data="hello world!">test data</span>
  </body>
</html>

サンプルスクリプト

data属性の値はdatasetを通じて取得することができる。

1
var myTestData = document.getElementById("data1").dataset.myTestData;

data属性の”data-“は取り除き、キャメルケースで指定すると取得できる。
しかし、この方法はChorme,Firefox,Edgeで成功したが、InternetExplorerでは、
ドキュメントモードがEdgeの場合にのみ動作した。
InternetExplorerがクライアントとして訪れるのであれば、datasetという新しい方法は用いずに、従来通りのgetAttributeを使う。

1
var myTestData = document.getElementById("data1").getAttribute("data-my-test-data");

name属性やclass属性を取得するのと同じく、ただ属性を取得しているだけなので、名称の変換などは行わずに指定する。

まとめ

data属性は便利だ。今まではキー情報などをtitle属性に設定してみたりしていたが、そうするとカーソルが当たった時など、その中身が見えてしまいデバッグはしやすいが、恥ずかしい場合もあった。
これで、いろいろ隠して設定できる。

同じタグの記事
同じカテゴリの記事

vue.jsでテンプレートが一瞬表示されてしまう

vue.jsでテンプレートが一瞬表示されてしまう

vue.jsを使って管理ツールや監視ツールを作っていたが、ページを開いたときに一瞬Mustacheテンプレートが表示されていた。
今までは特に気にしていなかったが、なんとなく気になってしまったら、気になって仕方がない。
これを抑制したい。

スタイルシートに、

1
2
3
[v-cloak] {
    display: none;
}

テンプレートを隠したいタグに、

1
2
3
<div v-cloak>
    {{ message }}
</div>

これで、

<div>が表示されなくなる。
ちなみに、これはVue.jsドキュメントのディレクティブのところに書かれていた。
もっと早く気がつけばよかった。
もう一度、ドキュメントを頭から眺めてみたい。

同じタグの記事
同じカテゴリの記事

jjs

jjsを使う

先日まで、java7サーバで作業していたため、jrunscriptを利用していたけれども、
これから使うサーバはjava8。なのでjjsを利用する。

jjsでは新たなメソッドが定義されている。
なお、下記のメソッドを利用するためには、jjsをscriptingモードで実行する必要がある。
scriptingモードで実行するためには、2つの方法がある。

jjsの引数に-scriptingを指定する。

下記の通りスクリプトを呼び出す。

1
$ jjs -scrpting my-script.js

スクリプトファイルの先頭にShebangを書く。

上記のmy-script.jsの先頭行にShebangを書く。

1
2
3
4
#!/usr/bin/env jjs

print('my script start!');
//

Shebangが書かれているスクリプトは、jjsの引数に-scriptingを指定しなくても、
自動的にscriptingモードで実行される。
Windowsでjjsを動かす場合も、特に気にせずShebangを書けば良い。
しかし、WindowsではShebangは利用されないので、1行目に#のみ書いておけば良い。

scriptingモードでの便利機能

  • ヒア・ドキュメント
  • グローバルオブジェクト
  • コマンド実行
  • readFully()

ヒア・ドキュメント

scriptingモードではヒアドキュメントを利用できる。
sqlを格納したいときなど便利。

1
2
3
4
5
6
var sql = <<"SQL";
SELECT
    *
FROM
    TAB
SQL

グローバルオブジェクト

$ARG配列を参照することで、スクリプトの引数を参照できる。
なお、argumentsからでも同様に取得することができる。

$ENVオブジェクトを利用することで、環境変数を取得することができる。

1
2
print($ENV.ORACLE_HOME);
print($ENV['ORACLE_HOME']);

コマンド実行

$EXEC(‘ls -l’)を利用することで、ls -lを実行できる。
なお、出力される標準出力は$OUTに入っている。戻り値にも標準出力に入っている。エラー出力は$ERRに入る。
終了コードは$EXITに入る。
なお、コマンド呼び出しに失敗すると例外が飛ぶ。
コマンドを呼び出し、$EXITや$OUTを解析することで、ジョブ実行判定などができる。

readFully()

テキストファイルを読み込んで、変数に収めることができる。

1
2
var text = readFully('my-data.txt');
print(text);

テキスト読み込みが簡単にできる。当然、java.ioやjava.nioを利用して読み込んでも良い。

java8からnashornなので

java7のRhinoでは、Listをfor eachしても、Listオブジェクトのメソッドが取得できるだけだった。
java8のNashornでは、Listの中身でeachする。

1
2
3
4
5
6
7
8
9
10
11
var list = new java.util.ArrayList();
list.add('apple');
list.add('banana');
for (var i in list) {
    print(list[i]);
}
// listの中身が欲しいとき
var ite = list.iterator();
while (ite.hasNext()) {
    print(ite.next());
};

上記のスクリプトをjava7のjrunscriptで実行すると、forループではArrayListのメソッドリストが出力され、whileループでapple,bananaが出力される。
java8のjjs(jrunscript)では、forループもwhileループもapple,bananaが出力される。

無駄にイテレーターを作らなくても良いので、本来の実装のみに力を注ぐ事ができる。

注意

Nashornになり、importPackage()とimportClass()が廃止されている。
今後は、Java.type()を利用することになる。

1
2
3
4
var ArrayList = Java.type('java.util.ArrayList');
var list = new ArrayList();
list.add('Apple');
list.add('Banana');

JavaImporterは従来通り利用できる。
どうしてもimportPackage()、importClass()を利用したい場合は、組み込み互換性スクリプトをロードする。

1
2
3
4
5
load('nashorn:mozilla_compat.js');
importClass(java.util.ArrayList);
var list = new ArrayList();
list.add('Apple');
list.add('Banana');
同じタグの記事
同じカテゴリの記事

jrunscript

jrunscript

今更ながらjavaの組み込みjavascriptを試す。

javaのクラス(パッケージは)簡単に呼び出せる。

java標準のクラスは、特に気にすること無く、普通に呼び出せる。

1
2
java.lang.System.out.println('test message');
java.swing.JOptionPane.showMessageDialog(null, 'Test Message');

Java標準以外のクラスは、Packagesから始めて呼び出す必要がある。

1
2
var log = Packages.org.apache.commons.logging.LogFactory.getLog('my-script.js');
log.info('message');

上の例では、commons-loggingを利用しているので、jrunscript引数の-cpまたは-classpathで、commons-logging.jarとロガーを指定する必要がある。
クラスパスの指定で、jarを*でディレクトリごと指定することはできない。個別に.jarを羅列する。

Java標準クラスをPackagesから辿ることもできる。

1
2
java.lang.String.format('Test. %04.3f', 12.3);
Packages.java.lang.String.format('Test. %04.0f', 13);

なお、Javaでは何もしなくてもインポートされているjava.langは、jrunscriptではインポートされていない。
Object,Boolean,Stringなどがjavascriptとjavaで当たってしまうためらしい。

jrunscriptでもimportを行えば、クラス名だけでクラスを指定することができる。

1
2
importClass(java.util.ArrayList);
importPackage(javax.swing);

クラス毎のimportと、パッケージ単位のimportができる。
このimport方法だとスクリプト内のすべてで有効になってしまうため、不都合があるかもしれない。
そんなときは、JavaImporterを利用することで、狭い範囲のインポート宣言を行える。

1
2
3
4
5
6
7
var mylib = new JavaImporter(
    java.lang,
    javax.swing
);
with (mylib) {
    JOptionPane.showMessageDialog(null, String.format('Test. %s', 'NN'));
}

度々、String.formatのサンプルで書いているが、javascriptの数値はjavaのDoubleとして変換される。
したがって、String.formatでjavascriptの数値を変換するときはfを利用する。

jrunscriptでは、外部のjavascriptファイルを簡単に呼び出すことができる。

1
load('myCommon.js');

面倒な処理があるばあいは、共通処理として出しておければ良いと思う。
内部処理的には、ファイルを開いてevalしているらしい。

注意すべきところ

javaのメソッドを呼び出して返ってきたStringはあくまでもjava.lang.String。
したがって、javascriptの文字列との比較でアンマッチになることがある。
if (a == b) は、問題なく比較できる。
Arrayにpushし、indexOfで存在確認すると、アンマッチになった。

まとめ

結構、普通に使えた。
ただ、Java7に付属するRhinoでは、javaのリストのイテレートがが面倒。
Java8からのNashornになると、イテレートがfor inでできるようになるので使い易いと思う。

Javaクラスを呼び出せばなんでもできてしまうが、javascriptそのものが非力なため、ファイルの一覧を処理するような場合は、jythonを使ったほうがずっと手軽にできた。

ただ、まったく新しい言語を覚えなくても、公用語とも言えるjavascriptでjavaのAPIを自由に使えるのはとても良いと思った。

同じタグの記事
同じカテゴリの記事

Template Engine Mustache を使う

Template Engine Mustache を使う

mustacheはテンプレートエンジン。
様々な言語で使えるように準備されている。
JavaScript,Python,PHP,Perl,Java…
私が普段利用する言語では一通り利用できる。

なので、一通り利用してみようと考えた。
しかし、実際に使ってみると、言語によっては準備が面倒だったりした。

ネットワークが自由に使える環境であれば、どの言語でも簡単にセットアップできるが、
ネットワークが限られている職場の環境では、モジュール一つコピーして利用するということはできなかった。
上記の一覧の中で、唯一できたのはJavaScript。

mustache.jsを使う

とりあえず、下記のサンプルコードを。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE>
<html>

<head>
    <meta charset="utf-8">
    <title>mustache test</title>
</head>

<body>
    <div id="target">Loading...</div>
    <script id="template" type="x-tmpl-mustache">
        * Hello {{name}}!<br>
        # 2 * 3 = {{calc}}<br>
        {{#mapList}}
            * {{firstName}} {{lastName}}<br>
        {{/mapList}}
        {{#simpleList}}
            - {{.}}<br>
        {{/simpleList}}
    </script>

    <script src="mustache.js"></script>
    <script>
        window.setTimeout(function() {
            var template = document.getElementById('template').innerHTML;
            var data = {
                name: "Luke",
                calc: function() {
                    return 2 * 3;
                },
                simpleList: [
                    "one","two","three"
                ],
                mapList: [
                    {firstName: "fname", lastName: "lname"},
                    {firstName: "fname2", lastName: "lname2"}
                ]
            };
            var rendered = Mustache.render(template, data);
            document.getElementById('target').innerHTML = rendered;
        }, 1500);
    </script>
</body>

</html>

テンプレートとデータを準備し、下記の処理でテンプレートを展開する。

1
var rendared = Mustache.render(template, date);

簡単に利用できた。

他の言語でも、環境さえ整えることができれば同じように使えるので、
覚えておいてもいいかもしれない。

同じタグの記事
同じカテゴリの記事

javascriptの配列操作

javascriptの配列操作

javascriptの配列操作は、すぐ忘れる。

準備

1
var arr = [];

追加

1
2
arr.push('a');
arr.push('b');

arr は [‘a’, ‘b’] になる。pushは末尾に追加される。
先頭に追加するには

1
2
arr.unshift('x');
arr.unshift('y');

arr は [‘y’, ‘x’, ‘a’, ‘b’] になる。
unshiftの命名はperlからだろうか。

配列数の取得

1
var l = arr.length;

l は 4になる。

除去

1
2
var i = arr.pop();
var j = arr.pop();

arr は [‘y’, ‘x’] になる。
i は ‘b’、j は ‘a’ になる。
末尾から除去されてている。スタックとして使う時に便利。

先頭から取得する場合、キューとして使う場合は、

1
2
var m = arr.shift();
var n = arr.shift();

arr は [] になる。
m は ‘y’、n は ‘x’になる。

同じタグの記事
同じカテゴリの記事