Google Maps API サービス変更「Google Maps Platform」(移行期間:2018年 6/11 – 7/16)

この期間中に旧サービスの「Google Maps APIs Standard Plan / Premium Plan」にてAPIキーを使用していない場合、7/17以降には、エラー画面となりGoogle Mapsが表示されなくなる。
※ただし、iframeによる埋め込みについてはAPIキーがなくても利用可能(一般公開されているページに限る)

APIキーは2016年6/22より必須となったが、6/22以前からGoogle Masp APIを利用しているドメインの場合は、コンソールでの警告にとどまっていた。
今回のサービス変更によって2018年の6/11からはAPIキーの使用が強制となり、
移行期間後の7/17以降にはエラー画面となる。

また旧サービスの「Google Maps APIs Standard Plan / Premium Plan」を使用していたとしても、利用規約や価格が変更されているため注意が必要(リクエスト数の大幅な減少など)。

  • Google Maps Platform:月間28,000リクエスト(1日平均933リクエスト)
  • Google Maps APIs Standard Plan:1日25,000リクエスト

利用料の確認・無料枠を超えないように制限をかける方法:
https://www.marie-web.design/blog/google-maps-platform/

参考:
https://internet.watch.impress.co.jp/docs/special/1124760.html
https://ring-and-link.co.jp/dream2000/user/notice/web/2479
https://qiita.com/umeume66/items/823c8188d895f89e42be

JavaScriptクォーテーションの個人的な見解

JavaScriptのクォーテーションはPHPなどと同じく「”(ダブルクォーテーション)」と「’(シングルクォーテーション)」があるが、JavaScriptに両者の違いはない(変数展開を行わない)。

そのため、人によって記述がバラバラになりがちだが、個人的には「’(シングルクォーテーション)」を使うべきだと感じている。

なぜなら、JavaScriptはHTMLの中でも利用されるため、HTMLで一般的に利用される「”(ダブルクォーテーション)」中に記述してもエスケープせずにそのまま使えるからである。

だから、JavaScriptでは「’(シングルクォーテーション)」を使ったほうが望ましいと思われる。

fsとfs-extraモジュールの違い

Node.jsのfsモジュールは、ファイルシステムに関するモジュールである。
fs.writeFile()fs.writeFileSync()は存在しないディレクトリのデータに書き込むことができないので、fs-extraモジュールを使って、fsExtra.outputFile()fsExtra.outputFileSync()で利用することがほとんどになる。

またNode.jsの原則だが、fs.writeFileSync()fsExtra.outputFileSync()は同期処理となるので利用すべきではなく、非同期のfs.writeFile()fsExtra.createWriteStream()fsExtra.outputFile()を利用するべきである。

Node.jsのCLIツール開発時のリンクの貼り方・外し方

自分でNode.jsのCLIツールを使うときは、npmを使って明示的にリンクを貼る。

package.jsonに下記のようなbinの記述があるかどうかを確認。

{
  "bin": {
    "iconfont-gen": "./bin/iconfont-gen"
  }
}

その後、下記のコマンドを実行し、リンクを貼る。

$ npm link

外すときは、下記のようにunlinkを実行する。

$ npm unlink -g iconfont-gen

テンプレートリテラル

ES6から利用できるようになったテンプレートリテラルは、単純にバッククォートで囲むだけ。

いままで制御文字を入れて改行していたところを、そのままの改行で表現できる(いままで通り制御文字を使っても大丈夫)。

let test1 = "Hello \n World!";
let test2 = `Hello
World!`;
conosle.log(test1 === test2); // true

また「${〜}」の記法を使うことで、変数や計算式を入れることも可能。

let hoge = 'World';
let test = `Hello ${hoge}!`;
console.log(test); // Hello World!

JavaScriptの型の復習

JavaScriptのプリミティブ型は下記の5つのみ。
それ以外の配列や関数などは全てobjectとなる。

  • boolean
  • number
  • string
  • undefined
  • null

よく同一視されるundefinedとnullの違いとしては、

  • undefinedは未定義の状態、つまり何も設定されていない状態
  • nullは何もない状態

であり、undefinedは変数宣言を行って値を入れていない状態でセットされるが、nullは意図的に設定しなければ、その値を示さない。
またES5以前の環境ではundefinedはグローバルオブジェクトで値を書き換えることができたため、void 0などの記法を用いて確実にundefinedを指すようにすることが多かったが、モダンブラウザでは単純な同値比較でOK。
typeof演算子を使った場合には、他のプリミティブ型と同じく、undefinedはundefinedを指すが、nullはobjectを指す(ちなみにobjectの中で関数のみfunctionを指す)。

入門書でtypeof演算子と一緒に紹介されるinstanceof演算子は、オブジェクトのプロトタイプチェーンを辿って、指定されたコンストラクタがあるかどうかを調べるもので、つまり全てのオブジェクトはObjectとの比較がtrueになる。
またそのオブジェクトのコンストラクタの名前を取得するには、コンストラクタで生成された全てのオブジェクトが持つ、object.constractorプロパティを参照すればいい。

nodebrewでNode.jsのバージョン管理

HomebrewのNode.jsをアンインストール

$ brew uninstall node

nodebrewをHomebrewでインストール

$ brew install nodebrew

nodebrewの初期設定

インストールしたときにメッセージが表示されるので、それに合わせて設定

$ /usr/local/opt/nodebrew/bin/nodebrew setup

「Export a path to nodebrew:」で示されたパスを「~/.bashrc」に追記

export PATH=/usr/local/var/nodebrew/current/bin:$PATH

「~/.bashrc」の読み込み

$ source ~/.bashrc

パスが通っているかを確認

$ nodebrew -v

