CORSが難しい

CORSはクロスサイト間のリソース管理。Javascriptから他のサイトのリソース取得を管理するためのプロトコル。

通常こういったクロスオリジンのアクセスは許されないが(ブラウザが許さない)サーバがあるhttpヘッダを返すことで許すことができる。

Access-Control-Allow-Origin

このヘッダを付けることで、クライアントはその値と自分のJSのサイトが一致していたら通信を許可する。.htaccessに以下のように記述すると、すべてのクロスオリジンアクセスを許す。

制限

通常は完全にアクセスを許すことはしたくないはずなので自分のサイトだけを登録するが、サイトが複数ある場合はデバッグ中のlocalhostを加えたい場合は面倒なことになる。

更にサイトがディレクトリを掘っていて、ディレクトリごとに.htaccessがある場合とかだっともっと複雑になる。

サイトが複数ある場合

とりあえず動いているものとして、以下の.htaccess。

これはlocalhostとtango.dip.jpを許可する。返されるヘッダにはアクセス元のサイトのみが返るのだと思われる。

仕様によると以下の記述でもいいらしい。(試していない)

メソッド

上記の.htaccessにはメソッドの記述もあるが、これは許すメソッドを定義しているものと思われる。そのためにブラウザはOPTIONメソッドでリクエストしてこの情報を得るものと思われる。このときのURLはサイトのURLと同じと思われるので、PHPなどが動くときは200が返るようにしておかないと、Chromeなどはエラーを出す。OPTIONのときはPHPの$_POSTがないと思われるので、このとき500とかを返すとCORSがうまくいかない。

ChromeなどのエラーResponse to preflight request doesn’t pass access control checkはこのOPTIONを指しているものと思われる。

このように非常に面倒で、ヘッダとかを調べるのも面倒なので適当に書いた。ヘッダを確認するにはChromeのDEVTOOLSを使うといい。304になってしまう場合は、シフトキーを押しながらリロードするか、リロードボタンで右クリックして、ハードリロードなどを選ぶ。タイプコラムがxhrになっているのがスクリプトからのアクセス。

ChromeのDevToolでCORSを調べる

npm runのnode実行でonelineのjavascriptに引数を渡して実行する

nodeでjavascriptを実行する場合、通常はnodeにファイルを渡してスクリプトを実行するが短いスクリプトの場合はコマンドラインにスクリプトを書くことができる。ちょっとしたスクリプトを書きたい場合はこうすることですべての情報がコマンドラインにしか存在しないのでよりポータブルになる。しかしコマンドラインの制約から文字列を囲むクォートやダブルクォートが書きにくいので、その点は注意する必要がある。Windowsではシングルクォートは通常の文字のように扱われるので、スクリプト全体をダブルクォートで囲い、スクリプト内部での文字列はシングルクォートで囲むようにする。

次にスクリプトに引数を渡したいときはnodeに渡す引数と区別するために、通常は最後に–(2つのハイフン)をつけて、それ以降の引数はスクリプトに渡されるものであることを指示する。

上記のことを組み合わせて、スクリプト内で引数を受け取り、コマンドラインでスクリプトとそれに渡す引数を渡すことができる。これを応用してnpm runに記述しておけば、ちょっとしたコマンドをpackage.jsonに登録することができる。jsonでダブルクォートを扱うときはバックスラッシュでエスケープすればいいので矛盾は生じない。

nodeでのスクリプトへの引数の渡し方

-eでスクリプトをそのまま指定。
–のあとのコマンドライン引数はスクリプトに渡される。

スクリプト内では引数はprocess.argvで受け取る。

npm runに引数を渡す

npm runはそのまま実行するだけのようなので以下のように書く。ダブルクォートはバックスラッシュでエスケープする。

npm runを実行

apacheでjsonを返す時httpヘッダを追加する

特殊なhttpレスポンスヘッダがあるとクライアントのjsからドメイン制限を無視して取得できる。apache2で設定する方法。

mod_headers.cを有効にする

サーバのjsonを置いたディレクトリに.htaccessを置き、ここに以下の記述を追加する。
(.htaccessが有効になっている必要がある。有効になってない場合はサーバの設定ファイルに直接書くか、有効にする)

ヘッダが帰ってきているかChromeで確認

Chromeで対象jsonを開き、[Ctrl]+[Shift]+Iでdevコンソールを開き「ネットワーク」タブの「All」を開く。[Ctrl]+Rと表示されたときは押す。

chromeのDEVツール。ネットワークタブでCtrl+R

ChromeのDEVツール。3xxが返ってくる

3xxが帰ってきているときは[Shift]を押しながらリロードする。

ChromeのDEVツール。200が返ってくる

対象ファイルをクリックするとヘッダが見れる。

ChromeのDEVツール。HTTPヘッダが見れる

javascriptで試す

node + vscode が前提。ここではjsonの取得にaxiosモジュールを使ってみる。

axiosのインストール

vscodeのターミナルで以下を実行。

htmlの作成

axiosで取得したjsonを表示した

リンク

このリンクのhtmlのjavascriptはhttps://jsonplaceholder.typicode.com/postsから取得している。次の例はこのサーバから取得。

.htaccessはすべてのクライアントから許可するように以下のように修正

リンク

このリンクが外部のクライアントからアクセスされた時のログは以下

サーバとクライアントとクロスサイトスクリプティングが一緒になって複雑