2015年1月31日土曜日

CouchDB JavaScriptからの読み込みについて

CouchDBのUIを作ってみたくなり、htmlを書いてみます。せっかくなのでjQueryを使って、Ajaxを試して見たいと思ったのですが、ここからが苦難の始まりでした。

簡単なサンプルを書いてみたんですが、どうしてもNo 'Access-Control-Allow-Origin' header is present on the requested resource.というエラーがコンソールに出てきて失敗します。(ChromeのJavaScriptコンソールで確認しています)色々、調べてみたんですが、エラーの意味はXSSを防ぐため、ドメインが異なるJavaScriptを実行したり、読み込もうとするとでるエラーのようです。(数年前、これおを悪用したサイトの改竄が流行った記憶があります)しかし自分はローカル環境、あるいは家庭内の別PCで動かしているcouchdbから読もうとしているんですが、このエラーから逃げれません。
そこで、jQueryの問題なのかcouchdbの問題なのか区別するため、素に戻って単純にJavaScriptでローカルPCに置いたjsonデータを読むプログラムを書いてみました。

   function loadJson(id) {
    $('#msg').append("これから読みます:");

    var url = "http://localhost/~hogehoge/test1.json";
    var xmlHttp;

    xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", url, false);
    xmlHttp.send(null);

    $('#msg').append(xmlHttp.responseText);

    $('#msg').append("うまくいった?");

   }

(これをやるために前回「ウェブ共有」の設定を調べました)
ところがMac上のchromeからでは相変わらず同じエラーが出ます。幾ら何でもこれはおかしいだろうと、調べてみるとchromeではセキュリティを厳しくしていて、ローカルPC上のファイルをhttp経由で読もうが、同じチェックをしていてエラーを出すそうです。ちなみに同じものをSafariで実行してみたら、あっさり動きました。(ちなみに同様のスクリプトをjQueryで書くと、Safariでもエラーがでます。どうもjQuery内部で同様のチェックをしているようで、簡単に自分のとこだけで試してみようと思っているのに難儀なことです)

さてCouchDBのUIを作ろうと思ったらなんとかcouchdbの設定で'Access-Control-Allow-Origin' のヘッダをつけるようにしないといけません。
現状、使用しているcouchdbは1.6ですが、1.4のドキュメントには以下の設定があるのがわかりました。

local.iniに以下の設定を追加。

[httpd]
enable_cors = true

[cors]
origins = *

特に[cors]の項目はデフォルトの設定ファイルには存在しておらず大丈夫かと思いましたが、うまくいきました。(ただこの設定は「全て許可する」という意味なんで、あまり推奨できませんが…本当は単にローカルPC上だけで動かしたいだけなら、origins=http://localhostとかするのがいいと思います。でもこれだと、http://127.0.0.1でアクセスすると拒否されてしまい、難しいところです。)
さて実際にcouchDBからデータを読み込んでみます。以下のプログラムで試してみました。(htmlにはボタンをつけて、以下のスクリプトを実行するようにしています)

   function readCouch(id) {
    $('#msg').append("これから読みます:");
    var url;
    url = 'http://localhost:5984/kakeibo';
    $.ajax({
     type: "GET",
     url: url,
     dataType:'json',
    }).done(function(data) {
     alert('読み込み');
     var str = parseJson(data);
     $('#msg').append(str);
    }).fail(function(xhr, textStatus, errorThrown){
     alert('error!!');
     console.log("NG:" + xhr.status);
     console.log("NG:" + textStatus.status);
     $('#msg').append("失敗しました");
    });

    $('#msg').append("うまくいった?");
   }

   function parseJson(json) {
    var ret = 'db_name : ' + json.db_name + '';
    ret = ret + 'doc_count : ' + json.doc_count;
    return ret;
   }

chromeで実行すると以下のようになります。(html上に、<p id=msg>が付けてあり、そこに追記するようにしています)


うまく読めましたね。

0 件のコメント:

コメントを投稿