Node.jsの最新版をバイナリでインストール(バイナリじゃないと時間がかかる)

$ nodebrew install-binary latest (安定板の場合はstable)

インストールできるバージョンは下記のコマンドで確認

$ nodebrew ls-remote

現在インストールされているものを確認

$ nodebrew ls

インストールされたものでどのバージョンを使うかを指定

$ nodebrew use v10.0.0

Node.jsのバージョン確認

$ node -v

※下記のようにエラー発生した場合

-bash: node: command not found

「~/.bashrc」はパスは書き込まれている場合には読み込まれていない。
そのため自動で読み込まれる「.bash_profile」の方に、「~/.bashrc」を自動で読み込ませる下記の設定を記述。

if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi

ブラウザで求められるクロスサイトのアクセス制限

JavaScriptでドメインを超えたデータのやりとりを行う場合のブラウザに求められるクロスサイトのアクセス制限の種類

FORM 制限なし(制限する場合はCSRF対策が必要)
SCRIPT 制限なし(JSONPへの応用が可能)
IMG インライン表示はできるが、SCRIPTから画像の中身は読めない
CSS レンダリングできるがSCRIPTから中身は読めない
IFRAME クロスサイトのDOM操作を禁止
XMLHttpRequest クロスサイトのリクエストを発行できない
XMLHttpRequest Level 2 クロスサイトのリクエストを条件付きで許可

http://labs.cybozu.co.jp/blog/kazuho/archives/2007/01/crosssite_security.php

XMLHttpRequest Level 2について

XMLHttpRequest Level 2に対応しているブラウザで外部サイトに対してXMLHttpRequest通信を行うと、ブラウザから送られるHTTPリクエストにOriginヘッダが付加される。Originヘッダにはドメイン名が設定される。

サーバー側から返されるHTTPレスポンスのAccess-Control-Allow-Originヘッダにアクセスを許可するリクエスト送信先のドメインを指定する。

XMLHttpRequest Level 2に対応しているブラウザは、Access-Control-Allow-Originヘッダの内容を確認して、それが現在のリクエスト送信元のドメインと一致している場合にのみ、レスポンスを受け取る。

通常は.htaccessなどでAccess-Control-Allow-Originヘッダに許可するドメインを羅列するが、その値に*を指定すると、すべてのドメインから利用できるようになる。

 

DOMについての復習

DOMはHTMLとほとんど同型のツリー構造をとるが、HTMLにおける要素ノード以外にも、いくつか種類がある。下記にDOMノードの種類を示す。

要素ノード

HTMLの要素に対応するノード。複数の属性を持ち、さらに子ノードを持つ。
具体的にはelement.getElementsByTagName()やdocument.getElementById()で取得できる。

ルートノード

HTMLではhtml要素が全ての要素のルートとなっているが、DOMではさらに上位にdocumentというルートノードが存在する。

テキストノード

文字列を格納するノード。子ノードを持たない。

 

上記のノードを取得・変更・追加・削除するためのAPIの規定がDOMである。
次にDOMを操作・取得するための関数を下記に示す。

DOMの関数

指定したid属性の値を持つ要素ノードを取得するメソッド

document.getElementById(id)

呼び出し元のノードの子孫要素の中で、指定した要素の名前を持つ要素ノードをリストとして取得するメソッド

element.getElementsByTagName(name)

呼び出し元のノードの子孫ノードの中から、指定したクラス属性の値を持つ要素ノードをリストとして取得するメソッド

element.getElementsByClassName(name)

呼び出し元のノードの指定した属性の値を取得するメソッド(ただし、ほとんどの属性には同名のプロパティが用意されている)

element.getAttribute(name)

呼び出し元のノードの直下のすべてのノード(テキストノード含む)のリストを取得するプロパティ

element.childNodes

呼び出し元のノードの直下の最初のノードを取得するプロパティ(element.childNodes[0]と同じ)
※ちなみにelement.firstElementChildとすると、最初の要素ノードの取得になる

element.firstChild

(例)子要素すべてを削除

let $el = document.getElementById('hoge');
while ( $el.firstChild ) {
    $el.removeChild($el);
}

指定した要素名の要素ノードを生成(生成後はappendChild()やinsertBefore()を使って、任意の場所に挿入)

document.createElement(name)

指定した文字を格納したテキストノードを生成(生成後はappendChild()やinsertBefore()を使って、任意の場所に挿入)

document.createTextNode(text)

呼び出し元のノードの子ノードの一番最後に指定したノードを追加

element.appendChild(node)

呼び出し元のノードの指定した子ノードを削除

element.removeChild(node)

指定したノードの直前にノードを挿入

insertBefore(node, ref)

 

より簡単にノードを取得できるAPIとしてSelectors APIがある。
今はこちらの方が主流。
上記の「element.getElementsByClassName(name)」「element.getElementsByTagName(name)」また「document.forms」などのDOM APIとSelectors APIの大きな違いとしては、上記の場合はLive NodeList(単純にNodeListと呼ばれることもある)を取得するのに対してSelectors APIはStatic NodeList(HTMLCollectionと呼ばれることもある)を取得する。

両者の違いは、別の概念で言い換えると、要素のコピーを取得するかポインタを取得するかの違いだと筆者は思っている。
それぞれ使用できるメソッドの違いがもちろんあり、混合することでよく発生するエラーは、下記のような感じ。

Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

Selectors APIはjQueryライクにかけるので、まだjQuery使っている人でも簡単に導入できると思う。

Selectors API

呼び出し元のノードの子ノードの中から、指定したセレクタで一番最初の要素ノードを取得

document.querySelector(selector)

呼び出し元のノードの子ノードの中から、指定したセレクタのすべての要素ノードを取得

document.querySelectorAll(selector)