2013/2

  • Feb
  • 18
  • 2013

IT

JSONPについて勉強した

JSONP(JSON with padding)とは、scriptタグを使用してクロスドメインなデータを取得する仕組みのことである。HTMLのscriptタグ、JavaScript(関数)、JSONを組み合わせて実現される。 ブラウザなどに実装されている「同一生成元ポリシー」という制約により、Webページは通常、自分を生成したドメイン以外のドメインのサーバと通信することはできない。 しかし、HTMLのscriptタグのsrc属性には別ドメインのURLを指定して通信することができるという点を利用することによって別ドメインのサーバからデータを取得することが可能になる。 JSONPでは、通常、上記src属性のレスポンスの内容はjavascript関数呼び出しの形式となるため、src属性に指定するURLにその関数の名前をクエリ文字列の形式で付加する。一般的な方法では、この時に指定する関数名はWebページ側ですでに定義されているコールバック用の関数の名前になる。

Wikipediaより

サーバ側は?callback=hogeで指定したコールバックでJSONを包んで返してくれるようなAPIで、
クライアントはそれを<script>タグのsrcで指定して呼び出す仕組みらしい。
<script>タグを使うからドメインを超えて通信できるのでレスポンスヘッダに

Access-Control-Allow-Origin: *

が入っていないJSON-APIをブラウザから呼ぶ時とかに使うといいっぽい。

実践編

githubのAPIをJSONPで叩いてみる


JSONPの結果をココに表示


このページのソース

<script type="text/javascript">
              $("#jsonp_run").on("click",function(){
                var jsonp = new JSONP();
                jsonp.request("https://api.github.com/users/georgeosddev",function(res){
                  var flagment = document.createDocumentFragment();
                  for (var key in res["data"]){
                    var span = document.createElement('span');
                    span.innerText = key+":"+res["data"][key]+"\r\n";
                    flagment.appendChild(span);
                  }
                  $("#jsonp_result").append(flagment);
                });
              }).on("touchstart",function(){
                $(this).trigger("click");
              });
              </script>
              

jsonp-client.js

できた。\(^o^)/

express向けconnect-ltsv-loggerを作った

ltsvのビッグ・ウェーブを眺めてたら最初にgem作ってたのが知人でびっくりして、俺もなんかやってみたいなーと思いつつ作ってみました。

connect-ltsv-logger

Node.js用のparserはもうあったし、それならstreamでって思ったけど Stream難しいので挫折してるうちに、ltsv-streamも登場していたので、 logを出力する側からアプローチしてみた。

こんな感じでexpressやconnectのMiddlewareとして使用します。

サンプル


              var express = require("express"),
                  ltsvlogger = require('connect-ltsv-logger');
              
              // define output WriteStream
              var out = fs.createWriteStream("ltsv-access.log",{flags: 'a+'}),
              
              // define tokens
              var ltsv = [];
              ltsv.push("host");
              ltsv.push("ident");
              ltsv.push("user");
              ltsv.push("time");
              ltsv.push("req");
              ltsv.push("status");
              ltsv.push("size");
              ltsv.push("referer");
              ltsv.push("ua");
              
              var app = express();
              app.configure(function(){
                // app.set(/*snip*/)
                // ...
              
                app.use(ltsvlogger({format:ltsv,stream:out}));
              
                // app.use(/*snip*/)
                // ...
              });
              

指定したTOKENをltsv形式でログ出力します。connect.loggerのラッパーなので元のオプションもそのまま使えます。

引数

  • format: String or 例のようにTokenのArrayが使えます。
  • stream :本家と同じ。ltsvにするのでstdoutじゃなくてファイルに書いた方が使いがいがあるかも。
  • buffer: 本家と同じ。
  • immediate: 本家と同じ。

使用可能なFormat

connect.logger'sのformatsをltsv形式にオーバーライドしているだけです。

  • default
    host:127.0.0.1ident:-user:-time:[Wed, 13 Feb 2013 10:00:55 GMT]req:GET / HTTP/1.1status:200size:110referer:-ua:-`
  • short
    host:127.0.0.1ident:-req:GET / HTTP/1.1status:200size:-response-time:1 ms`
  • tiny
    req:GET /status:200size:-response-time:1 ms
  • dev

    concise output colored by response status for development use (Not ltsv format).

使用可能なTokens

