Mojolicious

fmxj.js のサーバーサイドをPHPじゃなくてPerl(Mojolicious)で試す

先日、SeedCodeの方がFileMakerのCustom Web Publishing の為のJavaScriptとServer side で使うPHPのサンプルをGithubで公開されてました。

https://github.com/seedcode/fmxj

概要としては、FileMaker Server の XML公開を使う。

Web公開エンジンにXML公開のためのリクエストをJavaScriptで生成してサーバーサイドスクリプト(SeedCodeのサンプルではPHP)にpostする。

◆ハマった事:サンプルPHPの内容

サンプルのPHPをよく読んでなかった。。。

JavaScriptからFileMakerのユーザーアカウントとパスワードをpost出来るようにキーバリューを元々のpostデータに加えている。それから本来のpostデータからおまけを除くための追加分のパラメータ文字数もpostに加えている。この辺りの仕様にもんりょりする。

-db=dbname&-lay=layname&-query=(q1)&-q1=Status&-q1.value=Vendor&-findquery みたいな通常のクエリデータに

u=undefined&p=undefined&l=コンテンツの文字数

ていうのがくっついてPHPにpostされてくる。

それをPHP側でphp://inputでリクエストのボディを取得して余計なパラメータを削ってpostデータを作り直してcurl使ってPOSTしてた。

そこに気づかずperlで再現しようとした時にpostデータを丸投げしてエラーになってしまっていた。

なんでpostデータをわざわざこねくり回してるんだろう?て思ってた。

サンプルって事でいろいろハードコーディングされてるけど、気にしない。

◆ハマった:Nginxの設定

欲をかいてPerlでサーバーサイド書くにあたって、FastCGIでさらっと書くじゃなくてMojolicious使うことにしたら

WebServer→Nginxでバーチャルホスト(hoge.sample.comみたいな)とmorboで127.0.0.1:3000で動くMojoliciousになって、何が起きたかって言うとクロスドメインの問題が発生してしまい、エラーになる。

これについてはNginxの設定でproxy_passでMojoliciousにリクエストがリバースプロキシされるようにして解決。

しかしNginx、デフォルトではContent-Typeの書き換えができず、JavaScriptにレスポンスされるデータがXMLになっていなくて、意図する結果に終わらない。既にあるヘッダーに値を追加する処理を行ってしまう。

※Nginxで add_header Content-Type ‘application/xml’してもmime-typeの設定ファイルに追記しても

 Content-Type text/html;charset=UTF-8に application/xmlの値が追記されるだけになる。

その結果、fmxj.jsがXMLHttpRequestのresponseXMLに値がセットされない。そしてresponseXMLがあるの前提になっているXMLをパースする処理のところで結果が空欄になって処理が終わってしまう。

最初fmxj.js内部を書き換えて(responseTextをXMLに変換して)みたんだけど、コアのライブラリを触るのはよくないので、Nginxでちゃんとヘッダを書き換えられる方法を調べる、nginx-extrasを追加でインストールするとmore-set-headerというのが使えるようになり、ヘッダーの書き換えができるようになるとの事だったのでインストール。

自分はUbuntuの環境なので、

sudo apt-get install nginx-extras

後はNginxの設定ファイルに(厳密に言うとリクエストを受け付けるLocationディレクティブで)

more_set_headers ‘Content-Type: application/xml; charset=UTF8’;

を追記、more…がヘッダーの追記ではなく書き換えなのでcharsetも忘れずに書く!

これでようやく、Sample.html → fmxj.jsを使ってServerにpostリクエスト → 受けたリクエストをNginxがMojoliciousを動かしてるmorboにリバースプロキシ → MojoliciousがPOSTリクエスト受け取りXML公開のクエリパラメータ付きURLを生成して(生成しなおして)cURLをラップしたライブラリからPOST送信 → JavaScriptにレスポンスが返り、完成。

[Read More…]