identとか良くわかんないけど、connectも”−”にしてたので...(汗)

  • time

      logger.token("time",function(){
                      return "[" + moment().format("DD/MMM/YYYY:HH:mm:ss Z") + "]" ;
                    });
  • host

      logger.token("host",function(req,res){
                      return req.connection.address().address || '-';
                    });
  • X-Forwarded-For

      logger.token("X-Forwarded-For",function(req,res){
                      return res.getHeader("X-Forwarded-For") || "-";
                    });
  • user

      logger.token("user",function(req,res){
                      return '-';
                    });
  • ident

      logger.token("ident",function(req,res){
                      return '-';
                    });
  • req

      logger.token("req",function(req,res){
                      var ret = [];
                      ret.push(req.method);
                      ret.push(req.url);
                      ret.push("HTTP/"+req.httpVersion);
                      return ret.join(" ");
                    });
  • method

      logger.token("method",function(req,res){
                      return req.method;
                    });
  • uri

      logger.token("uri",function(req,res){
                      return url.parse(req.url).href;
                    });
  • protocol

      logger.token("protocol",function(req,res){
                      return url.parse(req.url).protocol;
                    });
  • status

      logger.token("status",function(req,res){
                      return res.statusCode;
                    });
  • size

      logger.token("size",function(req,res){
                      return res.getHeader("content-length");
                    });
  • reqsize

      logger.token("reqsize",function(req,res){
                      if(req.body) return req.body.length;
                      return "-";
                    });
  • referer

      logger.token("referer",function(req,res){
                      return req.headers['referer'] || req.headers['referrer'];
                    });
  • ua

      logger.token("ua",function(req,res){
                      return req.headers['user-agent'];
                    });
  • vhost

      logger.token("vhost",function(req,res){
                      return req.headers["host"];
                    });
  • reqtime

      logger.token("reqtime",function(req,res){
                      return new Date - req._startTime;;
                    });
  • X-Cache

      logger.token("X-Cache",function(req,res){
                      return res.getHeader('X-Cache');
                    });
  • X-Runtime

      logger.token("X-Runtime",function(req,res){
                      return res.getHeader('X-Runtime');
                    });

            |i
                   \      |.|
                    ト\   /| ト
                    | トヽ   / | | ト
                    | | トヽ\/| | | ト    /
                    | | | ト\≧三ミゞ=イ/
                   ム彡''´ ̄ ̄    ̄ ヽ{__..
                  /             V´
                  ノ  __          ',
               ,. == y ̄, __、\_        )      世 界 的 で す も ん ね
               |i  }-| ゝ二 |/ ̄ ̄  /ニ,l
               ヽ__ノ/ヾ _ ノ       > }}
                / >≦'__        し /        乗 る し か な い
                 Vて二オカ       (_,/}
                 Yこ二ノ!!|          }         こ の ビッ グ ウ ェ ー ブ に
                  Y⌒ 从        ∠)
                  从从从トミ   _.ィニ二 ̄丶
                   ミ三三彡 ' ´      \ \
                      /           \ヽ
                    /            ミ;,. ', ',
                     |   _  _ __    \',.',
                    ノ!   | V7\ ´/
                   / l /_ゝ| ト >__/ /
                   |   ヽン ´  ヽー'
                  i|                l
                  |:! ヽ              |
                  | ト、 `ミ,            l
              

iPhone4Sで無料テザリング via WebSocket!

ws-tether

Yet Another Tethering Solution for iPhone4S.

ws-tether mechanism

使い方(Node.jsが動く環境が前提)

  1. ws-tetherをLocalのMacとCloud上のサーバ双方にcloneします。
    Cloud環境はHerokuがwebsocketサポートしています。
    
                  git clone http://github.com/georegeosddev/ws-tether.git
                  
  2. コンフィグファイルの編集
    
                  var config = {
                    localProxy : "ws://"+window.location.host
                    ,serverProxy : "ws://"+Cloudサーバのドメイン+":ポート"
                  };
                  

    websocketの接続先としてcloudサーバで稼働させるserver-ploxyを指定します。

  3. MacでAdhocネットワークを作成.
    create adhoc network
  4. 詳しいやり方

    ネットワークができたらifconfig等でIPアドレスを調べます。

    /sbin/ifconfig

    このへんはDHCPじゃなくて固定にしてもいいのかもしれないが詳しいことはよくわからないので、
    とりあえず割り振られたIPを調べる。

  5. ローカルプロキシの起動 (on Local Mac)

    cd ws-tether/local-proxy && npm start.
                  
  6. サーバプロキシの起動(on Cloud Server)

    ws-tether/server-proxy/bin/start.sh を編集してポートはCloudサーバで使用出来るポートにセットしたら、

    cd ws-tether/server-proxy && npm start.
                  
  7. iPhoneのsafariで先ほどMacで作成したネットワークにWifi接続して、bridge.htmlに接続.

    http://Mac'sIP-adress:3000/bridge.html
  8. Proxy Switchy!などのChrome拡張を使って、Chromeのプロキシをlocalhost:3000に設定

    ploxy setting

  9. Enjoy!
  • Feb
  • 4
  • 2013

IT

Lokka on herokuにNewRelicを導入

TシャツをくれるようなのでNewRelicのアカウントを作って導入してみた。NewRelicが何なのかよくわかっていないけど。。。30日は無料っぽいし。 Herokuのアドオンとして使うのかlokkaのpluginとして使うのかGemとして使うのかイマイチよくわかんないけどググりながら

以下やったことをメモ

Gemfileに追記

              gem "newrelic_rpm", "~> 3.5.5.38"
              

lib/lokka.rbに追記

              if Lokka.production?
                require 'newrelic_rpm'
              end
              

newrelic.ymlをダウンロードして/configに配置

              mkdir config
              mv ~/Download/newrelic.yml ./config/
              bundle install
              git add -A
              git commit -m "add newrelic"
              heroku config:add NEW_RELIC_LICENSE_KEY=ダッシュボードで確認したkey
              git push heroku master
              

できたー。早くTシャツくれー。

参考